forked from OSchip/llvm-project
partial implementation of the ARM Addressing Mode 1
llvm-svn: 30252
This commit is contained in:
parent
e94f42a740
commit
e45a79a9e2
|
@ -54,6 +54,8 @@ namespace {
|
||||||
return "ARM Assembly Printer";
|
return "ARM Assembly Printer";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printAddrMode1(const MachineInstr *MI, int opNum);
|
||||||
|
|
||||||
void printMemRegImm(const MachineInstr *MI, int opNum,
|
void printMemRegImm(const MachineInstr *MI, int opNum,
|
||||||
const char *Modifier = NULL) {
|
const char *Modifier = NULL) {
|
||||||
const MachineOperand &MO1 = MI->getOperand(opNum);
|
const MachineOperand &MO1 = MI->getOperand(opNum);
|
||||||
|
@ -155,6 +157,17 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) {
|
||||||
|
const MachineOperand &MO1 = MI->getOperand(opNum);
|
||||||
|
|
||||||
|
if(MO1.isImmediate()) {
|
||||||
|
printOperand(MI, opNum);
|
||||||
|
} else {
|
||||||
|
assert(MO1.isRegister());
|
||||||
|
printOperand(MI, opNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
|
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
|
||||||
const MachineOperand &MO = MI->getOperand (opNum);
|
const MachineOperand &MO = MI->getOperand (opNum);
|
||||||
const MRegisterInfo &RI = *TM.getRegisterInfo();
|
const MRegisterInfo &RI = *TM.getRegisterInfo();
|
||||||
|
|
|
@ -386,7 +386,7 @@ static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) {
|
||||||
SDOperand ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32);
|
SDOperand ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32);
|
||||||
|
|
||||||
SDOperand Cmp = DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS);
|
SDOperand Cmp = DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS);
|
||||||
return DAG.getNode(ARMISD::SELECT, MVT::i32, FalseVal, TrueVal, ARMCC, Cmp);
|
return DAG.getNode(ARMISD::SELECT, MVT::i32, TrueVal, FalseVal, ARMCC, Cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) {
|
static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) {
|
||||||
|
@ -445,6 +445,7 @@ public:
|
||||||
SDNode *Select(SDOperand Op);
|
SDNode *Select(SDOperand Op);
|
||||||
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
|
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
|
||||||
bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base);
|
bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base);
|
||||||
|
bool SelectAddrMode1(SDOperand N, SDOperand &Arg);
|
||||||
|
|
||||||
// Include the pieces autogenerated from the target description.
|
// Include the pieces autogenerated from the target description.
|
||||||
#include "ARMGenDAGISel.inc"
|
#include "ARMGenDAGISel.inc"
|
||||||
|
@ -478,6 +479,24 @@ static bool isInt12Immediate(SDOperand Op, short &Imm) {
|
||||||
return isInt12Immediate(Op.Val, Imm);
|
return isInt12Immediate(Op.Val, Imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand N,
|
||||||
|
SDOperand &Arg) {
|
||||||
|
switch(N.getOpcode()) {
|
||||||
|
case ISD::CopyFromReg:
|
||||||
|
Arg = N;
|
||||||
|
return true;
|
||||||
|
case ISD::Constant: {
|
||||||
|
//TODO:check that we have a valid constant
|
||||||
|
int32_t t = cast<ConstantSDNode>(N)->getValue();
|
||||||
|
Arg = CurDAG->getTargetConstant(t, MVT::i32);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
std::cerr << "OpCode = " << N.getOpcode() << "\n";
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//register plus/minus 12 bit offset
|
//register plus/minus 12 bit offset
|
||||||
bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset,
|
bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset,
|
||||||
SDOperand &Base) {
|
SDOperand &Base) {
|
||||||
|
|
|
@ -33,15 +33,15 @@ bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
|
||||||
unsigned &SrcReg, unsigned &DstReg) const {
|
unsigned &SrcReg, unsigned &DstReg) const {
|
||||||
MachineOpCode oc = MI.getOpcode();
|
MachineOpCode oc = MI.getOpcode();
|
||||||
switch (oc) {
|
switch (oc) {
|
||||||
default:
|
case ARM::MOV:
|
||||||
return false;
|
|
||||||
case ARM::movrr:
|
|
||||||
assert(MI.getNumOperands() == 2 &&
|
assert(MI.getNumOperands() == 2 &&
|
||||||
MI.getOperand(0).isRegister() &&
|
MI.getOperand(0).isRegister() &&
|
||||||
MI.getOperand(1).isRegister() &&
|
|
||||||
"Invalid ARM MOV instruction");
|
"Invalid ARM MOV instruction");
|
||||||
SrcReg = MI.getOperand(1).getReg();;
|
if (MI.getOperand(1).isRegister()) {
|
||||||
DstReg = MI.getOperand(0).getReg();;
|
SrcReg = MI.getOperand(1).getReg();
|
||||||
return true;
|
DstReg = MI.getOperand(0).getReg();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,12 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Address operands
|
// Address operands
|
||||||
|
def op_addr_mode1 : Operand<iPTR> {
|
||||||
|
let PrintMethod = "printAddrMode1";
|
||||||
|
let NumMIOperands = 1;
|
||||||
|
let MIOperandInfo = (ops ptr_rc);
|
||||||
|
}
|
||||||
|
|
||||||
def memri : Operand<iPTR> {
|
def memri : Operand<iPTR> {
|
||||||
let PrintMethod = "printMemRegImm";
|
let PrintMethod = "printMemRegImm";
|
||||||
let NumMIOperands = 2;
|
let NumMIOperands = 2;
|
||||||
|
@ -20,6 +26,9 @@ def memri : Operand<iPTR> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define ARM specific addressing mode.
|
// Define ARM specific addressing mode.
|
||||||
|
//Addressing Mode 1: data processing operands
|
||||||
|
def addr_mode1 : ComplexPattern<iPTR, 1, "SelectAddrMode1", [imm]>;
|
||||||
|
|
||||||
//register plus/minus 12 bit offset
|
//register plus/minus 12 bit offset
|
||||||
def iaddr : ComplexPattern<iPTR, 2, "SelectAddrRegImm", [frameindex]>;
|
def iaddr : ComplexPattern<iPTR, 2, "SelectAddrRegImm", [frameindex]>;
|
||||||
//register plus scaled register
|
//register plus scaled register
|
||||||
|
@ -89,15 +98,12 @@ def str : InstARM<(ops IntRegs:$src, memri:$addr),
|
||||||
"str $src, $addr",
|
"str $src, $addr",
|
||||||
[(store IntRegs:$src, iaddr:$addr)]>;
|
[(store IntRegs:$src, iaddr:$addr)]>;
|
||||||
|
|
||||||
def movrr : InstARM<(ops IntRegs:$dst, IntRegs:$src),
|
def MOV : InstARM<(ops IntRegs:$dst, op_addr_mode1:$src),
|
||||||
"mov $dst, $src", []>;
|
"mov $dst, $src", [(set IntRegs:$dst, addr_mode1:$src)]>;
|
||||||
|
|
||||||
def movri : InstARM<(ops IntRegs:$dst, i32imm:$src),
|
def ADD : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
|
||||||
"mov $dst, $src", [(set IntRegs:$dst, imm:$src)]>;
|
|
||||||
|
|
||||||
def addri : InstARM<(ops IntRegs:$dst, IntRegs:$a, i32imm:$b),
|
|
||||||
"add $dst, $a, $b",
|
"add $dst, $a, $b",
|
||||||
[(set IntRegs:$dst, (add IntRegs:$a, imm:$b))]>;
|
[(set IntRegs:$dst, (add IntRegs:$a, addr_mode1:$b))]>;
|
||||||
|
|
||||||
// "LEA" forms of add
|
// "LEA" forms of add
|
||||||
def lea_addri : InstARM<(ops IntRegs:$dst, memri:$addr),
|
def lea_addri : InstARM<(ops IntRegs:$dst, memri:$addr),
|
||||||
|
@ -105,14 +111,13 @@ def lea_addri : InstARM<(ops IntRegs:$dst, memri:$addr),
|
||||||
[(set IntRegs:$dst, iaddr:$addr)]>;
|
[(set IntRegs:$dst, iaddr:$addr)]>;
|
||||||
|
|
||||||
|
|
||||||
def subri : InstARM<(ops IntRegs:$dst, IntRegs:$a, i32imm:$b),
|
def SUB : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
|
||||||
"sub $dst, $a, $b",
|
"sub $dst, $a, $b",
|
||||||
[(set IntRegs:$dst, (sub IntRegs:$a, imm:$b))]>;
|
[(set IntRegs:$dst, (sub IntRegs:$a, addr_mode1:$b))]>;
|
||||||
|
|
||||||
def andrr : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
|
|
||||||
"and $dst, $a, $b",
|
|
||||||
[(set IntRegs:$dst, (and IntRegs:$a, IntRegs:$b))]>;
|
|
||||||
|
|
||||||
|
def AND : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
|
||||||
|
"and $dst, $a, $b",
|
||||||
|
[(set IntRegs:$dst, (and IntRegs:$a, addr_mode1:$b))]>;
|
||||||
|
|
||||||
// All arm data processing instructions have a shift. Maybe we don't have
|
// All arm data processing instructions have a shift. Maybe we don't have
|
||||||
// to implement this
|
// to implement this
|
||||||
|
@ -124,20 +129,20 @@ def SRA : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
|
||||||
"mov $dst, $a, asr $b",
|
"mov $dst, $a, asr $b",
|
||||||
[(set IntRegs:$dst, (sra IntRegs:$a, IntRegs:$b))]>;
|
[(set IntRegs:$dst, (sra IntRegs:$a, IntRegs:$b))]>;
|
||||||
|
|
||||||
|
def EOR : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
|
||||||
|
"eor $dst, $a, $b",
|
||||||
|
[(set IntRegs:$dst, (xor IntRegs:$a, addr_mode1:$b))]>;
|
||||||
|
|
||||||
def eor_rr : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
|
def ORR : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
|
||||||
"eor $dst, $a, $b",
|
"orr $dst, $a, $b",
|
||||||
[(set IntRegs:$dst, (xor IntRegs:$a, IntRegs:$b))]>;
|
[(set IntRegs:$dst, (or IntRegs:$a, addr_mode1:$b))]>;
|
||||||
|
|
||||||
def orr_rr : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
|
|
||||||
"orr $dst, $a, $b",
|
|
||||||
[(set IntRegs:$dst, (or IntRegs:$a, IntRegs:$b))]>;
|
|
||||||
|
|
||||||
|
|
||||||
let isTwoAddress = 1 in {
|
let isTwoAddress = 1 in {
|
||||||
def movcond : InstARM<(ops IntRegs:$dst, IntRegs:$false, IntRegs:$true, CCOp:$cc),
|
def movcond : InstARM<(ops IntRegs:$dst, IntRegs:$false,
|
||||||
|
op_addr_mode1:$true, CCOp:$cc),
|
||||||
"mov$cc $dst, $true",
|
"mov$cc $dst, $true",
|
||||||
[(set IntRegs:$dst, (armselect IntRegs:$true, IntRegs:$false, imm:$cc))]>;
|
[(set IntRegs:$dst, (armselect addr_mode1:$true,
|
||||||
|
IntRegs:$false, imm:$cc))]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
def bcond : InstARM<(ops brtarget:$dst, CCOp:$cc),
|
def bcond : InstARM<(ops brtarget:$dst, CCOp:$cc),
|
||||||
|
@ -148,6 +153,6 @@ def b : InstARM<(ops brtarget:$dst),
|
||||||
"b $dst",
|
"b $dst",
|
||||||
[(br bb:$dst)]>;
|
[(br bb:$dst)]>;
|
||||||
|
|
||||||
def cmp : InstARM<(ops IntRegs:$a, IntRegs:$b),
|
def cmp : InstARM<(ops IntRegs:$a, op_addr_mode1:$b),
|
||||||
"cmp $a, $b",
|
"cmp $a, $b",
|
||||||
[(armcmp IntRegs:$a, IntRegs:$b)]>;
|
[(armcmp IntRegs:$a, addr_mode1:$b)]>;
|
||||||
|
|
|
@ -48,7 +48,7 @@ void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
|
||||||
unsigned DestReg, unsigned SrcReg,
|
unsigned DestReg, unsigned SrcReg,
|
||||||
const TargetRegisterClass *RC) const {
|
const TargetRegisterClass *RC) const {
|
||||||
assert (RC == ARM::IntRegsRegisterClass);
|
assert (RC == ARM::IntRegsRegisterClass);
|
||||||
BuildMI(MBB, I, ARM::movrr, 1, DestReg).addReg(SrcReg);
|
BuildMI(MBB, I, ARM::MOV, 1, DestReg).addReg(SrcReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
|
MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
|
||||||
|
@ -114,7 +114,7 @@ ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
|
||||||
// Insert a set of r12 with the full address
|
// Insert a set of r12 with the full address
|
||||||
// r12 = r13 + offset
|
// r12 = r13 + offset
|
||||||
MachineBasicBlock *MBB2 = MI.getParent();
|
MachineBasicBlock *MBB2 = MI.getParent();
|
||||||
BuildMI(*MBB2, II, ARM::addri, 2, ARM::R12).addReg(ARM::R13).addImm(Offset);
|
BuildMI(*MBB2, II, ARM::ADD, 2, ARM::R12).addReg(ARM::R13).addImm(Offset);
|
||||||
|
|
||||||
// Replace the FrameIndex with r12
|
// Replace the FrameIndex with r12
|
||||||
MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
|
MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
|
||||||
|
@ -140,7 +140,7 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
MFI->setStackSize(NumBytes);
|
MFI->setStackSize(NumBytes);
|
||||||
|
|
||||||
//sub sp, sp, #NumBytes
|
//sub sp, sp, #NumBytes
|
||||||
BuildMI(MBB, MBBI, ARM::subri, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes);
|
BuildMI(MBB, MBBI, ARM::SUB, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
|
@ -153,7 +153,7 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
int NumBytes = (int) MFI->getStackSize();
|
int NumBytes = (int) MFI->getStackSize();
|
||||||
|
|
||||||
//add sp, sp, #NumBytes
|
//add sp, sp, #NumBytes
|
||||||
BuildMI(MBB, MBBI, ARM::addri, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes);
|
BuildMI(MBB, MBBI, ARM::ADD, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ARMRegisterInfo::getRARegister() const {
|
unsigned ARMRegisterInfo::getRARegister() const {
|
||||||
|
|
Loading…
Reference in New Issue