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