diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 0f7afbc7fbf..76a8f01f6b5 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -279,14 +279,14 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, DAG.getConstant(32, MVT::i32), Amt); - SDOperand Tmp2 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Amt); - SDOperand Tmp3 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Tmp1); + SDOperand Tmp2 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Amt); + SDOperand Tmp3 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Tmp1); SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, DAG.getConstant(-32U, MVT::i32)); - SDOperand Tmp6 = DAG.getNode(ISD::SHL, MVT::i32, Lo, Tmp5); + SDOperand Tmp6 = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Tmp5); SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); - SDOperand OutLo = DAG.getNode(ISD::SHL, MVT::i32, Lo, Amt); + SDOperand OutLo = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Amt); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } case ISD::SRL: { @@ -305,14 +305,14 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, DAG.getConstant(32, MVT::i32), Amt); - SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); - SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); + SDOperand Tmp2 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Amt); + SDOperand Tmp3 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Tmp1); SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, DAG.getConstant(-32U, MVT::i32)); - SDOperand Tmp6 = DAG.getNode(ISD::SRL, MVT::i32, Hi, Tmp5); + SDOperand Tmp6 = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Tmp5); SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6); - SDOperand OutHi = DAG.getNode(ISD::SRL, MVT::i32, Hi, Amt); + SDOperand OutHi = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Amt); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } case ISD::SRA: { @@ -330,13 +330,13 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, DAG.getConstant(32, MVT::i32), Amt); - SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt); - SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1); + SDOperand Tmp2 = DAG.getNode(PPCISD::SRL, MVT::i32, Lo, Amt); + SDOperand Tmp3 = DAG.getNode(PPCISD::SHL, MVT::i32, Hi, Tmp1); SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3); SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt, DAG.getConstant(-32U, MVT::i32)); - SDOperand Tmp6 = DAG.getNode(ISD::SRA, MVT::i32, Hi, Tmp5); - SDOperand OutHi = DAG.getNode(ISD::SRA, MVT::i32, Hi, Amt); + SDOperand Tmp6 = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Tmp5); + SDOperand OutHi = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Amt); SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32), Tmp4, Tmp6, ISD::SETLE); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index d68ac14a850..392e735aa52 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -49,6 +49,12 @@ namespace llvm { /// GlobalBaseReg - On Darwin, this node represents the result of the mflr /// at function entry, used for PIC code. GlobalBaseReg, + + + /// These nodes represent the 32-bit PPC shifts that operate on 6-bit + /// shift amounts. These nodes are generated by the multi-precision shift + /// code. + SRL, SRA, SHL, }; } diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 504c3cc82e5..9f5d0ad4e63 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -30,6 +30,15 @@ def PPCfsel : SDNode<"PPCISD::FSEL", def PPChi : SDNode<"PPCISD::Hi", SDTIntBinOp, []>; def PPClo : SDNode<"PPCISD::Lo", SDTIntBinOp, []>; +// These nodes represent the 32-bit PPC shifts that operate on 6-bit shift +// amounts. These nodes are generated by the multi-precision shift code. +def SDT_PPCShiftOp : SDTypeProfile<1, 2, [ // PPCshl, PPCsra, PPCsrl + SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32> +]>; +def PPCsrl : SDNode<"PPCISD::SRL" , SDT_PPCShiftOp>; +def PPCsra : SDNode<"PPCISD::SRA" , SDT_PPCShiftOp>; +def PPCshl : SDNode<"PPCISD::SHL" , SDT_PPCShiftOp>; + // These are target-independent nodes, but have target-specific formats. def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>; @@ -430,19 +439,19 @@ def SLD : XForm_6<31, 27, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), [(set G8RC:$rA, (shl G8RC:$rS, G8RC:$rB))]>, isPPC64; def SLW : XForm_6<31, 24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "slw $rA, $rS, $rB", IntGeneral, - [(set GPRC:$rA, (shl GPRC:$rS, GPRC:$rB))]>; + [(set GPRC:$rA, (PPCshl GPRC:$rS, GPRC:$rB))]>; def SRD : XForm_6<31, 539, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), "srd $rA, $rS, $rB", IntRotateD, [(set G8RC:$rA, (srl G8RC:$rS, G8RC:$rB))]>, isPPC64; def SRW : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "srw $rA, $rS, $rB", IntGeneral, - [(set GPRC:$rA, (srl GPRC:$rS, GPRC:$rB))]>; + [(set GPRC:$rA, (PPCsrl GPRC:$rS, GPRC:$rB))]>; def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), "srad $rA, $rS, $rB", IntRotateD, [(set G8RC:$rA, (sra G8RC:$rS, G8RC:$rB))]>, isPPC64; def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), "sraw $rA, $rS, $rB", IntShift, - [(set GPRC:$rA, (sra GPRC:$rS, GPRC:$rB))]>; + [(set GPRC:$rA, (PPCsra GPRC:$rS, GPRC:$rB))]>; let isStore = 1 in { def STBX : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stbx $rS, $rA, $rB", LdStGeneral>; @@ -891,6 +900,16 @@ def : Pat<(PPClo tglobaladdr:$in, (i32 0)), (LI tglobaladdr:$in)>; def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), (ADDIS GPRC:$in, tglobaladdr:$g)>; +// Standard shifts. These are represented separately from the real shifts above +// so that we can distinguish between shifts that allow 5-bit and 6-bit shift +// amounts. +def : Pat<(sra GPRC:$rS, GPRC:$rB), + (SRAW GPRC:$rS, GPRC:$rB)>; +def : Pat<(srl GPRC:$rS, GPRC:$rB), + (SRW GPRC:$rS, GPRC:$rB)>; +def : Pat<(shl GPRC:$rS, GPRC:$rB), + (SLW GPRC:$rS, GPRC:$rB)>; + // Same as above, but using a temporary. FIXME: implement temporaries :) /* def : Pattern<(xor GPRC:$in, imm:$imm),