about summary refs log tree commit diff
diff options
context:
space:
mode:
-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