summaryrefslogtreecommitdiff
path: root/sysdeps/x86_64/fpu/s_floorl.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/x86_64/fpu/s_floorl.S')
-rw-r--r--sysdeps/x86_64/fpu/s_floorl.S18
1 files changed, 12 insertions, 6 deletions
diff --git a/sysdeps/x86_64/fpu/s_floorl.S b/sysdeps/x86_64/fpu/s_floorl.S
index f9ecc388df..75f8255648 100644
--- a/sysdeps/x86_64/fpu/s_floorl.S
+++ b/sysdeps/x86_64/fpu/s_floorl.S
@@ -5,26 +5,32 @@
* Public domain.
*/
+#include <libm-alias-ldouble.h>
#include <machine/asm.h>
ENTRY(__floorl)
fldt 8(%rsp)
- fstcw -4(%rsp) /* store fpu control word */
+ fnstenv -28(%rsp) /* store fpu environment */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x400,%edx /* round towards -oo */
- orl -4(%rsp),%edx
+ orl -28(%rsp),%edx
andl $0xf7ff,%edx
- movl %edx,-8(%rsp)
- fldcw -8(%rsp) /* load modified control word */
+ movl %edx,-32(%rsp)
+ fldcw -32(%rsp) /* load modified control word */
frndint /* round */
- fldcw -4(%rsp) /* restore original control word */
+ /* Preserve "invalid" exceptions from sNaN input. */
+ fnstsw
+ andl $0x1, %eax
+ orl %eax, -24(%rsp)
+
+ fldenv -28(%rsp) /* restore original environment */
ret
END (__floorl)
-weak_alias (__floorl, floorl)
+libm_alias_ldouble (__floor, floor)