Index: fusl/src/fenv/x86_64/fenv.s |
diff --git a/fusl/src/fenv/x86_64/fenv.s b/fusl/src/fenv/x86_64/fenv.s |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b5aeaf4f494df7ddbf46664f427f5c887b618a6f |
--- /dev/null |
+++ b/fusl/src/fenv/x86_64/fenv.s |
@@ -0,0 +1,97 @@ |
+.global feclearexcept |
+.type feclearexcept,@function |
+feclearexcept: |
+ # maintain exceptions in the sse mxcsr, clear x87 exceptions |
+ mov %edi,%ecx |
+ and $0x3f,%ecx |
+ fnstsw %ax |
+ test %eax,%ecx |
+ jz 1f |
+ fnclex |
+1: stmxcsr -8(%rsp) |
+ and $0x3f,%eax |
+ or %eax,-8(%rsp) |
+ test %ecx,-8(%rsp) |
+ jz 1f |
+ not %ecx |
+ and %ecx,-8(%rsp) |
+ ldmxcsr -8(%rsp) |
+1: xor %eax,%eax |
+ ret |
+ |
+.global feraiseexcept |
+.type feraiseexcept,@function |
+feraiseexcept: |
+ and $0x3f,%edi |
+ stmxcsr -8(%rsp) |
+ or %edi,-8(%rsp) |
+ ldmxcsr -8(%rsp) |
+ xor %eax,%eax |
+ ret |
+ |
+.global __fesetround |
+.type __fesetround,@function |
+__fesetround: |
+ push %rax |
+ xor %eax,%eax |
+ mov %edi,%ecx |
+ fnstcw (%rsp) |
+ andb $0xf3,1(%rsp) |
+ or %ch,1(%rsp) |
+ fldcw (%rsp) |
+ stmxcsr (%rsp) |
+ shl $3,%ch |
+ andb $0x9f,1(%rsp) |
+ or %ch,1(%rsp) |
+ ldmxcsr (%rsp) |
+ pop %rcx |
+ ret |
+ |
+.global fegetround |
+.type fegetround,@function |
+fegetround: |
+ push %rax |
+ stmxcsr (%rsp) |
+ pop %rax |
+ shr $3,%eax |
+ and $0xc00,%eax |
+ ret |
+ |
+.global fegetenv |
+.type fegetenv,@function |
+fegetenv: |
+ xor %eax,%eax |
+ fnstenv (%rdi) |
+ stmxcsr 28(%rdi) |
+ ret |
+ |
+.global fesetenv |
+.type fesetenv,@function |
+fesetenv: |
+ xor %eax,%eax |
+ inc %rdi |
+ jz 1f |
+ fldenv -1(%rdi) |
+ ldmxcsr 27(%rdi) |
+ ret |
+1: push %rax |
+ push %rax |
+ pushq $0xffff |
+ pushq $0x37f |
+ fldenv (%rsp) |
+ pushq $0x1f80 |
+ ldmxcsr (%rsp) |
+ add $40,%rsp |
+ ret |
+ |
+.global fetestexcept |
+.type fetestexcept,@function |
+fetestexcept: |
+ and $0x3f,%edi |
+ push %rax |
+ stmxcsr (%rsp) |
+ pop %rsi |
+ fnstsw %ax |
+ or %esi,%eax |
+ and %edi,%eax |
+ ret |