aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/x86_64/fpu/s_ceill.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/x86_64/fpu/s_ceill.S')
-rw-r--r--sysdeps/x86_64/fpu/s_ceill.S15
1 files changed, 10 insertions, 5 deletions
diff --git a/sysdeps/x86_64/fpu/s_ceill.S b/sysdeps/x86_64/fpu/s_ceill.S
index 910c371..9d8b79d 100644
--- a/sysdeps/x86_64/fpu/s_ceill.S
+++ b/sysdeps/x86_64/fpu/s_ceill.S
@@ -11,20 +11,25 @@
ENTRY(__ceill)
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 $0x0800,%edx /* round towards +oo */
- orl -4(%rsp),%edx
+ orl -28(%rsp),%edx
andl $0xfbff,%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 (__ceill)