This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH 1/2] sparc: remove ceil, floor, trunc sparc specific implementations
From: David Miller <davem@davemloft.net>
Date: Mon, 01 Aug 2016 18:10:33 -0700 (PDT)
> From: Aurelien Jarno <aurelien@aurel32.net>
> Date: Tue, 2 Aug 2016 01:59:24 +0200
>
>> On 2016-08-01 14:57, David Miller wrote:
>>> >> Aurelien, it looks like we have the same exact issue with nearbyint on
>>> >> sparc, right?
>>> >
>>> > I don't see the issue on nearbyint here. What is the issue exactly?
>>>
>>> Maybe only the vis3 variant shows the problem:
>>>
>>> Failure: nearbyint (sNaN): Exception "Invalid operation" not set
>>> Failure: nearbyint (-sNaN): Exception "Invalid operation" not set
>>> Failure: nearbyint_downward (sNaN): Exception "Invalid operation" not set
>>> Failure: nearbyint_downward (-sNaN): Exception "Invalid operation" not set
>>> Failure: nearbyint_towardzero (sNaN): Exception "Invalid operation" not set
>>> Failure: nearbyint_towardzero (-sNaN): Exception "Invalid operation" not set
>>> Failure: nearbyint_upward (sNaN): Exception "Invalid operation" not set
>>> Failure: nearbyint_upward (-sNaN): Exception "Invalid operation" not set
...
>> Now about the fix itself, we have to move the check before the fsr is
>> saved and after the value has been moved to the floating point register,
>> which is not something easy to do without breaking the whole code. One
>> option would be to do it after loading the fsr at the end, the other one
>> would be to use the generic version.
>
> I'll look into this.
Aurelien I just tested the following and committed it to master:
====================
[PATCH] Fix sNaN handling in nearbyint on 32-bit sparc.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S
(__nearbyint_vis3): Don't check for sNaN before float register is
loaded with the incoming argument.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S
(__nearbyintf_vis3): Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S (__nearbyint):
Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S (__nearbyintf):
Likewise.
---
ChangeLog | 10 ++++++++++
sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S | 6 +++---
.../sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S | 2 +-
sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S | 8 ++++----
sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S | 4 ++--
5 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8caa301..f84b981 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2016-08-02 David S. Miller <davem@davemloft.net>
+ * sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S
+ (__nearbyint_vis3): Don't check for sNaN before float register is
+ loaded with the incoming argument.
+ * sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S
+ (__nearbyintf_vis3): Likewise.
+ * sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S (__nearbyint):
+ Likewise.
+ * sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S (__nearbyintf):
+ Likewise.
+
* string/test-strncmp.c (do_test_limit): Make sure the test data
stream is aligned as required for the type "CHAR".
(do_test): Likewise.
diff --git a/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S b/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S
index d9ff0cc..ff81b0d 100644
--- a/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S
+++ b/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S
@@ -36,15 +36,15 @@
#define SIGN_BIT %f12 /* -0.0 */
ENTRY (__nearbyint_vis3)
+ sllx %o0, 32, %o0
+ or %o0, %o1, %o0
+ movxtod %o0, %f0
fcmpd %fcc3, %f0, %f0 /* Check for sNaN */
st %fsr, [%sp + 88]
sethi %hi(TWO_FIFTYTWO), %o2
sethi %hi(0xf8003e0), %o5
ld [%sp + 88], %o4
- sllx %o0, 32, %o0
or %o5, %lo(0xf8003e0), %o5
- or %o0, %o1, %o0
- movxtod %o0, %f0
andn %o4, %o5, %o4
fzero ZERO
st %o4, [%sp + 80]
diff --git a/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S b/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S
index 5cd1eb0..833a0df 100644
--- a/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S
+++ b/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S
@@ -35,9 +35,9 @@
#define SIGN_BIT %f12 /* -0.0 */
ENTRY (__nearbyintf_vis3)
+ movwtos %o0, %f1
fcmps %fcc3, %f1, %f1 /* Check for sNaN */
st %fsr, [%sp + 88]
- movwtos %o0, %f1
sethi %hi(TWO_TWENTYTHREE), %o2
sethi %hi(0xf8003e0), %o5
ld [%sp + 88], %o4
diff --git a/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S b/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S
index 84a1097..198440a 100644
--- a/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S
+++ b/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S
@@ -36,21 +36,21 @@
#define SIGN_BIT %f12 /* -0.0 */
ENTRY (__nearbyint)
+ sllx %o0, 32, %o0
+ or %o0, %o1, %o0
+ stx %o0, [%sp + 72]
+ ldd [%sp + 72], %f0
fcmpd %fcc3, %f0, %f0 /* Check for sNaN */
st %fsr, [%sp + 88]
sethi %hi(TWO_FIFTYTWO), %o2
sethi %hi(0xf8003e0), %o5
ld [%sp + 88], %o4
- sllx %o0, 32, %o0
or %o5, %lo(0xf8003e0), %o5
- or %o0, %o1, %o0
andn %o4, %o5, %o4
fzero ZERO
st %o4, [%sp + 80]
- stx %o0, [%sp + 72]
sllx %o2, 32, %o2
fnegd ZERO, SIGN_BIT
- ldd [%sp + 72], %f0
ld [%sp + 80], %fsr
stx %o2, [%sp + 72]
fabsd %f0, %f14
diff --git a/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S b/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S
index d5cf5ce..9be41f6 100644
--- a/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S
+++ b/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S
@@ -35,9 +35,10 @@
#define SIGN_BIT %f12 /* -0.0 */
ENTRY (__nearbyintf)
+ st %o0, [%sp + 68]
+ ld [%sp + 68], %f1
fcmps %fcc3, %f1, %f1 /* Check for sNaN */
st %fsr, [%sp + 88]
- st %o0, [%sp + 68]
sethi %hi(TWO_TWENTYTHREE), %o2
sethi %hi(0xf8003e0), %o5
ld [%sp + 88], %o4
@@ -46,7 +47,6 @@ ENTRY (__nearbyintf)
fnegs ZERO, SIGN_BIT
andn %o4, %o5, %o4
st %o4, [%sp + 80]
- ld [%sp + 68], %f1
ld [%sp + 80], %fsr
st %o2, [%sp + 68]
fabss %f1, %f14
--
2.1.2.532.g19b5d50