OSDN Git Service

compiler: Prohibit comparisons of funcs, maps, and slices to non-nil.
[pf3gnuchains/gcc-fork.git] / gcc / config / spu / spu-builtins.md
index 325a80d..ac3a333 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" "")