Port-amd64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

fpsetmask(3) do not clear exception bits



Hi,

While checking fpsetmask(3) behaviour i noticed that, while it can set
bits to unmask exception, it cannot clear them afterwards.

The attached patch should fix it. But wanted to ask for some more
review to the asm code before committing it (and the corresponding
testcase).

Thanks.

-- 
Nicolas Joly

Projects and Developments in Bioinformatics
Institut Pasteur, Paris.
Index: lib/libc/arch/x86_64/gen/fpsetmask.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/x86_64/gen/fpsetmask.S,v
retrieving revision 1.3
diff -u -p -r1.3 fpsetmask.S
--- lib/libc/arch/x86_64/gen/fpsetmask.S        12 Jun 2002 19:17:22 -0000      
1.3
+++ lib/libc/arch/x86_64/gen/fpsetmask.S        12 Oct 2011 16:39:24 -0000
@@ -20,22 +20,25 @@ ENTRY(_fpsetmask)
 #else
 ENTRY(fpsetmask)
 #endif
-       fnstcw  -4(%rsp)
-       stmxcsr -8(%rsp)
-       andl    $63,%edi
        notl    %edi
+       andl    $0x0000003f,%edi
 
-       movl    -4(%rsp),%edx
-       movl    %edx,%eax
-       andl    %edi,%edx
+       fnstcw  -4(%rsp)
+       movl    -4(%rsp), %edx
+       movl    %edx, %eax
+       andl    $0xffffffc0, %edx
+       orl     %edi, %edx
        movl    %edx,-4(%rsp)
+       fldcw   -4(%rsp)
 
-       movl    -8(%rsp),%edx
-       roll    $7,%edi
-       andl    %edi,%edx
-       movl    %edx,-8(%rsp)
+       stmxcsr -4(%rsp)
+       movl    -4(%rsp), %edx
+       andl    $0xfffff07f, %edx
+       sall    $7, %edi
+       orl     %edi, %edx
+       movl    %edx,-4(%rsp)
+       ldmxcsr -4(%rsp)
 
-       fldcw   -4(%rsp)
-       ldmxcsr -8(%rsp)
-       andl    $63,%eax
+       notl    %eax
+       andl    $0x0000003f, %eax
        ret
Index: tests/lib/libc/gen/t_fpsetmask.c
===================================================================
RCS file: /cvsroot/src/tests/lib/libc/gen/t_fpsetmask.c,v
retrieving revision 1.2
diff -u -p -r1.2 t_fpsetmask.c
--- tests/lib/libc/gen/t_fpsetmask.c    1 Oct 2011 17:46:10 -0000       1.2
+++ tests/lib/libc/gen/t_fpsetmask.c    12 Oct 2011 16:39:24 -0000
@@ -310,6 +310,27 @@ TEST(fpsetmask_unmasked, float)
 TEST(fpsetmask_unmasked, double)
 TEST(fpsetmask_unmasked, long_double)
 
+ATF_TC(fpsetmask_basic);
+ATF_TC_HEAD(fpsetmask_basic, tc)
+{
+       atf_tc_set_md_var(tc, "descr", "A basic test of fpsetmask(3)");
+}
+
+ATF_TC_BODY(fpsetmask_basic, tc)
+{
+       size_t i;
+       fp_except_t msk, lst[] = { FP_X_INV, FP_X_DZ, FP_X_OFL, FP_X_UFL };
+
+       msk = fpgetmask();
+       for (i = 0; i < __arraycount(lst); i++) {
+               fpsetmask(msk | lst[i]);
+               ATF_CHECK((fpgetmask() & lst[i]) != 0);
+               fpsetmask(msk & lst[i]);
+               ATF_CHECK((fpgetmask() & lst[i]) == 0);
+       }
+
+}
+
 #endif /* defined(_FLOAT_IEEE754) */
 
 ATF_TP_ADD_TCS(tp)
@@ -318,6 +339,7 @@ ATF_TP_ADD_TCS(tp)
 #ifndef _FLOAT_IEEE754
        ATF_TP_ADD_TC(tp, no_test);
 #else
+       ATF_TP_ADD_TC(tp, fpsetmask_basic);
        ATF_TP_ADD_TC(tp, fpsetmask_masked_float);
        ATF_TP_ADD_TC(tp, fpsetmask_masked_double);
        ATF_TP_ADD_TC(tp, fpsetmask_masked_long_double);


Home | Main Index | Thread Index | Old Index