From f3a335cedff423438789c593d58be068b124dc1e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 17 Aug 2006 17:09:40 +0000 Subject: [PATCH] add a "load effective address" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29748 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMAsmPrinter.cpp | 24 ++++++++++++++++-------- lib/Target/ARM/ARMISelDAGToDAG.cpp | 5 +++++ lib/Target/ARM/ARMInstrInfo.td | 8 +++++++- lib/Target/ARM/ARMRegisterInfo.cpp | 3 ++- test/CodeGen/ARM/argaddr.ll | 18 ++++++++++++++++++ 5 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 test/CodeGen/ARM/argaddr.ll diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index d998fdff010..adf444d29a6 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 80aaae54dab..56d61165c3c 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(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 cc6377eabde..8619a80a3b9 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -21,7 +21,7 @@ def memri : Operand { // Define ARM specific addressing mode. //register plus/minus 12 bit offset -def iaddr : ComplexPattern; +def iaddr : ComplexPattern; //register plus scaled register //def raddr : ComplexPattern; @@ -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 a9c30c40c7e..c5eef119520 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 00000000000..abdf215ee02 --- /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 ; [#uses=2] + %b_addr = alloca int ; [#uses=2] + %c_addr = alloca int ; [#uses=2] + %d_addr = alloca int ; [#uses=2] + %e_addr = alloca 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*) -- 2.11.0