diff options
author | Jim Grosbach <grosbach@apple.com> | 2009-10-31 21:00:56 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2009-10-31 21:00:56 +0000 |
commit | 5480bad7b9ba0a765d937631674f2b65f8eeea1e (patch) | |
tree | 0a68890b1367608319d6b4a8b995e88e3f73d119 /lib | |
parent | 70337f0e084c54af2348a7a8aee72a2823c0e5b8 (diff) | |
download | external_llvm-5480bad7b9ba0a765d937631674f2b65f8eeea1e.zip external_llvm-5480bad7b9ba0a765d937631674f2b65f8eeea1e.tar.gz external_llvm-5480bad7b9ba0a765d937631674f2b65f8eeea1e.tar.bz2 |
Expand 64-bit arithmetic shift right inline
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85685 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 6263fbb..25fc86f 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -331,7 +331,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::MULHS, MVT::i32, Expand); } setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom); - setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); + setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom); setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRL, MVT::i64, Custom); setOperationAction(ISD::SRA, MVT::i64, Custom); @@ -2096,6 +2096,40 @@ static SDValue getOnesVector(EVT VT, SelectionDAG &DAG, DebugLoc dl) { return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Vec); } +/// LowerShiftRightParts - Lower SRA_PARTS, which returns two +/// i32 values and take a 2 x i32 value to shift plus a shift amount. +static SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG, + const ARMSubtarget *ST) { + assert(Op.getNumOperands() == 3 && "Not a double-shift!"); + EVT VT = Op.getValueType(); + unsigned VTBits = VT.getSizeInBits(); + DebugLoc dl = Op.getDebugLoc(); + SDValue ShOpLo = Op.getOperand(0); + SDValue ShOpHi = Op.getOperand(1); + SDValue ShAmt = Op.getOperand(2); + SDValue ARMCC; + + assert(Op.getOpcode() == ISD::SRA_PARTS); + SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, + DAG.getConstant(VTBits, MVT::i32), ShAmt); + SDValue Tmp1 = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, ShAmt); + SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt, + DAG.getConstant(VTBits, MVT::i32)); + SDValue Tmp2 = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, RevShAmt); + SDValue FalseVal = DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2); + SDValue TrueVal = DAG.getNode(ISD::SRA, dl, VT, ShOpHi, ExtraShAmt); + + SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); + SDValue Cmp = getARMCmp(ExtraShAmt, DAG.getConstant(0, MVT::i32), ISD::SETGE, + ARMCC, DAG, ST->isThumb1Only(), dl); + SDValue Hi = DAG.getNode(ISD::SRA, dl, VT, ShOpHi, ShAmt); + SDValue Lo = DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMCC, + CCR, Cmp); + + SDValue Ops[2] = { Lo, Hi }; + return DAG.getMergeValues(Ops, 2, dl); +} + /// LowerShiftLeftParts - Lower SHL_PARTS, which returns two /// i32 values and take a 2 x i32 value to shift plus a shift amount. static SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG, @@ -2823,6 +2857,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SRL: case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget); case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG, Subtarget); + case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG, Subtarget); case ISD::VSETCC: return LowerVSETCC(Op, DAG); case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG); case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); |