Codegen things like:
 <int -1, int -1, int -1, int -1>
and
 <int 65537, int 65537, int 65537, int 65537>

Using things like:
  vspltisb v0, -1
and:
  vspltish v0, 1

instead of using constant pool loads.

This implements CodeGen/PowerPC/vec_splat.ll:splat_imm_i{32|16}.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27106 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index 5078d39..4ac06a6 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -140,6 +140,37 @@
 }]>;
 
 
+// VSPLTISB_get_imm xform function: convert build_vector to VSPLTISB imm.
+def VSPLTISB_get_imm : SDNodeXForm<build_vector, [{
+  char Val;
+  PPC::isVecSplatImm(N, 1, &Val);
+  return getI32Imm(Val);
+}]>;
+def vecspltisb : PatLeaf<(build_vector), [{
+  return PPC::isVecSplatImm(N, 1);
+}], VSPLTISB_get_imm>;
+
+// VSPLTISH_get_imm xform function: convert build_vector to VSPLTISH imm.
+def VSPLTISH_get_imm : SDNodeXForm<build_vector, [{
+  char Val;
+  PPC::isVecSplatImm(N, 2, &Val);
+  return getI32Imm(Val);
+}]>;
+def vecspltish : PatLeaf<(build_vector), [{
+  return PPC::isVecSplatImm(N, 2);
+}], VSPLTISH_get_imm>;
+
+// VSPLTISW_get_imm xform function: convert build_vector to VSPLTISW imm.
+def VSPLTISW_get_imm : SDNodeXForm<build_vector, [{
+  char Val;
+  PPC::isVecSplatImm(N, 4, &Val);
+  return getI32Imm(Val);
+}]>;
+def vecspltisw : PatLeaf<(build_vector), [{
+  return PPC::isVecSplatImm(N, 4);
+}], VSPLTISW_get_imm>;
+
+
 //===----------------------------------------------------------------------===//
 // PowerPC Flag Definitions.
 
@@ -155,6 +186,9 @@
 //===----------------------------------------------------------------------===//
 // PowerPC Operand Definitions.
 
+def s5imm   : Operand<i32> {
+  let PrintMethod = "printS5ImmOperand";
+}
 def u5imm   : Operand<i32> {
   let PrintMethod = "printU5ImmOperand";
 }
@@ -1055,12 +1089,21 @@
 def VSPLTH : VXForm_1<588, (ops VRRC:$vD, u5imm:$UIMM, VRRC:$vB),
                       "vsplth $vD, $vB, $UIMM", VecPerm,
                       []>;
-                      
 def VSPLTW : VXForm_1<652, (ops VRRC:$vD, u5imm:$UIMM, VRRC:$vB),
                       "vspltw $vD, $vB, $UIMM", VecPerm,
                       [(set VRRC:$vD, (vector_shuffle (v4f32 VRRC:$vB), (undef),
                                       VSPLT_shuffle_mask:$UIMM))]>;
-                      // FIXME: ALSO ADD SUPPORT FOR v4i32!
+
+def VSPLTISB : VXForm_1<780, (ops VRRC:$vD, s5imm:$SIMM),
+                      "vspltisb $vD, $SIMM", VecPerm,
+                      [(set VRRC:$vD, (v4f32 vecspltisb:$SIMM))]>;
+def VSPLTISH : VXForm_1<844, (ops VRRC:$vD, s5imm:$SIMM),
+                      "vspltish $vD, $SIMM", VecPerm,
+                      [(set VRRC:$vD, (v4f32 vecspltish:$SIMM))]>;
+def VSPLTISW : VXForm_1<908, (ops VRRC:$vD, s5imm:$SIMM),
+                      "vspltisw $vD, $SIMM", VecPerm,
+                      [(set VRRC:$vD, (v4f32 vecspltisw:$SIMM))]>;
+
                       
 // VX-Form Pseudo Instructions
 
@@ -1216,6 +1259,11 @@
 def : Pat<(v4i32 (undef)), (v4i32 (IMPLICIT_DEF_VRRC))>;
 def : Pat<(v4i32 vecimm0), (v4i32 (V_SET0))>;
 
+def : Pat<(v4i32 vecspltisb:$invec), (v4i32 (VSPLTISB vecspltisb:$invec))>;
+def : Pat<(v4i32 vecspltish:$invec), (v4i32 (VSPLTISH vecspltish:$invec))>;
+def : Pat<(v4i32 vecspltisw:$invec), (v4i32 (VSPLTISW vecspltisw:$invec))>;
+
+
 // bit_convert
 def : Pat<(v4i32 (bitconvert (v4f32 VRRC:$src))), (v4i32 VRRC:$src)>;
 def : Pat<(v4f32 (bitconvert (v4i32 VRRC:$src))), (v4f32 VRRC:$src)>;