summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-03-13 21:05:54 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-03-13 21:05:54 +0000
commit72a8bcf2384776ce9419b49114f2f6682d82b693 (patch)
tree28eecf5ee9a0153394b7514f32f4cf360882f4b3
parent507eefa75714cbff717106f4a42cda8cd7422ee3 (diff)
downloadbcm5719-llvm-72a8bcf2384776ce9419b49114f2f6682d82b693.tar.gz
bcm5719-llvm-72a8bcf2384776ce9419b49114f2f6682d82b693.zip
AM2 can match 2^n +/- 1. e.g. ldr r3, [r2, r2, lsl #2]
llvm-svn: 35088
-rw-r--r--llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index c9642caef73..b0c040b39d7 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -102,6 +102,29 @@ void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
bool ARMDAGToDAGISel::SelectAddrMode2(SDOperand Op, SDOperand N,
SDOperand &Base, SDOperand &Offset,
SDOperand &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.
+ int RHSC = (int)RHS->getValue();
+ if (RHSC & 1) {
+ RHSC = RHSC & ~1;
+ ARM_AM::AddrOpc AddSub = ARM_AM::add;
+ if (RHSC < 0) {
+ AddSub = ARM_AM::sub;
+ RHSC = - RHSC;
+ }
+ if (isPowerOf2_32(RHSC)) {
+ unsigned ShAmt = Log2_32(RHSC);
+ Base = Offset = N.getOperand(0);
+ Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
+ ARM_AM::lsl),
+ MVT::i32);
+ return true;
+ }
+ }
+ }
+ }
+
if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) {
Base = N;
if (N.getOpcode() == ISD::FrameIndex) {
OpenPOWER on IntegriCloud