aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Goodwin <david_goodwin@apple.com>2009-07-30 18:56:48 +0000
committerDavid Goodwin <david_goodwin@apple.com>2009-07-30 18:56:48 +0000
commitd8c95b5ac2ae0619c22434dbdd993196ea82489b (patch)
treea528043507699838e145e501dcab5a5b65d19c26
parent78ab9e2c4907428f5f0d8aa594258ac188dd2125 (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.cpp69
-rw-r--r--test/CodeGen/Thumb2/pic-load.ll2
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