aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-09-29 19:03:54 +0000
committerJim Grosbach <grosbach@apple.com>2010-09-29 19:03:54 +0000
commit828916203a731c5031fbe440f1fc6cdf82b2e711 (patch)
tree83080218c2ce6bef5b2a9227ba4f68653431fa7f
parent8892b033e4c8d25403f10ad3977a8905ec4c5029 (diff)
downloadexternal_llvm-828916203a731c5031fbe440f1fc6cdf82b2e711.zip
external_llvm-828916203a731c5031fbe440f1fc6cdf82b2e711.tar.gz
external_llvm-828916203a731c5031fbe440f1fc6cdf82b2e711.tar.bz2
Add specializations of addrmode2 that allow differentiating those forms
which require the use of the shifter-operand. This will be used to split the ldr/str instructions such that those versions needing the shifter operand can get a different scheduling itenerary, as in some cases, the use of the shifter can cause different scheduling than the simpler forms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115066 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp42
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td18
2 files changed, 49 insertions, 11 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 7bc7b4a..d619564 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -46,6 +46,12 @@ DisableShifterOp("disable-shifter-op", cl::Hidden,
/// instructions for SelectionDAG operations.
///
namespace {
+
+enum AddrMode2Type {
+ AM2_BASE, // Simple AM2 (+-imm12)
+ AM2_SHOP // Shifter-op AM2
+};
+
class ARMDAGToDAGISel : public SelectionDAGISel {
ARMBaseTargetMachine &TM;
@@ -74,8 +80,25 @@ public:
bool SelectShifterOperandReg(SDValue N, SDValue &A,
SDValue &B, SDValue &C);
- bool SelectAddrMode2(SDValue N, SDValue &Base,
- SDValue &Offset, SDValue &Opc);
+ AddrMode2Type SelectAddrMode2Worker(SDValue N, SDValue &Base,
+ SDValue &Offset, SDValue &Opc);
+ bool SelectAddrMode2Base(SDValue N, SDValue &Base, SDValue &Offset,
+ SDValue &Opc) {
+ return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE;
+ }
+
+ bool SelectAddrMode2ShOp(SDValue N, SDValue &Base, SDValue &Offset,
+ SDValue &Opc) {
+ return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP;
+ }
+
+ bool SelectAddrMode2(SDValue N, SDValue &Base, SDValue &Offset,
+ SDValue &Opc) {
+ SelectAddrMode2Worker(N, Base, Offset, Opc);
+ // This always matches one way or another.
+ return true;
+ }
+
bool SelectAddrMode2Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc);
bool SelectAddrMode3(SDValue N, SDValue &Base,
@@ -245,9 +268,10 @@ bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue N,
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
- SDValue &Base, SDValue &Offset,
- SDValue &Opc) {
+AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N,
+ SDValue &Base,
+ SDValue &Offset,
+ SDValue &Opc) {
if (N.getOpcode() == ISD::MUL) {
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
// X * [3,5,9] -> X + X * [2,4,8] etc.
@@ -265,7 +289,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
ARM_AM::lsl),
MVT::i32);
- return true;
+ return AM2_SHOP;
}
}
}
@@ -285,7 +309,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
ARM_AM::no_shift),
MVT::i32);
- return true;
+ return AM2_BASE;
}
// Match simple R +/- imm12 operands.
@@ -309,7 +333,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
ARM_AM::no_shift),
MVT::i32);
- return true;
+ return AM2_BASE;
}
}
}
@@ -353,7 +377,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
MVT::i32);
- return true;
+ return AM2_SHOP;
}
bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N,
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 4980d8b..97ac233 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -369,8 +369,22 @@ def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
// Define ARM specific addressing modes.
-// addrmode2 := reg +/- reg shop imm
-// addrmode2 := reg +/- imm12
+// addrmode2base := reg +/- imm12
+//
+def addrmode2base : Operand<i32>,
+ ComplexPattern<i32, 3, "SelectAddrMode2Base", []> {
+ let PrintMethod = "printAddrMode2Operand";
+ let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
+}
+// addrmode2shop := reg +/- reg shop imm
+//
+def addrmode2shop : Operand<i32>,
+ ComplexPattern<i32, 3, "SelectAddrMode2ShOp", []> {
+ let PrintMethod = "printAddrMode2Operand";
+ let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
+}
+
+// addrmode2 := (addrmode2base || addrmode2shop)
//
def addrmode2 : Operand<i32>,
ComplexPattern<i32, 3, "SelectAddrMode2", []> {