/// VPKUHUM_shuffle_mask/VPKUWUM_shuffle_mask - Return true if this is a valid
/// shuffle mask for the VPKUHUM or VPKUWUM instructions.
def VPKUHUM_shuffle_mask : PatLeaf<(build_vector), [{
- return PPC::isVPKUHUMShuffleMask(N);
+ return PPC::isVPKUHUMShuffleMask(N, false);
}]>;
def VPKUWUM_shuffle_mask : PatLeaf<(build_vector), [{
- return PPC::isVPKUWUMShuffleMask(N);
+ return PPC::isVPKUWUMShuffleMask(N, false);
}]>;
+def VPKUHUM_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVPKUHUMShuffleMask(N, true);
+}]>;
+def VPKUWUM_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVPKUWUMShuffleMask(N, true);
+}]>;
+
+
+def VMRGLB_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGLShuffleMask(N, 1, false);
+}]>;
+def VMRGLH_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGLShuffleMask(N, 2, false);
+}]>;
+def VMRGLW_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGLShuffleMask(N, 4, false);
+}]>;
+def VMRGHB_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGHShuffleMask(N, 1, false);
+}]>;
+def VMRGHH_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGHShuffleMask(N, 2, false);
+}]>;
+def VMRGHW_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGHShuffleMask(N, 4, false);
+}]>;
+
+def VMRGLB_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGLShuffleMask(N, 1, true);
+}]>;
+def VMRGLH_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGLShuffleMask(N, 2, true);
+}]>;
+def VMRGLW_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGLShuffleMask(N, 4, true);
+}]>;
+def VMRGHB_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGHShuffleMask(N, 1, true);
+}]>;
+def VMRGHH_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGHShuffleMask(N, 2, true);
+}]>;
+def VMRGHW_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVMRGHShuffleMask(N, 4, true);
+}]>;
+
+
+def VSLDOI_get_imm : SDNodeXForm<build_vector, [{
+ return getI32Imm(PPC::isVSLDOIShuffleMask(N, false));
+}]>;
+def VSLDOI_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVSLDOIShuffleMask(N, false) != -1;
+}], VSLDOI_get_imm>;
+
+/// VSLDOI_unary* - These are used to match vsldoi(X,X), which is turned into
+/// vector_shuffle(X,undef,mask) by the dag combiner.
+def VSLDOI_unary_get_imm : SDNodeXForm<build_vector, [{
+ return getI32Imm(PPC::isVSLDOIShuffleMask(N, true));
+}]>;
+def VSLDOI_unary_shuffle_mask : PatLeaf<(build_vector), [{
+ return PPC::isVSLDOIShuffleMask(N, true) != -1;
+}], VSLDOI_unary_get_imm>;
+
+
// VSPLT*_get_imm xform function: convert vector_shuffle mask to VSPLT* imm.
def VSPLTB_get_imm : SDNodeXForm<build_vector, [{
return getI32Imm(PPC::getVSPLTImmediate(N, 1));
// 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);
+ return PPC::get_VSPLTI_elt(N, 1, *CurDAG);
}]>;
def vecspltisb : PatLeaf<(build_vector), [{
- return PPC::isVecSplatImm(N, 1);
+ return PPC::get_VSPLTI_elt(N, 1, *CurDAG).Val != 0;
}], 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);
+ return PPC::get_VSPLTI_elt(N, 2, *CurDAG);
}]>;
def vecspltish : PatLeaf<(build_vector), [{
- return PPC::isVecSplatImm(N, 2);
+ return PPC::get_VSPLTI_elt(N, 2, *CurDAG).Val != 0;
}], 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);
+ return PPC::get_VSPLTI_elt(N, 4, *CurDAG);
}]>;
def vecspltisw : PatLeaf<(build_vector), [{
- return PPC::isVecSplatImm(N, 4);
+ return PPC::get_VSPLTI_elt(N, 4, *CurDAG).Val != 0;
}], VSPLTISW_get_imm>;
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Instruction Definitions.
-def IMPLICIT_DEF_VRRC : Pseudo<(ops VRRC:$rD), "; $rD = IMPLICIT_DEF_VRRC",
- [(set VRRC:$rD, (v4f32 (undef)))]>;
+def IMPLICIT_DEF_VRRC : Pseudo<(ops VRRC:$rD), "; IMPLICIT_DEF_VRRC $rD",
+ [(set VRRC:$rD, (v4i32 (undef)))]>;
let noResults = 1 in {
def DSS : DSS_Form<822, (ops u5imm:$A, u5imm:$STRM,u5imm:$ZERO1,u5imm:$ZERO2),
def VPERM : VA1a_Int<43, "vperm", int_ppc_altivec_vperm>;
def VSEL : VA1a_Int<42, "vsel", int_ppc_altivec_vsel>;
+// Shuffles.
def VSLDOI : VAForm_2<44, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB, u5imm:$SH),
"vsldoi $vD, $vA, $vB, $SH", VecFP,
- [(set VRRC:$vD,
- (int_ppc_altivec_vsldoi VRRC:$vA, VRRC:$vB,
- imm:$SH))]>;
+ [(set VRRC:$vD,
+ (vector_shuffle (v16i8 VRRC:$vA), VRRC:$vB,
+ VSLDOI_shuffle_mask:$SH))]>;
// VX-Form instructions. AltiVec arithmetic ops.
def VADDFP : VXForm_1<10, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
def VMINUH : VX1_Int< 578, "vminuh", int_ppc_altivec_vminuh>;
def VMINUW : VX1_Int< 642, "vminuw", int_ppc_altivec_vminuw>;
-def VMRGHB : VX1_Int<12 , "vmrghb", int_ppc_altivec_vmrghb>;
-def VMRGHH : VX1_Int<76 , "vmrghh", int_ppc_altivec_vmrghh>;
-def VMRGHW : VX1_Int<140, "vmrghw", int_ppc_altivec_vmrghw>;
-def VMRGLB : VX1_Int<268, "vmrglb", int_ppc_altivec_vmrglb>;
-def VMRGLH : VX1_Int<332, "vmrglh", int_ppc_altivec_vmrglh>;
-def VMRGLW : VX1_Int<396, "vmrglw", int_ppc_altivec_vmrglw>;
+def VMRGHB : VXForm_1< 12, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+ "vmrghb $vD, $vA, $vB", VecFP,
+ [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+ VRRC:$vB, VMRGHB_shuffle_mask))]>;
+def VMRGHH : VXForm_1< 76, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+ "vmrghh $vD, $vA, $vB", VecFP,
+ [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+ VRRC:$vB, VMRGHH_shuffle_mask))]>;
+def VMRGHW : VXForm_1<140, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+ "vmrghw $vD, $vA, $vB", VecFP,
+ [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+ VRRC:$vB, VMRGHW_shuffle_mask))]>;
+def VMRGLB : VXForm_1<268, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+ "vmrglb $vD, $vA, $vB", VecFP,
+ [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+ VRRC:$vB, VMRGLB_shuffle_mask))]>;
+def VMRGLH : VXForm_1<332, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+ "vmrglh $vD, $vA, $vB", VecFP,
+ [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+ VRRC:$vB, VMRGLH_shuffle_mask))]>;
+def VMRGLW : VXForm_1<396, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+ "vmrglw $vD, $vA, $vB", VecFP,
+ [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+ VRRC:$vB, VMRGLW_shuffle_mask))]>;
def VMSUMMBM : VA1a_Int<37, "vmsummbm", int_ppc_altivec_vmsummbm>;
def VMSUMSHM : VA1a_Int<40, "vmsumshm", int_ppc_altivec_vmsumshm>;
def VSPLTISB : VXForm_3<780, (ops VRRC:$vD, s5imm:$SIMM),
"vspltisb $vD, $SIMM", VecPerm,
- [(set VRRC:$vD, (v4f32 vecspltisb:$SIMM))]>;
+ [(set VRRC:$vD, (v16i8 vecspltisb:$SIMM))]>;
def VSPLTISH : VXForm_3<844, (ops VRRC:$vD, s5imm:$SIMM),
"vspltish $vD, $SIMM", VecPerm,
- [(set VRRC:$vD, (v4f32 vecspltish:$SIMM))]>;
+ [(set VRRC:$vD, (v8i16 vecspltish:$SIMM))]>;
def VSPLTISW : VXForm_3<908, (ops VRRC:$vD, s5imm:$SIMM),
"vspltisw $vD, $SIMM", VecPerm,
- [(set VRRC:$vD, (v4f32 vecspltisw:$SIMM))]>;
+ [(set VRRC:$vD, (v4i32 vecspltisw:$SIMM))]>;
// Vector Pack.
def VPKPX : VX1_Int<782, "vpkpx", int_ppc_altivec_vpkpx>;
def V_SET0 : VXForm_setzero<1220, (ops VRRC:$vD),
"vxor $vD, $vD, $vD", VecFP,
- [(set VRRC:$vD, (v4f32 immAllZerosV))]>;
+ [(set VRRC:$vD, (v4i32 immAllZerosV))]>;
}
//===----------------------------------------------------------------------===//
def : Pat<(int_ppc_altivec_dststt GPRC:$rA, GPRC:$rB, imm:$STRM),
(DSTST 1, imm:$STRM, GPRC:$rA, GPRC:$rB)>;
-// Undef/Zero.
-def : Pat<(v16i8 (undef)), (v16i8 (IMPLICIT_DEF_VRRC))>;
-def : Pat<(v8i16 (undef)), (v8i16 (IMPLICIT_DEF_VRRC))>;
-def : Pat<(v4i32 (undef)), (v4i32 (IMPLICIT_DEF_VRRC))>;
-def : Pat<(v16i8 immAllZerosV), (v16i8 (V_SET0))>;
-def : Pat<(v8i16 immAllZerosV), (v8i16 (V_SET0))>;
-def : Pat<(v4i32 immAllZerosV), (v4i32 (V_SET0))>;
+// Undef.
+def : Pat<(v16i8 (undef)), (IMPLICIT_DEF_VRRC)>;
+def : Pat<(v8i16 (undef)), (IMPLICIT_DEF_VRRC)>;
+def : Pat<(v4f32 (undef)), (IMPLICIT_DEF_VRRC)>;
// Loads.
-def : Pat<(v16i8 (load xoaddr:$src)), (v16i8 (LVX xoaddr:$src))>;
-def : Pat<(v8i16 (load xoaddr:$src)), (v8i16 (LVX xoaddr:$src))>;
-def : Pat<(v4i32 (load xoaddr:$src)), (v4i32 (LVX xoaddr:$src))>;
-def : Pat<(v4f32 (load xoaddr:$src)), (v4f32 (LVX xoaddr:$src))>;
+def : Pat<(v4i32 (load xoaddr:$src)), (LVX xoaddr:$src)>;
// Stores.
-def : Pat<(store (v16i8 VRRC:$rS), xoaddr:$dst),
- (STVX (v16i8 VRRC:$rS), xoaddr:$dst)>;
-def : Pat<(store (v8i16 VRRC:$rS), xoaddr:$dst),
- (STVX (v8i16 VRRC:$rS), xoaddr:$dst)>;
def : Pat<(store (v4i32 VRRC:$rS), xoaddr:$dst),
(STVX (v4i32 VRRC:$rS), xoaddr:$dst)>;
-def : Pat<(store (v4f32 VRRC:$rS), xoaddr:$dst),
- (STVX (v4f32 VRRC:$rS), xoaddr:$dst)>;
// Bit conversions.
def : Pat<(v16i8 (bitconvert (v8i16 VRRC:$src))), (v16i8 VRRC:$src)>;
def : Pat<(v4f32 (bitconvert (v8i16 VRRC:$src))), (v4f32 VRRC:$src)>;
def : Pat<(v4f32 (bitconvert (v4i32 VRRC:$src))), (v4f32 VRRC:$src)>;
-// Immediate vector formation with vsplti*.
-def : Pat<(v16i8 vecspltisb:$invec), (v16i8 (VSPLTISB vecspltisb:$invec))>;
-def : Pat<(v16i8 vecspltish:$invec), (v16i8 (VSPLTISH vecspltish:$invec))>;
-def : Pat<(v16i8 vecspltisw:$invec), (v16i8 (VSPLTISW vecspltisw:$invec))>;
-
-def : Pat<(v8i16 vecspltisb:$invec), (v8i16 (VSPLTISB vecspltisb:$invec))>;
-def : Pat<(v8i16 vecspltish:$invec), (v8i16 (VSPLTISH vecspltish:$invec))>;
-def : Pat<(v8i16 vecspltisw:$invec), (v8i16 (VSPLTISW vecspltisw:$invec))>;
-
-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))>;
+// Shuffles.
+
+// Match vsldoi(x,x), vpkuwum(x,x), vpkuhum(x,x)
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VSLDOI_unary_shuffle_mask:$in),
+ (VSLDOI VRRC:$vA, VRRC:$vA, VSLDOI_unary_shuffle_mask:$in)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef,VPKUWUM_unary_shuffle_mask:$in),
+ (VPKUWUM VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef,VPKUHUM_unary_shuffle_mask:$in),
+ (VPKUHUM VRRC:$vA, VRRC:$vA)>;
+
+// Match vmrg*(x,x)
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGLB_unary_shuffle_mask:$in),
+ (VMRGLB VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGLH_unary_shuffle_mask:$in),
+ (VMRGLH VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGLW_unary_shuffle_mask:$in),
+ (VMRGLW VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHB_unary_shuffle_mask:$in),
+ (VMRGHB VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHH_unary_shuffle_mask:$in),
+ (VMRGHH VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHW_unary_shuffle_mask:$in),
+ (VMRGHW VRRC:$vA, VRRC:$vA)>;
// Logical Operations
-def : Pat<(v16i8 (vnot VRRC:$vA)), (v16i8 (VNOR VRRC:$vA, VRRC:$vA))>;
-def : Pat<(v8i16 (vnot VRRC:$vA)), (v8i16 (VNOR VRRC:$vA, VRRC:$vA))>;
-def : Pat<(v4i32 (vnot VRRC:$vA)), (v4i32 (VNOR VRRC:$vA, VRRC:$vA))>;
-
-def : Pat<(v16i8 (and VRRC:$A, VRRC:$B)), (v16i8 (VAND VRRC:$A, VRRC:$B))>;
-def : Pat<(v8i16 (and VRRC:$A, VRRC:$B)), (v8i16 (VAND VRRC:$A, VRRC:$B))>;
-def : Pat<(v16i8 (or VRRC:$A, VRRC:$B)), (v16i8 (VOR VRRC:$A, VRRC:$B))>;
-def : Pat<(v8i16 (or VRRC:$A, VRRC:$B)), (v8i16 (VOR VRRC:$A, VRRC:$B))>;
-def : Pat<(v16i8 (xor VRRC:$A, VRRC:$B)), (v16i8 (VXOR VRRC:$A, VRRC:$B))>;
-def : Pat<(v8i16 (xor VRRC:$A, VRRC:$B)), (v8i16 (VXOR VRRC:$A, VRRC:$B))>;
-def : Pat<(v16i8 (vnot (or VRRC:$A, VRRC:$B))),(v16i8 (VNOR VRRC:$A, VRRC:$B))>;
-def : Pat<(v8i16 (vnot (or VRRC:$A, VRRC:$B))),(v8i16 (VNOR VRRC:$A, VRRC:$B))>;
-def : Pat<(v16i8 (and VRRC:$A, (vnot VRRC:$B))),
- (v16i8 (VANDC VRRC:$A, VRRC:$B))>;
-def : Pat<(v8i16 (and VRRC:$A, (vnot VRRC:$B))),
- (v8i16 (VANDC VRRC:$A, VRRC:$B))>;
+def : Pat<(v4i32 (vnot VRRC:$vA)), (VNOR VRRC:$vA, VRRC:$vA)>;
+def : Pat<(v4i32 (vnot_conv VRRC:$vA)), (VNOR VRRC:$vA, VRRC:$vA)>;
+
+def : Pat<(v4i32 (vnot_conv (or VRRC:$A, VRRC:$B))),
+ (VNOR VRRC:$A, VRRC:$B)>;
+def : Pat<(v4i32 (and VRRC:$A, (vnot_conv VRRC:$B))),
+ (VANDC VRRC:$A, VRRC:$B)>;
def : Pat<(fmul VRRC:$vA, VRRC:$vB),
- (VMADDFP VRRC:$vA, VRRC:$vB, (V_SET0))>;
+ (VMADDFP VRRC:$vA, VRRC:$vB, (v4i32 (V_SET0)))>;
// Fused multiply add and multiply sub for packed float. These are represented
// separately from the real instructions above, for operations that must have
(VNMSUBFP VRRC:$A, VRRC:$B, VRRC:$C)>;
def : Pat<(PPCvperm (v16i8 VRRC:$vA), VRRC:$vB, VRRC:$vC),
- (v16i8 (VPERM VRRC:$vA, VRRC:$vB, VRRC:$vC))>;
+ (VPERM VRRC:$vA, VRRC:$vB, VRRC:$vC)>;