]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Allow non-constant arguments to conversion intrinsics.
authortsmigiel <tsmigiel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 27 Apr 2009 18:48:59 +0000 (18:48 +0000)
committertsmigiel <tsmigiel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 27 Apr 2009 18:48:59 +0000 (18:48 +0000)
* spu-protos.h (exp2_immediate_p, spu_gen_exp2): Declare.
* predicates.md (spu_inv_exp2_operand, spu_exp2_operand): New.
* spu.c (print_operand): Handle 'v' and 'w'.
(exp2_immediate_p, spu_gen_exp2): Define.
* spu-builtins.def (spu_convts, spu_convtu, spu_convtf_0,
spu_convtf_1): Update parameter descriptions.
* spu-builtins.md (spu_csflt, spu_cuflt, spu_cflts, spu_cfltu):
Update.
* constraints.md ('v', 'w'): New.
* spu.md (UNSPEC_CSFLT, UNSPEC_CFLTS, UNSPEC_CUFLT, UNSPEC_CFLTU):
Remove.
(i2f, I2F): New define_mode_attr.
(floatsisf2, floatv4siv4sf2, fix_truncsfsi2, fix_truncv4sfv4si2,
floatunssisf2, floatunsv4siv4sf2, fixuns_truncsfsi2,
fixuns_truncv4sfv4si2):  Update to use mode attribute.
(float<mode><i2f>2_mul, float<mode><i2f>2_div,
fix_trunc<mode><f2i>2_mul, floatuns<mode><i2f>2_mul,
floatuns<mode><i2f>2_div, fixuns_trunc<mode><f2i>2_mul): New
patterns for combine.
* gcc.target/spu/intrinsics-3.c: Update tests.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146849 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/spu/constraints.md
gcc/config/spu/predicates.md
gcc/config/spu/spu-builtins.def
gcc/config/spu/spu-builtins.md
gcc/config/spu/spu-protos.h
gcc/config/spu/spu.c
gcc/config/spu/spu.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/spu/intrinsics-3.c

index 17520f47292814aae4c2a0fde968199cf1dff0c0..013c0fcea4e2a1bf331868fc42a03bced46ec0ac 100644 (file)
@@ -1,3 +1,26 @@
+2009-04-27  Trevor Smigiel <trevor_smigiel@playstation.sony.com>
+
+       Allow non-constant arguments to conversion intrinsics.
+       * spu-protos.h (exp2_immediate_p, spu_gen_exp2): Declare.
+       * predicates.md (spu_inv_exp2_operand, spu_exp2_operand): New.
+       * spu.c (print_operand): Handle 'v' and 'w'.
+       (exp2_immediate_p, spu_gen_exp2): Define.
+       * spu-builtins.def (spu_convts, spu_convtu, spu_convtf_0,
+       spu_convtf_1): Update parameter descriptions.
+       * spu-builtins.md (spu_csflt, spu_cuflt, spu_cflts, spu_cfltu):
+       Update.
+       * constraints.md ('v', 'w'): New.
+       * spu.md (UNSPEC_CSFLT, UNSPEC_CFLTS, UNSPEC_CUFLT, UNSPEC_CFLTU):
+       Remove.
+       (i2f, I2F): New define_mode_attr.
+       (floatsisf2, floatv4siv4sf2, fix_truncsfsi2, fix_truncv4sfv4si2,
+       floatunssisf2, floatunsv4siv4sf2, fixuns_truncsfsi2,
+       fixuns_truncv4sfv4si2):  Update to use mode attribute.
+       (float<mode><i2f>2_mul, float<mode><i2f>2_div,
+       fix_trunc<mode><f2i>2_mul, floatuns<mode><i2f>2_mul,
+       floatuns<mode><i2f>2_div, fixuns_trunc<mode><f2i>2_mul): New
+       patterns for combine.
+
 2009-04-27  Steven Bosscher  <steven@gcc.gnu.org>
 
        * dbgcnt.def (cprop1, cprop2, gcse, jump_bypass): Remove
index fe81b2f66a8933832dfb34e9e6bed3079f05f81c..b1f5947064cc5e3f3d6fcc588160f2caef69b77d 100644 (file)
 ;; <http://www.gnu.org/licenses/>.
 
 \f
-;; GCC standard constraints:  g, i, m, n, o, p, r, s, E-H, I-P, V, X
-;; unused for SPU:  E-H, L, Q, d, e, h, q, t-z
+;;       ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+;; GCC:      ffffiiiiiiii     x x        x x   xxxx xx
+;; SPU:  xxxx    xxx xxxx xxxx x xxx xx x   xxx         xx
+;; FREE:     ffff   i    a          a  a  a        a  aa  aaa
+;; x - used
+;; a - available
+;; i - available for integer immediates
+;; f - available for floating point immediates
 
 ;; For most immediate constraints we have 3 variations to deal with the
 ;; fact const_int has no mode.  One variation treats const_int as 32 bit,
                    && INTVAL (XEXP (op, 0)) >= 0
                    && INTVAL (XEXP (op, 0)) <= 0x3ffff")))
 
+\f
+;; Floating-point constant constraints.
+
+(define_constraint "v"
+  "Floating point power of 2 with exponent in [0..127]"
+  (and (match_code "const_double,const_vector")
+       (match_test "exp2_immediate_p (op, VOIDmode, 0, 127)")))
 
+(define_constraint "w"
+  "Floating point power of 2 with exponent in [-126..0]"
+  (and (match_code "const_double,const_vector")
+       (match_test "exp2_immediate_p (op, VOIDmode, -126, 0)")))
index 7e5c6a9da6eb9a567e8f72d42eb7901f0ede0485..ce91ba230bb1d0c20319a877d39bff844bc5f355 100644 (file)
        (ior (match_test "GET_MODE (XEXP (op, 0)) == HImode")
            (match_test "GET_MODE (XEXP (op, 0)) == SImode"))))
 
+(define_predicate "spu_inv_exp2_operand"
+  (and (match_code "const_double,const_vector")
+       (and (match_operand 0 "immediate_operand")
+           (match_test "exp2_immediate_p (op, mode, -126, 0)"))))
+
+(define_predicate "spu_exp2_operand"
+  (and (match_code "const_double,const_vector")
+       (and (match_operand 0 "immediate_operand")
+           (match_test "exp2_immediate_p (op, mode, 0, 127)"))))
+
index b0f8e312f8622748f4ae4b0e67ef6d37c34b06f9..9e92781d31128059e3d6296f9a02a2ef765dec92 100644 (file)
@@ -235,8 +235,8 @@ DEF_BUILTIN (SI_FROM_PTR,    CODE_FOR_spu_convert,   "si_from_ptr",    B_INSN,
 
 /* definitions to support generic builtin functions: */
 
-DEF_BUILTIN (SPU_CONVTS,     CODE_FOR_spu_cflts,      "spu_convts",     B_INSN,     _A3(SPU_BTI_V4SI,     SPU_BTI_V4SF,   SPU_BTI_U7))
-DEF_BUILTIN (SPU_CONVTU,     CODE_FOR_spu_cfltu,      "spu_convtu",     B_INSN,     _A3(SPU_BTI_UV4SI,    SPU_BTI_V4SF,   SPU_BTI_U7))
+DEF_BUILTIN (SPU_CONVTS,     CODE_FOR_spu_cflts,      "spu_convts",     B_INSN,     _A3(SPU_BTI_V4SI,     SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_CONVTU,     CODE_FOR_spu_cfltu,      "spu_convtu",     B_INSN,     _A3(SPU_BTI_UV4SI,    SPU_BTI_V4SF,   SPU_BTI_INTSI))
 DEF_BUILTIN (SPU_ROUNDTF,    CODE_FOR_spu_frds,       "spu_roundtf",    B_INSN,     _A2(SPU_BTI_V4SF,     SPU_BTI_V2DF))
 DEF_BUILTIN (SPU_MULH,       CODE_FOR_spu_mpyh,       "spu_mulh",       B_INSN,     _A3(SPU_BTI_V4SI,     SPU_BTI_V8HI,   SPU_BTI_V8HI))
 DEF_BUILTIN (SPU_MULSR,      CODE_FOR_spu_mpys,       "spu_mulsr",      B_INSN,     _A3(SPU_BTI_V4SI,     SPU_BTI_V8HI,   SPU_BTI_V8HI))
@@ -257,8 +257,8 @@ DEF_BUILTIN (SPU_TESTSV,     CODE_FOR_dftsv,          "spu_testsv",     B_INSN,
 /* definitions to support overloaded generic builtin functions:  */
 
 DEF_BUILTIN (SPU_CONVTF,           CODE_FOR_nothing,       "spu_convtf",           B_OVERLOAD, _A1(SPU_BTI_VOID))
-DEF_BUILTIN (SPU_CONVTF_0,         CODE_FOR_spu_cuflt,     "spu_convtf_0",         B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_UV4SI,  SPU_BTI_U7))
-DEF_BUILTIN (SPU_CONVTF_1,         CODE_FOR_spu_csflt,     "spu_convtf_1",         B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SI,   SPU_BTI_U7))
+DEF_BUILTIN (SPU_CONVTF_0,         CODE_FOR_spu_cuflt,     "spu_convtf_0",         B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_CONVTF_1,         CODE_FOR_spu_csflt,     "spu_convtf_1",         B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SI,   SPU_BTI_UINTSI))
 DEF_BUILTIN (SPU_EXTEND,           CODE_FOR_nothing,       "spu_extend",           B_OVERLOAD, _A1(SPU_BTI_VOID))
 DEF_BUILTIN (SPU_EXTEND_0,         CODE_FOR_spu_xsbh,      "spu_extend_0",         B_INTERNAL, _A2(SPU_BTI_V8HI,   SPU_BTI_V16QI))
 DEF_BUILTIN (SPU_EXTEND_1,         CODE_FOR_spu_xshw,      "spu_extend_1",         B_INTERNAL, _A2(SPU_BTI_V4SI,   SPU_BTI_V8HI))
index 325a80d6b293b911508d587b6c336015b0330447..ac3a333610674e35f7055b59896cfee5c8173f2d 100644 (file)
   [(set_attr "type" "br")])
 
 ;; float convert
-(define_insn "spu_csflt"
+(define_expand "spu_csflt"
+  [(set (match_operand:V4SF 0 "spu_reg_operand")
+       (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand")
+                     (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
+  ""
+{
+  if (GET_CODE (operands[2]) == CONST_INT
+      && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
+    {
+      error ("spu_convtf expects an integer literal in the range [0, 127].");
+      operands[2] = force_reg (SImode, operands[2]);
+    }
+  if (GET_CODE (operands[2]) != CONST_INT)
+    {
+      rtx exp2;
+      rtx cnv = gen_reg_rtx (V4SFmode);
+      rtx scale = gen_reg_rtx (SImode);
+      rtx op2 = force_reg (SImode, operands[2]);
+      rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1));
+      emit_insn (gen_subsi3 (scale, const1_rtx, op2));
+      exp2 = spu_gen_exp2 (V4SFmode, scale);
+      emit_insn (gen_floatv4siv4sf2_mul (cnv, operands[1], m1));
+      emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2));
+    }
+  else
+    {
+      rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
+      emit_insn (gen_floatv4siv4sf2_div (operands[0], operands[1], exp2));
+    }
+  DONE;
+})
+
+(define_expand "spu_cflts"
+  [(set (match_operand:V4SI 0 "spu_reg_operand")
+       (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand")
+                      (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
+  ""
+{
+  rtx exp2;
+  if (GET_CODE (operands[2]) == CONST_INT
+      && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
+    {
+      error ("spu_convts expects an integer literal in the range [0, 127].");
+      operands[2] = force_reg (SImode, operands[2]);
+    }
+  exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
+  if (GET_CODE (operands[2]) != CONST_INT)
+    {
+      rtx mul = gen_reg_rtx (V4SFmode);
+      emit_insn (gen_mulv4sf3 (mul, operands[1], exp2));
+      emit_insn (gen_fix_truncv4sfv4si2 (operands[0], mul));
+    }
+  else 
+    emit_insn (gen_fix_truncv4sfv4si2_mul (operands[0], operands[1], exp2));
+  DONE;
+})
+
+(define_expand "spu_cuflt"
   [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
-       (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
-                     (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CSFLT ))]
-  ""
-  "csflt\t%0,%1,%2"
-  [(set_attr "type" "fp7")])
-
-(define_insn "spu_cflts"
-  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
-       (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
-                      (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTS ))]
-  ""
-  "cflts\t%0,%1,%2"
-  [(set_attr "type" "fp7")])
-
-(define_insn "spu_cuflt"
-  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
-       (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
-                     (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CUFLT ))]
-  ""
-  "cuflt\t%0,%1,%2"
-  [(set_attr "type" "fp7")])
-
-(define_insn "spu_cfltu"
-  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
-       (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
-                     (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTU ))]
-  ""
-  "cfltu\t%0,%1,%2"
-  [(set_attr "type" "fp7")])
+       (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand")
+                     (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
+  ""
+{
+  if (GET_CODE (operands[2]) == CONST_INT
+      && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
+    {
+      error ("spu_convtf expects an integer literal in the range [0, 127].");
+      operands[2] = force_reg (SImode, operands[2]);
+    }
+  if (GET_CODE (operands[2]) != CONST_INT)
+    {
+      rtx exp2;
+      rtx cnv = gen_reg_rtx (V4SFmode);
+      rtx scale = gen_reg_rtx (SImode);
+      rtx op2 = force_reg (SImode, operands[2]);
+      rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1));
+      emit_insn (gen_subsi3 (scale, const1_rtx, op2));
+      exp2 = spu_gen_exp2 (V4SFmode, scale);
+      emit_insn (gen_floatunsv4siv4sf2_mul (cnv, operands[1], m1));
+      emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2));
+    }
+  else
+    {
+      rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
+      emit_insn (gen_floatunsv4siv4sf2_div (operands[0], operands[1], exp2));
+    }
+  DONE;
+})
+
+(define_expand "spu_cfltu"
+  [(set (match_operand:V4SI 0 "spu_reg_operand")
+       (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand")
+                     (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
+  ""
+{
+  rtx exp2;
+  if (GET_CODE (operands[2]) == CONST_INT
+      && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
+    {
+      error ("spu_convtu expects an integer literal in the range [0, 127].");
+      operands[2] = force_reg (SImode, operands[2]);
+    }
+  exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
+  if (GET_CODE (operands[2]) != CONST_INT)
+    {
+      rtx mul = gen_reg_rtx (V4SFmode);
+      emit_insn (gen_mulv4sf3 (mul, operands[1], exp2));
+      emit_insn (gen_fixuns_truncv4sfv4si2 (operands[0], mul));
+    }
+  else 
+    emit_insn (gen_fixuns_truncv4sfv4si2_mul (operands[0], operands[1], exp2));
+  DONE;
+})
 
 (define_expand "spu_frds"
    [(set (match_operand:V4SF 0 "spu_reg_operand" "")
index 07eb654c7f3f622349111fc6a8e6e5fedb7a6093..d8376d86d0f3268437e55594cf25e9d0cba1cb37 100644 (file)
@@ -51,6 +51,8 @@ extern int logical_immediate_p (rtx op, enum machine_mode mode);
 extern int iohl_immediate_p (rtx op, enum machine_mode mode);
 extern int arith_immediate_p (rtx op, enum machine_mode mode,
                              HOST_WIDE_INT low, HOST_WIDE_INT high);
+extern bool exp2_immediate_p (rtx op, enum machine_mode mode, int low,
+                             int high);
 extern int spu_constant_address_p (rtx x);
 extern int spu_legitimate_constant_p (rtx x);
 extern int spu_legitimate_address (enum machine_mode mode, rtx x,
@@ -75,6 +77,7 @@ extern rtx gen_cpat_const (rtx * ops);
 extern void constant_to_array (enum machine_mode mode, rtx x,
                               unsigned char *arr);
 extern rtx array_to_constant (enum machine_mode mode, unsigned char *arr);
+extern rtx spu_gen_exp2 (enum machine_mode mode, rtx x);
 extern void spu_allocate_stack (rtx op0, rtx op1);
 extern void spu_restore_stack_nonlocal (rtx op0, rtx op1);
 extern void spu_restore_stack_block (rtx op0, rtx op1);
index a51170bad21b38141ec680b83d277cc4619ec0e4..56abdf8deb383ac1606476d8090eb168c2b832ad 100644 (file)
@@ -1586,6 +1586,13 @@ print_operand (FILE * file, rtx x, int code)
       output_addr_const (file, GEN_INT (val));
       return;
 
+    case 'v':
+    case 'w':
+      constant_to_array (mode, x, arr);
+      val = (((arr[0] << 1) + (arr[1] >> 7)) & 0xff) - 127;
+      output_addr_const (file, GEN_INT (code == 'w' ? -val : val));
+      return;
+
     case 0:
       if (xcode == REG)
        fprintf (file, "%s", reg_names[REGNO (x)]);
@@ -1598,7 +1605,7 @@ print_operand (FILE * file, rtx x, int code)
       return;
 
       /* unused letters
-                     o qr  uvw yz
+                     o qr  u   yz
        AB            OPQR  UVWXYZ */
     default:
       output_operand_lossage ("invalid %%xn code");
@@ -3495,6 +3502,58 @@ arith_immediate_p (rtx op, enum machine_mode mode,
   return val >= low && val <= high;
 }
 
+/* TRUE when op is an immediate and an exact power of 2, and given that
+   OP is 2^scale, scale >= LOW && scale <= HIGH.  When OP is a vector,
+   all entries must be the same. */
+bool
+exp2_immediate_p (rtx op, enum machine_mode mode, int low, int high)
+{
+  enum machine_mode int_mode;
+  HOST_WIDE_INT val;
+  unsigned char arr[16];
+  int bytes, i, j;
+
+  gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
+             || GET_CODE (op) == CONST_VECTOR);
+
+  if (GET_CODE (op) == CONST_VECTOR
+      && !const_vector_immediate_p (op))
+    return 0;
+
+  if (GET_MODE (op) != VOIDmode)
+    mode = GET_MODE (op);
+
+  constant_to_array (mode, op, arr);
+
+  if (VECTOR_MODE_P (mode))
+    mode = GET_MODE_INNER (mode);
+
+  bytes = GET_MODE_SIZE (mode);
+  int_mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
+
+  /* Check that bytes are repeated. */
+  for (i = bytes; i < 16; i += bytes)
+    for (j = 0; j < bytes; j++)
+      if (arr[j] != arr[i + j])
+       return 0;
+
+  val = arr[0];
+  for (j = 1; j < bytes; j++)
+    val = (val << 8) | arr[j];
+
+  val = trunc_int_for_mode (val, int_mode);
+
+  /* Currently, we only handle SFmode */
+  gcc_assert (mode == SFmode);
+  if (mode == SFmode)
+    {
+      int exp = (val >> 23) - 127;
+      return val > 0 && (val & 0x007fffff) == 0
+            &&  exp >= low && exp <= high;
+    }
+  return FALSE;
+}
+
 /* We accept:
    - any 32-bit constant (SImode, SFmode)
    - any constant that can be generated with fsmbi (any mode)
@@ -6364,4 +6423,36 @@ spu_section_type_flags (tree decl, const char *name, int reloc)
   return default_section_type_flags (decl, name, reloc);
 }
 
+/* Generate a constant or register which contains 2^SCALE.  We assume
+   the result is valid for MODE.  Currently, MODE must be V4SFmode and
+   SCALE must be SImode. */
+rtx
+spu_gen_exp2 (enum machine_mode mode, rtx scale)
+{
+  gcc_assert (mode == V4SFmode);
+  gcc_assert (GET_MODE (scale) == SImode || GET_CODE (scale) == CONST_INT);
+  if (GET_CODE (scale) != CONST_INT)
+    {
+      /* unsigned int exp = (127 + scale) << 23;
+       __vector float m = (__vector float) spu_splats (exp); */
+      rtx reg = force_reg (SImode, scale);
+      rtx exp = gen_reg_rtx (SImode);
+      rtx mul = gen_reg_rtx (mode);
+      emit_insn (gen_addsi3 (exp, reg, GEN_INT (127)));
+      emit_insn (gen_ashlsi3 (exp, exp, GEN_INT (23)));
+      emit_insn (gen_spu_splats (mul, gen_rtx_SUBREG (GET_MODE_INNER (mode), exp, 0)));
+      return mul;
+    }
+  else 
+    {
+      HOST_WIDE_INT exp = 127 + INTVAL (scale);
+      unsigned char arr[16];
+      arr[0] = arr[4] = arr[8] = arr[12] = exp >> 1;
+      arr[1] = arr[5] = arr[9] = arr[13] = exp << 7;
+      arr[2] = arr[6] = arr[10] = arr[14] = 0;
+      arr[3] = arr[7] = arr[11] = arr[15] = 0;
+      return array_to_constant (mode, arr);
+    }
+}
+
 #include "gt-spu.h"
index 1dccfcff66a090cba9ee9f0d19a71a3cc5bd3a79..bd6936fd9e3044a2ebab679b98ca2a81cc8d29bb 100644 (file)
  (UNSPEC_HEQ            31)
  (UNSPEC_HGT            32)
  (UNSPEC_HLGT           33)
- (UNSPEC_CSFLT          34)
- (UNSPEC_CFLTS          35)
- (UNSPEC_CUFLT          36)
- (UNSPEC_CFLTU          37)
  (UNSPEC_STOP           38)
  (UNSPEC_STOPD          39)
  (UNSPEC_SET_INTR       40)
                        (DF "di") (V2DF "v2di")])
 (define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
                        (DF "DI") (V2DF "V2DI")])
+(define_mode_attr i2f [(SI "sf") (V4SI "v4sf")
+                       (DI "df") (V2DI "v2df")])
+(define_mode_attr I2F [(SI "SF") (V4SI "V4SF")
+                       (DI "DF") (V2DI "V2DF")])
 
 (define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
 
 \f
 ;; float conversions
 
-(define_insn "floatsisf2"
-  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
-       (float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
+(define_insn "float<mode><i2f>2"
+  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
+       (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
   ""
   "csflt\t%0,%1,0"
   [(set_attr "type" "fp7")])
 
-(define_insn "floatv4siv4sf2"
-  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
-       (float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
+(define_insn "fix_trunc<mode><f2i>2"
+  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
+       (fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
   ""
-  "csflt\t%0,%1,0"
+  "cflts\t%0,%1,0"
   [(set_attr "type" "fp7")])
 
-(define_insn "fix_truncsfsi2"
-  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
-       (fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
+(define_insn "floatuns<mode><i2f>2"
+  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
+       (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
   ""
-  "cflts\t%0,%1,0"
+  "cuflt\t%0,%1,0"
   [(set_attr "type" "fp7")])
 
-(define_insn "fix_truncv4sfv4si2"
-  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
-       (fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
+(define_insn "fixuns_trunc<mode><f2i>2"
+  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
+       (unsigned_fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
   ""
-  "cflts\t%0,%1,0"
+  "cfltu\t%0,%1,0"
   [(set_attr "type" "fp7")])
 
-(define_insn "floatunssisf2"
-  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
-       (unsigned_float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
+(define_insn "float<mode><i2f>2_mul"
+  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
+       (mult:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
+                   (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
   ""
-  "cuflt\t%0,%1,0"
+  "csflt\t%0,%1,%w2"
   [(set_attr "type" "fp7")])
 
-(define_insn "floatunsv4siv4sf2"
-  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
-       (unsigned_float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
+(define_insn "float<mode><i2f>2_div"
+  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
+       (div:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
+                  (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
   ""
-  "cuflt\t%0,%1,0"
+  "csflt\t%0,%1,%v2"
   [(set_attr "type" "fp7")])
 
-(define_insn "fixuns_truncsfsi2"
-  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
-       (unsigned_fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
+
+(define_insn "fix_trunc<mode><f2i>2_mul"
+  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
+       (fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+                            (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
   ""
-  "cfltu\t%0,%1,0"
+  "cflts\t%0,%1,%v2"
   [(set_attr "type" "fp7")])
 
-(define_insn "fixuns_truncv4sfv4si2"
-  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
-       (unsigned_fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
+(define_insn "floatuns<mode><i2f>2_mul"
+  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
+       (mult:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
+                   (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
   ""
-  "cfltu\t%0,%1,0"
+  "cuflt\t%0,%1,%w2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "floatuns<mode><i2f>2_div"
+  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
+       (div:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
+                  (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
+  ""
+  "cuflt\t%0,%1,%v2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "fixuns_trunc<mode><f2i>2_mul"
+  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
+       (unsigned_fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+                                     (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
+  ""
+  "cfltu\t%0,%1,%v2"
   [(set_attr "type" "fp7")])
 
 (define_insn "extendsfdf2"
index 79b0ea129fcd2196affacdd0edc3ffd091bdd8b7..4e660e983449a1d0e833914200634c6df8f64a13 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-27  Trevor Smigiel <trevor_smigiel@playstation.sony.com>
+
+       Allow non-constant arguments to conversion intrinsics.
+       * gcc.target/spu/intrinsics-3.c: Update tests.
+
 2009-04-27  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/39928
index d468b23b6d0091ea3d2c7d2b5423bf594d8b1072..3d3946641028ff885a083cfa18eb2eac209afa70 100644 (file)
@@ -19,3 +19,24 @@ void f3 (vec_float4 *in)
 {
   vec_uint4 out = spu_convtu (in[0], 128); /* { dg-error "expects an integer literal in the range" "0, 127"  }*/
 }
+
+/* Test that these intrinsics accept non-literal arguments */
+void f4 (vec_uint4 *in, int n)
+{
+  vec_float4 out = spu_convtf (in[0], n); 
+}
+
+void f5 (vec_int4 *in, int n)
+{
+  vec_float4 out = spu_convtf (in[0], n);
+}
+
+void f6 (vec_float4 *in, int n)
+{
+  vec_int4 out = spu_convts (in[0], n);
+}
+
+void f7 (vec_float4 *in, int n)
+{
+  vec_uint4 out = spu_convtu (in[0], n);
+}