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.

Cheers

Christian

2010-04-20  Christian Bruel  <christian.br...@st.com>

        * gcc.dg/builtins-nan.c: New test.

2010-04-20  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. Clobber R2.




2010-04-20  Christian Bruel  <christian.br...@st.com>

        * gcc.dg/builtins-nan.c: New test.

2010-04-20  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. Clobber R2.

Index: gcc/config/sh/ieee-754-df.S
===================================================================
--- gcc/config/sh/ieee-754-df.S (revision 1352)
+++ gcc/config/sh/ieee-754-df.S (revision 1373)
@@ -88,11 +88,12 @@
        HIDDEN_FUNC(GLOBAL(nedf2f))
 GLOBAL(nedf2f):
        cmp/eq  DBL0L,DBL1L
+       bf.s    LOCAL(ne)
+       mov     #1,r0
+       cmp/eq  DBL0H,DBL1H
        mov.l   LOCAL(c_DF_NAN_MASK),r1
-       bf LOCAL(ne)
-       cmp/eq  DBL0H,DBL1H
-       not     DBL0H,r0
-       bt      LOCAL(check_nan)
+       bt.s    LOCAL(check_nan)
+       not     DBL0H,r0        
        mov     DBL0H,r0
        or      DBL1H,r0
        add     r0,r0
@@ -100,11 +101,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

Index: gcc/config/sh/ieee-754-sf.S
===================================================================
--- gcc/config/sh/ieee-754-sf.S (revision 1352)
+++ gcc/config/sh/ieee-754-sf.S (revision 1373)
@@ -55,19 +55,27 @@
           the values are NaN.  */
        cmp/eq  r4,r5
        mov.l   LOCAL(c_SF_NAN_MASK),r1
+       bt.s    LOCAL(check_nan)
        not     r4,r0
-       bt      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
 LOCAL(c_SF_NAN_MASK):
        .long SF_NAN_MASK
+LOCAL(c_SF_SNAN_MASK):
        ENDFUNC(GLOBAL(nesf2f))
 #endif /* L_nesf2f */
 
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md (revision 1352)
+++ gcc/config/sh/sh.md (revision 1373)
@@ -11182,6 +11182,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%#"
@@ -11257,13 +11258,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.
@@ -11967,6 +11973,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%#"
@@ -12008,13 +12015,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.
/* { dg-do run } */
/* { dg-options "-mieee" { target sh*-*-* } } */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

static int lisnan(double v)
{
  return (v != v);
}

static int lisnanf(float v)
{
  return (v != v);
}

int main(void)
{
  double d;
  float f;

  /* double */
  d = __builtin_nans("");
  if (! lisnan(d))
    abort();

  if (! __builtin_isnan(d))
    abort();

  d = __builtin_nan("");
  if (! lisnan(d))
    abort();

  if (! __builtin_isnan(d))
    abort();

  /* float */
  f = __builtin_nansf("");
  if (! lisnanf(f))
    abort();

  if (! __builtin_isnanf(f))
    abort();

  f = __builtin_nanf("");
  if (! lisnanf(f))
    abort();

  if (! __builtin_isnanf(f))
    abort();

  exit (0);
}

Reply via email to