about summary refs log tree commit diff
path: root/sysdeps/x86_64/fpu/s_fminl.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/x86_64/fpu/s_fminl.S')
-rw-r--r--sysdeps/x86_64/fpu/s_fminl.S27
1 files changed, 24 insertions, 3 deletions
diff --git a/sysdeps/x86_64/fpu/s_fminl.S b/sysdeps/x86_64/fpu/s_fminl.S
index f1a06d29d7..12fc3fb06c 100644
--- a/sysdeps/x86_64/fpu/s_fminl.S
+++ b/sysdeps/x86_64/fpu/s_fminl.S
@@ -24,14 +24,35 @@ ENTRY(__fminl)
 	fldt	8(%rsp)		// x
 	fldt	24(%rsp)	// x : y
 
-	fucomi	%st(0), %st
-	fcmovu	%st(1), %st	// now %st contains y if not NaN, x otherwise
-
 	fucomi	%st(1), %st
+	jp	2f
 	fcmovnb	%st(1), %st
 
 	fstp	%st(1)
 
 	ret
+
+2:	// Unordered.
+	fucomi	%st(0), %st
+	jp	3f
+	// st(1) is a NaN; st(0) is not.  Test if st(1) is signaling.
+	testb	$0x40, 15(%rsp)
+	jz	4f
+	fstp	%st(1)
+	ret
+
+3:	// st(0) is a NaN; st(1) may or may not be.
+	fxch
+	fucomi	%st(0), %st
+	jp	4f
+	// st(1) is a NaN; st(0) is not.  Test if st(1) is signaling.
+	testb	$0x40, 31(%rsp)
+	jz	4f
+	fstp	%st(1)
+	ret
+
+4:	// Both arguments are NaNs, or one is a signaling NaN.
+	faddp
+	ret
 END(__fminl)
 weak_alias (__fminl, fminl)