about summary refs log tree commit diff
path: root/src/fenv/i386/fenv.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/fenv/i386/fenv.s')
-rw-r--r--src/fenv/i386/fenv.s39
1 files changed, 27 insertions, 12 deletions
diff --git a/src/fenv/i386/fenv.s b/src/fenv/i386/fenv.s
index 9bba40a5..a8540add 100644
--- a/src/fenv/i386/fenv.s
+++ b/src/fenv/i386/fenv.s
@@ -4,26 +4,41 @@
 .type feclearexcept,@function
 feclearexcept:	
 	mov 4(%esp),%ecx
-	not %ecx
+	fnstsw %ax
 		# consider sse fenv as well if the cpu has XMM capability
 	call 1f
 1:	addl $__hwcap-1b,(%esp)
 	pop %edx
 	testl $0x02000000,(%edx)
+	jz 2f
+		# maintain exceptions in the sse mxcsr, clear x87 exceptions
+	test %eax,%ecx
 	jz 1f
-	stmxcsr 4(%esp)
-	and %ecx,4(%esp)
-	ldmxcsr 4(%esp)
-1:	test $0x3f,%ecx
-	jnz 2f
-1:	fnclex
-	xor %eax,%eax
+	fnclex
+1:	push %edx
+	stmxcsr (%esp)
+	pop %edx
+	and $0x3f,%eax
+	or %eax,%edx
+	test %edx,%ecx
+	jz 1f
+	not %ecx
+	and %ecx,%edx
+	push %edx
+	ldmxcsr (%esp)
+	pop %edx
+1:	xor %eax,%eax
 	ret
-2:	fnstsw %ax
-		# TODO: only load/store fenv if exceptions arent clear yet
-	and %ecx,%eax
+		# only do the expensive x87 fenv load/store when needed
+2:	test %eax,%ecx
 	jz 1b
-	sub $32,%esp
+	not %ecx
+	and %ecx,%eax
+	test $0x3f,%eax
+	jz 1f
+	fnclex
+	jmp 1b
+1:	sub $32,%esp
 	fnstenv (%esp)
 	mov %al,4(%esp)
 	fldenv (%esp)