Changes in directory llvm/lib/Target/PowerPC:
PPCISelDAGToDAG.cpp updated: 1.177 -> 1.178 PPCISelLowering.cpp updated: 1.113 -> 1.114 PPCISelLowering.h updated: 1.34 -> 1.35 PPCInstrAltivec.td updated: 1.9 -> 1.10 PPCInstrInfo.td updated: 1.211 -> 1.212 --- Log message: Codegen vector predicate compares. --- Diffs of the changes: (+139 -15) PPCISelDAGToDAG.cpp | 14 +++++++++ PPCISelLowering.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ PPCISelLowering.h | 11 +++++++ PPCInstrAltivec.td | 39 ++++++++++++++++--------- PPCInstrInfo.td | 10 +++++- 5 files changed, 139 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.177 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.178 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.177 Sat Mar 25 00:47:10 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Sun Mar 26 04:06:40 2006 @@ -1060,6 +1060,20 @@ getI32Imm(0)), 0); return; } + + case PPCISD::MFCR: { + SDOperand InFlag; + Select(InFlag, N->getOperand(1)); + // Use MFOCRF if supported. + if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor()) + Result = SDOperand(CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, + N->getOperand(0), InFlag), 0); + else + Result = SDOperand(CurDAG->getTargetNode(PPC::MFCR, MVT::i32, InFlag), 0); + CodeGenMap[Op] = Result; + return; + } + case ISD::SDIV: { // FIXME: since this depends on the setting of the carry flag from the srawi // we should really be making notes about that for the scheduler. Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.113 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.114 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.113 Sun Mar 26 03:52:32 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Sun Mar 26 04:06:40 2006 @@ -22,6 +22,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Constants.h" #include "llvm/Function.h" +#include "llvm/Intrinsics.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetOptions.h" using namespace llvm; @@ -136,6 +137,9 @@ setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); + // We want to custom lower some of our intrinsics. + setOperationAction(ISD::INTRINSIC , MVT::Other, Custom); + if (TM.getSubtarget<PPCSubtarget>().is64Bit()) { // They also have instructions for converting between i64 and fp. setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); @@ -230,6 +234,8 @@ case PPCISD::STD_32: return "PPCISD::STD_32"; case PPCISD::CALL: return "PPCISD::CALL"; case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG"; + case PPCISD::MFCR: return "PPCISD::MFCR"; + case PPCISD::VCMPo: return "PPCISD::VCMPo"; } } @@ -746,6 +752,80 @@ SDOperand VPermMask =DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, ResultMask); return DAG.getNode(PPCISD::VPERM, V1.getValueType(), V1, V2, VPermMask); } + case ISD::INTRINSIC: { + bool HasChain = Op.getOperand(0).getValueType() == MVT::Other; + unsigned IntNo=cast<ConstantSDNode>(Op.getOperand(HasChain))->getValue(); + + // If this is a lowered altivec predicate compare, CompareOpc is set to the + // opcode number of the comparison. + int CompareOpc = -1; + switch (IntNo) { + default: return SDOperand(); // Don't custom lower most intrinsics. + case Intrinsic::ppc_altivec_vcmpbfp_p: CompareOpc = 966; break; + case Intrinsic::ppc_altivec_vcmpeqfp_p: CompareOpc = 198; break; + case Intrinsic::ppc_altivec_vcmpequb_p: CompareOpc = 6; break; + case Intrinsic::ppc_altivec_vcmpequh_p: CompareOpc = 70; break; + case Intrinsic::ppc_altivec_vcmpequw_p: CompareOpc = 134; break; + case Intrinsic::ppc_altivec_vcmpgefp_p: CompareOpc = 454; break; + case Intrinsic::ppc_altivec_vcmpgtfp_p: CompareOpc = 710; break; + case Intrinsic::ppc_altivec_vcmpgtsb_p: CompareOpc = 774; break; + case Intrinsic::ppc_altivec_vcmpgtsh_p: CompareOpc = 838; break; + case Intrinsic::ppc_altivec_vcmpgtsw_p: CompareOpc = 902; break; + case Intrinsic::ppc_altivec_vcmpgtub_p: CompareOpc = 518; break; + case Intrinsic::ppc_altivec_vcmpgtuh_p: CompareOpc = 582; break; + case Intrinsic::ppc_altivec_vcmpgtuw_p: CompareOpc = 646; break; + } + + assert(CompareOpc>0 && "We only lower altivec predicate compares so far!"); + + // Create the PPCISD altivec 'dot' comparison node. + std::vector<SDOperand> Ops; + std::vector<MVT::ValueType> VTs; + Ops.push_back(Op.getOperand(2)); // LHS + Ops.push_back(Op.getOperand(3)); // RHS + Ops.push_back(DAG.getConstant(CompareOpc, MVT::i32)); + VTs.push_back(Op.getOperand(2).getValueType()); + VTs.push_back(MVT::Flag); + SDOperand CompNode = DAG.getNode(PPCISD::VCMPo, VTs, Ops); + + // Now that we have the comparison, emit a copy from the CR to a GPR. + // This is flagged to the above dot comparison. + SDOperand Flags = DAG.getNode(PPCISD::MFCR, MVT::i32, + DAG.getRegister(PPC::CR6, MVT::i32), + CompNode.getValue(1)); + + // Unpack the result based on how the target uses it. + unsigned BitNo; // Bit # of CR6. + bool InvertBit; // Invert result? + switch (cast<ConstantSDNode>(Op.getOperand(1))->getValue()) { + default: // Can't happen, don't crash on invalid number though. + case 0: // Return the value of the EQ bit of CR6. + BitNo = 0; InvertBit = false; + break; + case 1: // Return the inverted value of the EQ bit of CR6. + BitNo = 0; InvertBit = true; + break; + case 2: // Return the value of the LT bit of CR6. + BitNo = 2; InvertBit = false; + break; + case 3: // Return the inverted value of the LT bit of CR6. + BitNo = 2; InvertBit = true; + break; + } + + // Shift the bit into the low position. + Flags = DAG.getNode(ISD::SRL, MVT::i32, Flags, + DAG.getConstant(8-(3-BitNo), MVT::i32)); + // Isolate the bit. + Flags = DAG.getNode(ISD::AND, MVT::i32, Flags, + DAG.getConstant(1, MVT::i32)); + + // If we are supposed to, toggle the bit. + if (InvertBit) + Flags = DAG.getNode(ISD::XOR, MVT::i32, Flags, + DAG.getConstant(1, MVT::i32)); + return Flags; + } } return SDOperand(); } Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.34 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.35 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.34 Sun Mar 26 03:52:32 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Sun Mar 26 04:06:40 2006 @@ -88,6 +88,17 @@ /// Return with a flag operand, matched by 'blr' RET_FLAG, + + /// R32 = MFCR(CRREG, INFLAG) - Represents the MFCR/MFOCRF instructions. + /// This copies the bits corresponding to the specified CRREG into the + /// resultant GPR. Bits corresponding to other CR regs are undefined. + MFCR, + + /// RESVEC, OUTFLAG = VCMPo(LHS, RHS, OPC) - Represents one of the + /// altivec VCMP*o instructions. For lack of better number, we use the + /// opcode number encoding for the OPC field to identify the compare. For + /// example, 838 is VCMPGTSH. + VCMPo }; } Index: llvm/lib/Target/PowerPC/PPCInstrAltivec.td diff -u llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.9 llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.10 --- llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.9 Sun Mar 26 03:52:32 2006 +++ llvm/lib/Target/PowerPC/PPCInstrAltivec.td Sun Mar 26 04:06:40 2006 @@ -306,28 +306,32 @@ (int_ppc_altivec_vcmpbfp VRRC:$vA, VRRC:$vB))]>; def VCMPBFPo : VXRForm_1<966, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpbfp. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v4f32 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 966)))]>, isVDOT; def VCMPEQFP : VXRForm_1<198, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpeqfp $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpeqfp VRRC:$vA, VRRC:$vB))]>; def VCMPEQFPo : VXRForm_1<198, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpeqfp. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v4f32 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 198)))]>, isVDOT; def VCMPGEFP : VXRForm_1<454, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgefp $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpgefp VRRC:$vA, VRRC:$vB))]>; def VCMPGEFPo : VXRForm_1<454, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgefp. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v4f32 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 454)))]>, isVDOT; def VCMPGTFP : VXRForm_1<710, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtfp $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpgtfp VRRC:$vA, VRRC:$vB))]>; def VCMPGTFPo : VXRForm_1<710, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtfp. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v4f32 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 710)))]>, isVDOT; // i8 element comparisons. def VCMPEQUB : VXRForm_1<6, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), @@ -336,21 +340,24 @@ (int_ppc_altivec_vcmpequb VRRC:$vA, VRRC:$vB))]>; def VCMPEQUBo : VXRForm_1<6, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpequb. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v16i8 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 6)))]>, isVDOT; def VCMPGTSB : VXRForm_1<774, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtsb $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpgtsb VRRC:$vA, VRRC:$vB))]>; def VCMPGTSBo : VXRForm_1<774, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtsb. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v16i8 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 774)))]>, isVDOT; def VCMPGTUB : VXRForm_1<518, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtub $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpgtub VRRC:$vA, VRRC:$vB))]>; def VCMPGTUBo : VXRForm_1<518, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtub. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v16i8 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 518)))]>, isVDOT; // i16 element comparisons. def VCMPEQUH : VXRForm_1<70, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), @@ -359,21 +366,24 @@ (int_ppc_altivec_vcmpequh VRRC:$vA, VRRC:$vB))]>; def VCMPEQUHo : VXRForm_1<70, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpequh. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v8i16 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 70)))]>, isVDOT; def VCMPGTSH : VXRForm_1<838, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtsh $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpgtsh VRRC:$vA, VRRC:$vB))]>; def VCMPGTSHo : VXRForm_1<838, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtsh. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v8i16 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 838)))]>, isVDOT; def VCMPGTUH : VXRForm_1<582, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtuh $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpgtuh VRRC:$vA, VRRC:$vB))]>; def VCMPGTUHo : VXRForm_1<582, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtuh. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v8i16 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 582)))]>, isVDOT; // i32 element comparisons. def VCMPEQUW : VXRForm_1<134, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), @@ -382,21 +392,24 @@ (int_ppc_altivec_vcmpequw VRRC:$vA, VRRC:$vB))]>; def VCMPEQUWo : VXRForm_1<134, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpequw. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v4i32 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 134)))]>, isVDOT; def VCMPGTSW : VXRForm_1<902, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtsw $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpgtsw VRRC:$vA, VRRC:$vB))]>; def VCMPGTSWo : VXRForm_1<902, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtsw. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v4i32 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 902)))]>, isVDOT; def VCMPGTUW : VXRForm_1<646, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtuw $vD, $vA, $vB", VecFPCompare, [(set VRRC:$vD, (int_ppc_altivec_vcmpgtuw VRRC:$vA, VRRC:$vB))]>; def VCMPGTUWo : VXRForm_1<646, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB), "vcmpgtuw. $vD, $vA, $vB", VecFPCompare, - []>, isVDOT; + [(set VRRC:$vD, (v4i32 + (PPCvcmp_o VRRC:$vA, VRRC:$vB, 646)))]>, isVDOT; def V_SET0 : VXForm_setzero<1220, (ops VRRC:$vD), "vxor $vD, $vD, $vD", VecFP, Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.211 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.212 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.211 Sat Mar 25 01:51:43 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Sun Mar 26 04:06:40 2006 @@ -30,6 +30,10 @@ SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2> ]>; +def SDT_PPCvcmp_o : SDTypeProfile<1, 3, [ + SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32> +]>; + //===----------------------------------------------------------------------===// // PowerPC specific DAG Nodes. // @@ -68,6 +72,8 @@ def retflag : SDNode<"PPCISD::RET_FLAG", SDT_PPCRetFlag, [SDNPHasChain, SDNPOptInFlag]>; +def PPCvcmp_o : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp_o, [SDNPOutFlag]>; + //===----------------------------------------------------------------------===// // PowerPC specific transformation functions and pattern fragments. // @@ -701,11 +707,11 @@ "mfspr $rT, 256", IntGeneral>, PPC970_DGroup_First, PPC970_Unit_FXU; -def MFCR : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>, - PPC970_MicroCode, PPC970_Unit_CRU; def MTCRF : XFXForm_5<31, 144, (ops crbitm:$FXM, GPRC:$rS), "mtcrf $FXM, $rS", BrMCRX>, PPC970_MicroCode, PPC970_Unit_CRU; +def MFCR : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>, + PPC970_MicroCode, PPC970_Unit_CRU; def MFOCRF: XFXForm_5a<31, 19, (ops GPRC:$rT, crbitm:$FXM), "mfcr $rT, $FXM", SprMFCR>, PPC970_DGroup_First, PPC970_Unit_CRU; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits