return "ARM Assembly Printer";
}
return "ARM Assembly Printer";
}
+ void printAddrMode1(const MachineInstr *MI, int opNum);
+
void printMemRegImm(const MachineInstr *MI, int opNum,
const char *Modifier = NULL) {
const MachineOperand &MO1 = MI->getOperand(opNum);
void printMemRegImm(const MachineInstr *MI, int opNum,
const char *Modifier = NULL) {
const MachineOperand &MO1 = MI->getOperand(opNum);
+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) {
const MachineOperand &MO = MI->getOperand (opNum);
const MRegisterInfo &RI = *TM.getRegisterInfo();
void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand (opNum);
const MRegisterInfo &RI = *TM.getRegisterInfo();
SDOperand ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32);
SDOperand Cmp = DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS);
SDOperand ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32);
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) {
SDNode *Select(SDOperand Op);
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base);
SDNode *Select(SDOperand Op);
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base);
+ bool SelectAddrMode1(SDOperand N, SDOperand &Arg);
// Include the pieces autogenerated from the target description.
#include "ARMGenDAGISel.inc"
// Include the pieces autogenerated from the target description.
#include "ARMGenDAGISel.inc"
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
bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset,
SDOperand &Base) {
//register plus/minus 12 bit offset
bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset,
SDOperand &Base) {
unsigned &SrcReg, unsigned &DstReg) const {
MachineOpCode oc = MI.getOpcode();
switch (oc) {
unsigned &SrcReg, unsigned &DstReg) const {
MachineOpCode oc = MI.getOpcode();
switch (oc) {
- default:
- return false;
- case ARM::movrr:
assert(MI.getNumOperands() == 2 &&
MI.getOperand(0).isRegister() &&
assert(MI.getNumOperands() == 2 &&
MI.getOperand(0).isRegister() &&
- MI.getOperand(1).isRegister() &&
"Invalid ARM MOV instruction");
"Invalid ARM MOV instruction");
- SrcReg = MI.getOperand(1).getReg();;
- DstReg = MI.getOperand(0).getReg();;
- return true;
+ if (MI.getOperand(1).isRegister()) {
+ SrcReg = MI.getOperand(1).getReg();
+ DstReg = MI.getOperand(0).getReg();
+ return true;
+ }
//===----------------------------------------------------------------------===//
// 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> {
let PrintMethod = "printMemRegImm";
let NumMIOperands = 2;
def memri : Operand<iPTR> {
let PrintMethod = "printMemRegImm";
let NumMIOperands = 2;
}
// 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
def iaddr : ComplexPattern<iPTR, 2, "SelectAddrRegImm", [frameindex]>;
//register plus scaled register
//register plus/minus 12 bit offset
def iaddr : ComplexPattern<iPTR, 2, "SelectAddrRegImm", [frameindex]>;
//register plus scaled register
"str $src, $addr",
[(store IntRegs:$src, iaddr:$addr)]>;
"str $src, $addr",
[(store IntRegs:$src, iaddr:$addr)]>;
-def movrr : InstARM<(ops IntRegs:$dst, IntRegs:$src),
- "mov $dst, $src", []>;
-
-def movri : InstARM<(ops IntRegs:$dst, i32imm:$src),
- "mov $dst, $src", [(set IntRegs:$dst, imm:$src)]>;
+def MOV : InstARM<(ops IntRegs:$dst, op_addr_mode1:$src),
+ "mov $dst, $src", [(set IntRegs:$dst, addr_mode1:$src)]>;
-def addri : InstARM<(ops IntRegs:$dst, IntRegs:$a, i32imm:$b),
+def ADD : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
- [(set IntRegs:$dst, (add IntRegs:$a, imm:$b))]>;
+ [(set IntRegs:$dst, (add IntRegs:$a, addr_mode1:$b))]>;
// "LEA" forms of add
def lea_addri : InstARM<(ops IntRegs:$dst, memri:$addr),
// "LEA" forms of add
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),
- [(set IntRegs:$dst, (sub IntRegs:$a, imm:$b))]>;
-
-def andrr : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
- "and $dst, $a, $b",
- [(set IntRegs:$dst, (and IntRegs:$a, IntRegs:$b))]>;
+ [(set IntRegs:$dst, (sub IntRegs:$a, addr_mode1:$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
// to implement this
// All arm data processing instructions have a shift. Maybe we don't have
// to implement this
"mov $dst, $a, asr $b",
[(set IntRegs:$dst, (sra IntRegs:$a, IntRegs:$b))]>;
"mov $dst, $a, asr $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),
- "eor $dst, $a, $b",
- [(set IntRegs:$dst, (xor IntRegs:$a, IntRegs:$b))]>;
-
-def orr_rr : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
- "orr $dst, $a, $b",
- [(set IntRegs:$dst, (or IntRegs:$a, IntRegs:$b))]>;
-
+def ORR : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
+ "orr $dst, $a, $b",
+ [(set IntRegs:$dst, (or IntRegs:$a, addr_mode1:$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),
- [(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),
"b $dst",
[(br bb:$dst)]>;
"b $dst",
[(br bb:$dst)]>;
-def cmp : InstARM<(ops IntRegs:$a, IntRegs:$b),
+def cmp : InstARM<(ops IntRegs:$a, op_addr_mode1:$b),
- [(armcmp IntRegs:$a, IntRegs:$b)]>;
+ [(armcmp IntRegs:$a, addr_mode1:$b)]>;
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const {
assert (RC == ARM::IntRegsRegisterClass);
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const {
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,
// Insert a set of r12 with the full address
// r12 = r13 + offset
MachineBasicBlock *MBB2 = MI.getParent();
// Insert a set of r12 with the full address
// r12 = r13 + offset
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
MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
// Replace the FrameIndex with r12
MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
MFI->setStackSize(NumBytes);
//sub sp, sp, #NumBytes
MFI->setStackSize(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,
int NumBytes = (int) MFI->getStackSize();
//add sp, sp, #NumBytes
int NumBytes = (int) MFI->getStackSize();
//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 {