summaryrefslogtreecommitdiff
path: root/src/fenv/x86_64/fenv.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/fenv/x86_64/fenv.s')
-rw-r--r--src/fenv/x86_64/fenv.s88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/fenv/x86_64/fenv.s b/src/fenv/x86_64/fenv.s
new file mode 100644
index 00000000..3ed22755
--- /dev/null
+++ b/src/fenv/x86_64/fenv.s
@@ -0,0 +1,88 @@
+2: not %edi
+ sub $32,%rsp
+ fnstenv (%rsp)
+ and %edi,4(%rsp)
+ or %esi,4(%rsp)
+ fldenv (%rsp)
+ stmxcsr (%rsp)
+ and %edi,(%rsp)
+ ldmxcsr (%rsp)
+ add $32,%rsp
+ ret
+
+.global feclearexcept
+feclearexcept:
+ xor %eax,%eax
+ xor %esi,%esi
+ test %edi,%edi
+ jnz 2b
+ ret
+
+.global feraiseexcept
+feraiseexcept:
+ xor %eax,%eax
+ mov %edi,%esi
+ xor %edi,%edi
+ test %esi,%esi
+ jnz 2b
+ ret
+
+.global fesetround
+fesetround:
+ xor %eax,%eax
+ sub $32,%rsp
+ fnstenv (%rsp)
+ andb $0xf3,1(%rsp)
+ or %edi,(%rsp)
+ fldenv (%rsp)
+ stmxcsr (%rsp)
+ shl $3,%edi
+ andb $0x9f,1(%rsp)
+ or %edi,(%rsp)
+ ldmxcsr (%rsp)
+ add $32,%rsp
+ ret
+
+.global fegetround
+fegetround:
+ push %rax
+ stmxcsr (%rsp)
+ pop %rax
+ shr $3,%eax
+ and $0xc,%ah
+ ret
+
+.global fegetenv
+fegetenv:
+ xor %eax,%eax
+ fnstenv (%rdi)
+ stmxcsr 28(%rdi)
+ ret
+
+.global fesetenv
+fesetenv:
+ xor %eax,%eax
+ inc %rdi
+ jz 1f
+ fldenv -1(%rdi)
+ ldmxcsr 27(%rdi)
+ ret
+1: push %rax
+ push %rax
+ push %rax
+ pushq $0x37f
+ fldenv (%rsp)
+ pushq $0x1f80
+ ldmxcsr (%rsp)
+ add $40,%rsp
+ ret
+
+.global fetestexcept
+fetestexcept:
+ push %rax
+ stmxcsr (%rsp)
+ pop %rsi
+ fnstsw %ax
+ or %esi,%eax
+ and %edi,%eax
+ ret