Christian Bruel wrote:
Hi Kaz,
Kaz Kojima wrote:
BTW, it looks that softfp __unord?f2 routines check signaling NaNs
only. This makes __builtin_isnan return false for quiet NaNs for
which current fp-bit ones return true when -mieee enabled. Perhaps
that change of behavior might be OK for software FP.
I use the attached patch to handle the QNaNs in the assembly solf-fp.
Need to be updated for trunk (and update the dates in changelogs). Will do.
Edited to apply on top of latest Joern's patch. Certainly not optimal
but it fixes the QNaNs checks for builtins and inlined unordered
comparisons for -mieee or -fno-inite-math-only.
Best Regards
Christian
2010-07-22 Christian Bruel <christian.br...@st.com>
* gcc.dg/builtins-nan.c: New test.
2010-07-22 Christian Bruel <christian.br...@st.com>
* config/sh/ieee-754-df.S (nedf2f): Don't check Qbit for NaNs.
* config/sh/ieee-754-sf.S (nesf2f): Likewise.
* config/sh/sh.md (cmpunsf_i1, cmpundf_i1): Likewise.
(cmpnesf_i1, cmpnedf_i1): Clobber R2.
diff '--exclude=.svn' '--exclude=*.rej' '--exclude=*~' -ubrN
gnu_trunk.ref/gcc/gcc/config/sh/ieee-754-df.S
gnu_trunk/gcc/gcc/config/sh/ieee-754-df.S
--- gnu_trunk.ref/gcc/gcc/config/sh/ieee-754-df.S 2010-07-21
18:04:17.000000000 +0200
+++ gnu_trunk/gcc/gcc/config/sh/ieee-754-df.S 2010-07-21 18:09:10.000000000
+0200
@@ -92,11 +92,12 @@
HIDDEN_FUNC(GLOBAL(nedf2))
GLOBAL(nedf2):
cmp/eq DBL0L,DBL1L
- mov.l LOCAL(c_DF_NAN_MASK),r1
- bf LOCAL(ne)
+ bf.s LOCAL(ne)
+ mov #1,r0
cmp/eq DBL0H,DBL1H
+ mov.l LOCAL(c_DF_NAN_MASK),r1
+ bt.s LOCAL(check_nan)
not DBL0H,r0
- bt LOCAL(check_nan)
mov DBL0H,r0
or DBL1H,r0
add r0,r0
@@ -104,11 +105,17 @@
or DBL0L,r0
LOCAL(check_nan):
tst r1,r0
- rts
+ bt.s LOCAL(nan)
+ mov #12,r2
+ shll16 r2
+ xor r2,r1
+ tst r1,r0
+LOCAL(nan):
movt r0
LOCAL(ne):
rts
- mov #1,r0
+ nop
+
.balign 4
LOCAL(c_DF_NAN_MASK):
.long DF_NAN_MASK
diff '--exclude=.svn' '--exclude=*.rej' '--exclude=*~' -ubrN
gnu_trunk.ref/gcc/gcc/config/sh/ieee-754-sf.S
gnu_trunk/gcc/gcc/config/sh/ieee-754-sf.S
--- gnu_trunk.ref/gcc/gcc/config/sh/ieee-754-sf.S 2010-07-21
18:04:18.000000000 +0200
+++ gnu_trunk/gcc/gcc/config/sh/ieee-754-sf.S 2010-07-21 18:09:10.000000000
+0200
@@ -51,13 +51,19 @@
cmp/eq r4,r5
mov.l LOCAL(c_SF_NAN_MASK),r1
not r4,r0
- bt LOCAL(check_nan)
+ bt.s LOCAL(check_nan)
mov r4,r0
or r5,r0
rts
add r0,r0
LOCAL(check_nan):
tst r1,r0
+ bt.s LOCAL(nan)
+ mov #96,r2
+ shll16 r2
+ xor r2,r1
+ tst r1,r0
+ LOCAL(nan):
rts
movt r0
.balign 4
diff '--exclude=.svn' '--exclude=*.rej' '--exclude=*~' -ubrN
gnu_trunk.ref/gcc/gcc/config/sh/sh.md gnu_trunk/gcc/gcc/config/sh/sh.md
--- gnu_trunk.ref/gcc/gcc/config/sh/sh.md 2010-07-21 18:06:25.000000000
+0200
+++ gnu_trunk/gcc/gcc/config/sh/sh.md 2010-07-22 09:13:12.000000000 +0200
@@ -10262,6 +10262,7 @@
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:SI R1_REG))
+ (clobber (reg:SI R2_REG))
(use (match_operand:SI 1 "arith_reg_operand" "r"))]
"TARGET_SH1 && ! TARGET_SH2E"
"jsr @%1%#"
@@ -10337,13 +10338,18 @@
(define_insn "cmpunsf_i1"
[(set (reg:SI T_REG)
- (unordered:SI (match_operand:SF 0 "arith_reg_operand" "r,r")
- (match_operand:SF 1 "arith_reg_operand" "r,r")))
- (use (match_operand:SI 2 "arith_reg_operand" "r,r"))
- (clobber (match_scratch:SI 3 "=0,&r"))]
+ (unordered:SI (match_operand:SF 0 "arith_reg_operand" "r")
+ (match_operand:SF 1 "arith_reg_operand" "r")))
+ (use (match_operand:SI 2 "arith_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "=&r"))]
"TARGET_SH1 && ! TARGET_SH2E"
- "not\t%0,%3\;tst\t%2,%3\;not\t%1,%3\;bt\t0f\;tst\t%2,%3\;0:"
- [(set_attr "length" "10")])
+ "not\t%0,%3\;tst\t%2,%3\;bt.s\t0f
+ \tnot\t%1,%3\;tst\t%2,%3\;bt.s\t0f
+ \tmov\t#96,%3\;shll16\t%3\;xor\t%3,%2
+ \tnot\t%0,%3\;tst\t%2,%3\;bt.s\t0f
+ \tnot\t%1,%3\;tst\t%2,%3
+ 0:"
+ [(set_attr "length" "28")])
;; ??? This is a lot of code with a lot of branches; a library function
;; might be better.
@@ -11069,6 +11075,7 @@
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:SI R1_REG))
+ (clobber (reg:SI R2_REG))
(use (match_operand:SI 1 "arith_reg_operand" "r"))]
"TARGET_SH1_SOFTFP"
"jsr @%1%#"
@@ -11093,6 +11100,7 @@
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:SI R1_REG))
+ (clobber (reg:SI R2_REG))
(use (match_operand:SI 1 "arith_reg_operand" "r"))]
"TARGET_SH1_SOFTFP"
"jsr @%1%#"
@@ -11110,13 +11118,18 @@
(define_insn "cmpundf_i1"
[(set (reg:SI T_REG)
- (unordered:SI (match_operand:DF 0 "arith_reg_operand" "r,r")
- (match_operand:DF 1 "arith_reg_operand" "r,r")))
- (use (match_operand:SI 2 "arith_reg_operand" "r,r"))
- (clobber (match_scratch:SI 3 "=0,&r"))]
+ (unordered:SI (match_operand:DF 0 "arith_reg_operand" "r")
+ (match_operand:DF 1 "arith_reg_operand" "r")))
+ (use (match_operand:SI 2 "arith_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "=&r"))]
"TARGET_SH1 && ! TARGET_SH2E"
- "not\t%S0,%3\;tst\t%2,%3\;not\t%S1,%3\;bt\t0f\;tst\t%2,%3\;0:"
- [(set_attr "length" "10")])
+ "not\t%S0,%3\;tst\t%2,%3\;bt.s\t0f
+ \tnot\t%S1,%3\;tst\t%2,%3\;bt.s\t0f
+ \tmov\t#12,%3\;shll16\t%3\;xor\t%3,%2
+ \tnot\t%S0,%3\;tst\t%2,%3\;bt.s\t0f
+ \tnot\t%S1,%3\;tst\t%2,%3
+0:"
+ [(set_attr "length" "28")])
;; ??? This is a lot of code with a lot of branches; a library function
;; might be better.