diff options
author | David Goodwin <david_goodwin@apple.com> | 2009-07-30 18:56:48 +0000 |
---|---|---|
committer | David Goodwin <david_goodwin@apple.com> | 2009-07-30 18:56:48 +0000 |
commit | d8c95b5ac2ae0619c22434dbdd993196ea82489b (patch) | |
tree | a528043507699838e145e501dcab5a5b65d19c26 | |
parent | 78ab9e2c4907428f5f0d8aa594258ac188dd2125 (diff) |
Cleanup and include code selection for some frame index cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77622 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMISelDAGToDAG.cpp | 69 | ||||
-rw-r--r-- | test/CodeGen/Thumb2/pic-load.ll | 2 |
2 files changed, 50 insertions, 21 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index f5f5adedf6..cadd7c690b 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -598,7 +598,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, // Match simple R + imm12 operands. // Match frame index... - if (N.getOpcode() != ISD::ADD) { + if ((N.getOpcode() != ISD::ADD) && (N.getOpcode() != ISD::SUB)) { if (N.getOpcode() == ISD::FrameIndex) { int FI = cast<FrameIndexSDNode>(N)->getIndex(); Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); @@ -610,8 +610,15 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { int RHSC = (int)RHS->getZExtValue(); - if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits. + if (N.getOpcode() == ISD::SUB) + RHSC = -RHSC; + + if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned) Base = N.getOperand(0); + if (Base.getOpcode() == ISD::FrameIndex) { + int FI = cast<FrameIndexSDNode>(Base)->getIndex(); + Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); + } OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); return true; } @@ -622,20 +629,31 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N, SDValue &Base, SDValue &OffImm) { - if ((N.getOpcode() == ISD::ADD) || (N.getOpcode() == ISD::SUB)) { - if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { - int RHSC = (int)RHS->getSExtValue(); - if (N.getOpcode() == ISD::SUB) - RHSC = -RHSC; + // Match simple R - imm8 operands. - if ((RHSC >= -255) && (RHSC <= 0)) { // 8 bits (always negative) - Base = N.getOperand(0); - OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); - return true; + // Match frame index... + if ((N.getOpcode() != ISD::ADD) && (N.getOpcode() != ISD::SUB)) { + if (N.getOpcode() == ISD::FrameIndex) { + int FI = cast<FrameIndexSDNode>(N)->getIndex(); + Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); + OffImm = CurDAG->getTargetConstant(0, MVT::i32); + return true; + } + return false; + } + + if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { + int RHSC = (int)RHS->getSExtValue(); + if (N.getOpcode() == ISD::SUB) + RHSC = -RHSC; + + if ((RHSC >= -255) && (RHSC <= 0)) { // 8 bits (always negative) + Base = N.getOperand(0); + if (Base.getOpcode() == ISD::FrameIndex) { + int FI = cast<FrameIndexSDNode>(Base)->getIndex(); + Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); } - } else if (N.getOpcode() == ISD::SUB) { - Base = N; - OffImm = CurDAG->getTargetConstant(0, MVT::i32); + OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); return true; } } @@ -706,9 +724,24 @@ bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N, return true; } + // Leave (R +/- imm) for other address modes... unless they can't + // handle them + if (dyn_cast<ConstantSDNode>(N.getOperand(1)) != NULL) { + SDValue OffImm; + if (SelectT2AddrModeImm12(Op, N, Base, OffImm) || + SelectT2AddrModeImm8 (Op, N, Base, OffImm)) + return false; + } + // Thumb2 does not support (R - R) or (R - (R << [1,2,3])). - if (N.getOpcode() != ISD::ADD) - return false; + if (N.getOpcode() == ISD::SUB) { + Base = N; + OffReg = CurDAG->getRegister(0, MVT::i32); + ShImm = CurDAG->getTargetConstant(0, MVT::i32); + return true; + } + + assert(N.getOpcode() == ISD::ADD); // Look for (R + R) or (R + (R << [1,2,3])). unsigned ShAmt = 0; @@ -736,10 +769,6 @@ bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N, } else { ShOpcVal = ARM_AM::no_shift; } - } else if (SelectT2AddrModeImm12(Op, N, Base, ShImm) || - SelectT2AddrModeImm8 (Op, N, Base, ShImm)) { - // Don't match if it's possible to match to one of the r +/- imm cases. - return false; } ShImm = CurDAG->getTargetConstant(ShAmt, MVT::i32); diff --git a/test/CodeGen/Thumb2/pic-load.ll b/test/CodeGen/Thumb2/pic-load.ll index 71fec5d96d..553377b48b 100644 --- a/test/CodeGen/Thumb2/pic-load.ll +++ b/test/CodeGen/Thumb2/pic-load.ll @@ -8,7 +8,7 @@ define hidden arm_apcscc i32 @atexit(void ()* %func) nounwind { entry: ; CHECK: atexit: -; CHECK: add.w r1, r1, pc +; CHECK: add.w r0, r0, pc %r = alloca %struct.one_atexit_routine, align 4 ; <%struct.one_atexit_routine*> [#uses=3] %0 = getelementptr %struct.one_atexit_routine* %r, i32 0, i32 0, i32 0 ; <void ()**> [#uses=1] store void ()* %func, void ()** %0, align 4 |