summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2006-08-17 17:09:40 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2006-08-17 17:09:40 +0000
commitf3a335cedff423438789c593d58be068b124dc1e (patch)
tree0101525f562092cbaabf4a4ff64c971be4dfdb41
parentd337295fb0f724d9da1e029260f68ef09b25e1fe (diff)
downloadllvm-f3a335cedff423438789c593d58be068b124dc1e.tar.gz
llvm-f3a335cedff423438789c593d58be068b124dc1e.tar.bz2
llvm-f3a335cedff423438789c593d58be068b124dc1e.tar.xz
add a "load effective address"
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29748 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp24
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp5
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td8
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.cpp3
-rw-r--r--test/CodeGen/ARM/argaddr.ll18
5 files changed, 48 insertions, 10 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index d998fdff01..adf444d29a 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -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");
}
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 80aaae54da..56d61165c3 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -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)) {
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index cc6377eabd..8619a80a3b 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -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))]>;
diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp
index a9c30c40c7..c5eef11952 100644
--- a/lib/Target/ARM/ARMRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMRegisterInfo.cpp
@@ -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
index 0000000000..abdf215ee0
--- /dev/null
+++ b/test/CodeGen/ARM/argaddr.ll
@@ -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*)