]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
real.c (spu_single_format): New variable.
authorUlrich Weigand <uweigand@de.ibm.com>
Tue, 12 Aug 2008 13:13:38 +0000 (13:13 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Tue, 12 Aug 2008 13:13:38 +0000 (13:13 +0000)
ChangeLog:

* real.c (spu_single_format): New variable.
* real.h (spu_single_format): Declare.

* config/spu/spu.c (spu_override_options): Install SFmode format.
(spu_split_immediate): Use integer mode to operate on pieces of
floating-point values in all cases.

* config/spu/spu.md (UNSPEC_FLOAT_EXTEND, UNSPEC_FLOAT_TRUNCATE): New.
("extendsfdf2"): Use UNSPEC_FLOAT_EXTEND instead of FLOAT_EXTEND.
("truncdfsf2"): Use UNSPEC_FLOAT_TRUNCATE instead of FLOAT_TRUNCATE.

testsuite/ChangeLog:

* gcc.c-torture/execute/ieee/inf-2.c (testf): Skip on the SPU.

Co-Authored-By: Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
From-SVN: r139013

gcc/ChangeLog
gcc/config/spu/spu.c
gcc/config/spu/spu.md
gcc/real.c
gcc/real.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c

index 42afad26c729434730ad80f972548cc2d1e90436..cbd499ee0fb76cea04eed1d2cfa3b651dcb48c11 100644 (file)
@@ -1,3 +1,17 @@
+2008-08-12  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+           Trevor Smigiel  <trevor_smigiel@playstation.sony.com>
+
+       * real.c (spu_single_format): New variable.
+       * real.h (spu_single_format): Declare.
+
+       * config/spu/spu.c (spu_override_options): Install SFmode format.
+       (spu_split_immediate): Use integer mode to operate on pieces of
+       floating-point values in all cases.
+
+       * config/spu/spu.md (UNSPEC_FLOAT_EXTEND, UNSPEC_FLOAT_TRUNCATE): New.
+       ("extendsfdf2"): Use UNSPEC_FLOAT_EXTEND instead of FLOAT_EXTEND.
+       ("truncdfsf2"): Use UNSPEC_FLOAT_TRUNCATE instead of FLOAT_TRUNCATE.
+
 2008-08-12  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
 
        * config/spu/spu.c (spu_safe_dma): Respect TARGET_SAFE_DMA.
index 230f4c076981fbdf0a99da74df83b6ebf4b905f9..1021a918275b68fdbe5e86d3aa7b08beb4323c05 100644 (file)
@@ -352,6 +352,8 @@ spu_override_options (void)
       else
         error ("Unknown architecture '%s'", &spu_tune_string[0]);
     }
+
+  REAL_MODE_FORMAT (SFmode) = &spu_single_format;
 }
 \f
 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
@@ -1519,10 +1521,18 @@ spu_split_immediate (rtx * ops)
       {
        unsigned char arrhi[16];
        unsigned char arrlo[16];
-       rtx to, hi, lo;
+       rtx to, temp, hi, lo;
        int i;
+       enum machine_mode imode = mode;
+       /* We need to do reals as ints because the constant used in the
+          IOR might not be a legitimate real constant. */
+       imode = int_mode_for_mode (mode);
        constant_to_array (mode, ops[1], arrhi);
-       to = !can_create_pseudo_p () ? ops[0] : gen_reg_rtx (mode);
+       if (imode != mode)
+         to = simplify_gen_subreg (imode, ops[0], mode, 0);
+       else
+         to = ops[0];
+       temp = !can_create_pseudo_p () ? to : gen_reg_rtx (imode);
        for (i = 0; i < 16; i += 4)
          {
            arrlo[i + 2] = arrhi[i + 2];
@@ -1530,11 +1540,11 @@ spu_split_immediate (rtx * ops)
            arrlo[i + 0] = arrlo[i + 1] = 0;
            arrhi[i + 2] = arrhi[i + 3] = 0;
          }
-       hi = array_to_constant (mode, arrhi);
-       lo = array_to_constant (mode, arrlo);
-       emit_move_insn (to, hi);
+       hi = array_to_constant (imode, arrhi);
+       lo = array_to_constant (imode, arrlo);
+       emit_move_insn (temp, hi);
        emit_insn (gen_rtx_SET
-                  (VOIDmode, ops[0], gen_rtx_IOR (mode, to, lo)));
+                  (VOIDmode, to, gen_rtx_IOR (imode, temp, lo)));
        return 1;
       }
     case IC_FSMBI2:
index c267efd29d1b47a783cc51cc7f52fdcff7f10477..e50a65a188979a81ff15af8a6d385962233e0199 100644 (file)
  (UNSPEC_SPU_REALIGN_LOAD 49)
  (UNSPEC_SPU_MASK_FOR_LOAD 50)
  (UNSPEC_DFTSV          51)
+ (UNSPEC_FLOAT_EXTEND   52)
+ (UNSPEC_FLOAT_TRUNCATE         53)
 ])
 
 (include "predicates.md")
 
 (define_insn "extendsfdf2"
   [(set (match_operand:DF 0 "spu_reg_operand" "=r")
-       (float_extend:DF (match_operand:SF 1 "spu_reg_operand" "r")))]
+       (unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")]
+                   UNSPEC_FLOAT_EXTEND))]
   ""
   "fesd\t%0,%1"
   [(set_attr "type" "fpd")])
 
 (define_insn "truncdfsf2"
   [(set (match_operand:SF 0 "spu_reg_operand" "=r")
-       (float_truncate:SF (match_operand:DF 1 "spu_reg_operand" "r")))]
+       (unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")]
+                   UNSPEC_FLOAT_TRUNCATE))]
   ""
   "frds\t%0,%1"
   [(set_attr "type" "fpd")])
index b07175696837c7c943950c72d624174a2cabc7fd..49eb97d740c63b681367c46863cb0d36a6c81007 100644 (file)
@@ -2862,6 +2862,36 @@ const struct real_format motorola_single_format =
     true,
     true
   };
+
+/*  SPU Single Precision (Extended-Range Mode) format is the same as IEEE
+    single precision with the following differences:
+      - Infinities are not supported.  Instead MAX_FLOAT or MIN_FLOAT
+       are generated.
+      - NaNs are not supported.
+      - The range of non-zero numbers in binary is
+       (001)[1.]000...000 to (255)[1.]111...111.
+      - Denormals can be represented, but are treated as +0.0 when
+       used as an operand and are never generated as a result.
+      - -0.0 can be represented, but a zero result is always +0.0.
+      - the only supported rounding mode is trunction (towards zero).  */
+const struct real_format spu_single_format =
+  {
+    encode_ieee_single,
+    decode_ieee_single,
+    2,
+    24,
+    24,
+    -125,
+    129,
+    31,
+    31,
+    false,
+    false,
+    true,
+    true,
+    false,
+    false
+  };
 \f
 /* IEEE double-precision format.  */
 
index 633229969a7c9554db21814ef397ddbe89b80fc5..39522b6332c5e1eac9d80b09a51f9ae327ad65c6 100644 (file)
@@ -259,6 +259,7 @@ extern unsigned int real_hash (const REAL_VALUE_TYPE *);
 extern const struct real_format ieee_single_format;
 extern const struct real_format mips_single_format;
 extern const struct real_format motorola_single_format;
+extern const struct real_format spu_single_format;
 extern const struct real_format ieee_double_format;
 extern const struct real_format mips_double_format;
 extern const struct real_format motorola_double_format;
index d6f281122e3e57480bb4182386f093fdd3a03494..8653a14d64aeecc7bbb5c0731a84a5542aa23396 100644 (file)
@@ -1,3 +1,7 @@
+2008-08-12  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+       * gcc.c-torture/execute/ieee/inf-2.c (testf): Skip on the SPU.
+
 2008-08-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/36688
index 40270c0f6abcb8bd2e1a7d0e452b8e4fc61bc561..1823b35ff0ff18a9ba0368b31157ebc5d39a8a02 100644 (file)
@@ -25,6 +25,9 @@ void test(double f, double i)
 
 void testf(float f, float i)
 {
+#ifndef __SPU__
+  /* The SPU single-precision floating point format does not support Inf.  */
+
   if (f == __builtin_inff())
     abort ();
   if (f == -__builtin_inff())
@@ -44,6 +47,7 @@ void testf(float f, float i)
     abort ();
   if (f < -__builtin_inff())
     abort ();
+#endif
 }
 
 void testl(long double f, long double i)