add a "load effective address"
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 17 Aug 2006 17:09:40 +0000 (17:09 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 17 Aug 2006 17:09:40 +0000 (17:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29748 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMISelDAGToDAG.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMRegisterInfo.cpp
test/CodeGen/ARM/argaddr.ll [new file with mode: 0644]

index d998fdff010ce1b26ce1195f97821ecd40bd051d..adf444d29a671f4626b29feedd0ab88aa262baf3 100644 (file)
@@ -59,19 +59,27 @@ namespace {
       return "ARM Assembly Printer";
     }
 
-    void printMemRegImm(const MachineInstr *MI, unsigned OpNo) {
-      const MachineOperand &MO1 = MI->getOperand(OpNo);
-      const MachineOperand &MO2 = MI->getOperand(OpNo + 1);
+    void printMemRegImm(const MachineInstr *MI, int opNum,
+                       const char *Modifier = NULL) {
+      const MachineOperand &MO1 = MI->getOperand(opNum);
+      const MachineOperand &MO2 = MI->getOperand(opNum + 1);
       assert(MO1.isImmediate());
+      bool arith = false;
+      if (Modifier != NULL) {
+       assert(strcmp(Modifier, "arith") == 0);
+       arith = true;
+      }
 
       if (MO2.isConstantPoolIndex()) {
-       printOperand(MI, OpNo + 1);
+       printOperand(MI, opNum + 1);
       } else if (MO2.isRegister()) {
-       O << '[';
-       printOperand(MI, OpNo + 1);
+       if(!arith)
+         O << '[';
+       printOperand(MI, opNum + 1);
        O << ", ";
-       printOperand(MI, OpNo);
-       O << ']';
+       printOperand(MI, opNum);
+       if(!arith)
+         O << ']';
       } else {
        assert(0 && "Invalid Operand Type");
       }
index 80aaae54daba0f1a922ed1c42a486a21ef78e94a..56d61165c3c3d4793ab3e8133423ad5a76b17b96 100644 (file)
@@ -358,6 +358,11 @@ static bool isInt12Immediate(SDOperand Op, short &Imm) {
 //register plus/minus 12 bit offset
 bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset,
                                    SDOperand &Base) {
+  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
+    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
+    Offset = CurDAG->getTargetConstant(0, MVT::i32);
+    return true;
+  }
   if (N.getOpcode() == ISD::ADD) {
     short imm = 0;
     if (isInt12Immediate(N.getOperand(1), imm)) {
index cc6377eabde9442260732c5088c4e44ebcdeca5b..8619a80a3b935951f8adab39707b116cd48fd9ad 100644 (file)
@@ -21,7 +21,7 @@ def memri : Operand<iPTR> {
 
 // Define ARM specific addressing mode.
 //register plus/minus 12 bit offset
-def iaddr  : ComplexPattern<iPTR, 2, "SelectAddrRegImm", []>;
+def iaddr  : ComplexPattern<iPTR, 2, "SelectAddrRegImm", [frameindex]>;
 //register plus scaled register
 //def raddr  : ComplexPattern<iPTR, 2, "SelectAddrRegReg", []>;
 
@@ -83,6 +83,12 @@ def addri   : InstARM<(ops IntRegs:$dst, IntRegs:$a, i32imm:$b),
                        "add $dst, $a, $b",
                       [(set IntRegs:$dst, (add IntRegs:$a, imm:$b))]>;
 
+// "LEA" forms of add
+def lea_addri : InstARM<(ops IntRegs:$dst, memri:$addr),
+                        "add $dst, ${addr:arith}",
+                        [(set IntRegs:$dst, iaddr:$addr)]>;
+
+
 def subri   : InstARM<(ops IntRegs:$dst, IntRegs:$a, i32imm:$b),
                        "sub $dst, $a, $b",
                       [(set IntRegs:$dst, (sub IntRegs:$a, imm:$b))]>;
index a9c30c40c7e98541b984f78b14cf9a1038584c95..c5eef1195205c7d23acf2a36bad3d4b6a112fa7d 100644 (file)
@@ -89,7 +89,8 @@ ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
   MachineFunction &MF = *MBB.getParent();
 
   assert (MI.getOpcode() == ARM::ldr ||
-         MI.getOpcode() == ARM::str);
+         MI.getOpcode() == ARM::str ||
+         MI.getOpcode() == ARM::lea_addri);
 
   unsigned FrameIdx = 2;
   unsigned OffIdx = 1;
diff --git a/test/CodeGen/ARM/argaddr.ll b/test/CodeGen/ARM/argaddr.ll
new file mode 100644 (file)
index 0000000..abdf215
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | llc -march=arm
+void %f(int %a, int %b, int %c, int %d, int %e) {
+entry:
+       %a_addr = alloca int            ; <int*> [#uses=2]
+       %b_addr = alloca int            ; <int*> [#uses=2]
+       %c_addr = alloca int            ; <int*> [#uses=2]
+       %d_addr = alloca int            ; <int*> [#uses=2]
+       %e_addr = alloca int            ; <int*> [#uses=2]
+       store int %a, int* %a_addr
+       store int %b, int* %b_addr
+       store int %c, int* %c_addr
+       store int %d, int* %d_addr
+       store int %e, int* %e_addr
+       call void %g( int* %a_addr, int* %b_addr, int* %c_addr, int* %d_addr, int* %e_addr )
+       ret void
+}
+
+declare void %g(int*, int*, int*, int*, int*)