forked from OSchip/llvm-project
parent
84cc1f7cb8
commit
3130a756ef
|
@ -41,6 +41,16 @@ namespace llvm {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ARMShift {
|
||||||
|
enum ShiftTypes {
|
||||||
|
LSL,
|
||||||
|
LSR,
|
||||||
|
ASR,
|
||||||
|
ROR,
|
||||||
|
RRX
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
|
static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
|
||||||
switch (CC) {
|
switch (CC) {
|
||||||
default: assert(0 && "Unknown condition code");
|
default: assert(0 && "Unknown condition code");
|
||||||
|
|
|
@ -158,13 +158,38 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) {
|
void ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) {
|
||||||
const MachineOperand &MO1 = MI->getOperand(opNum);
|
const MachineOperand &Arg = MI->getOperand(opNum);
|
||||||
|
const MachineOperand &Shift = MI->getOperand(opNum + 1);
|
||||||
|
const MachineOperand &ShiftType = MI->getOperand(opNum + 2);
|
||||||
|
|
||||||
if(MO1.isImmediate()) {
|
if(Arg.isImmediate()) {
|
||||||
|
assert(Shift.getImmedValue() == 0);
|
||||||
printOperand(MI, opNum);
|
printOperand(MI, opNum);
|
||||||
} else {
|
} else {
|
||||||
assert(MO1.isRegister());
|
assert(Arg.isRegister());
|
||||||
printOperand(MI, opNum);
|
printOperand(MI, opNum);
|
||||||
|
if(Shift.isRegister() || Shift.getImmedValue() != 0) {
|
||||||
|
const char *s = NULL;
|
||||||
|
switch(ShiftType.getImmedValue()) {
|
||||||
|
case ARMShift::LSL:
|
||||||
|
s = ", lsl ";
|
||||||
|
break;
|
||||||
|
case ARMShift::LSR:
|
||||||
|
s = ", lsr ";
|
||||||
|
break;
|
||||||
|
case ARMShift::ASR:
|
||||||
|
s = ", asr ";
|
||||||
|
break;
|
||||||
|
case ARMShift::ROR:
|
||||||
|
s = ", ror ";
|
||||||
|
break;
|
||||||
|
case ARMShift::RRX:
|
||||||
|
s = ", rrx ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
O << s;
|
||||||
|
printOperand(MI, opNum + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -445,7 +445,8 @@ 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);
|
bool SelectAddrMode1(SDOperand N, SDOperand &Arg, SDOperand &Shift,
|
||||||
|
SDOperand &ShiftType);
|
||||||
|
|
||||||
// Include the pieces autogenerated from the target description.
|
// Include the pieces autogenerated from the target description.
|
||||||
#include "ARMGenDAGISel.inc"
|
#include "ARMGenDAGISel.inc"
|
||||||
|
@ -480,17 +481,38 @@ static bool isInt12Immediate(SDOperand Op, short &Imm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand N,
|
bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand N,
|
||||||
SDOperand &Arg) {
|
SDOperand &Arg,
|
||||||
|
SDOperand &Shift,
|
||||||
|
SDOperand &ShiftType) {
|
||||||
switch(N.getOpcode()) {
|
switch(N.getOpcode()) {
|
||||||
case ISD::Constant: {
|
case ISD::Constant: {
|
||||||
//TODO:check that we have a valid constant
|
//TODO:check that we have a valid constant
|
||||||
int32_t t = cast<ConstantSDNode>(N)->getValue();
|
int32_t t = cast<ConstantSDNode>(N)->getValue();
|
||||||
Arg = CurDAG->getTargetConstant(t, MVT::i32);
|
Arg = CurDAG->getTargetConstant(t, MVT::i32);
|
||||||
|
Shift = CurDAG->getTargetConstant(0, MVT::i32);
|
||||||
|
ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case ISD::SRA:
|
||||||
|
Arg = N.getOperand(0);
|
||||||
|
Shift = N.getOperand(1);
|
||||||
|
ShiftType = CurDAG->getTargetConstant(ARMShift::ASR, MVT::i32);
|
||||||
|
return true;
|
||||||
|
case ISD::SRL:
|
||||||
|
Arg = N.getOperand(0);
|
||||||
|
Shift = N.getOperand(1);
|
||||||
|
ShiftType = CurDAG->getTargetConstant(ARMShift::LSR, MVT::i32);
|
||||||
|
return true;
|
||||||
|
case ISD::SHL:
|
||||||
|
Arg = N.getOperand(0);
|
||||||
|
Shift = N.getOperand(1);
|
||||||
|
ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Arg = N;
|
Arg = N;
|
||||||
|
Shift = CurDAG->getTargetConstant(0, MVT::i32);
|
||||||
|
ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,15 +33,18 @@ 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) {
|
||||||
case ARM::MOV:
|
case ARM::MOV: {
|
||||||
assert(MI.getNumOperands() == 2 &&
|
assert(MI.getNumOperands() == 4 &&
|
||||||
MI.getOperand(0).isRegister() &&
|
MI.getOperand(0).isRegister() &&
|
||||||
"Invalid ARM MOV instruction");
|
"Invalid ARM MOV instruction");
|
||||||
if (MI.getOperand(1).isRegister()) {
|
const MachineOperand &Arg = MI.getOperand(1);
|
||||||
|
const MachineOperand &Shift = MI.getOperand(2);
|
||||||
|
if (Arg.isRegister() && Shift.isImmediate() && Shift.getImmedValue() == 0) {
|
||||||
SrcReg = MI.getOperand(1).getReg();
|
SrcReg = MI.getOperand(1).getReg();
|
||||||
DstReg = MI.getOperand(0).getReg();
|
DstReg = MI.getOperand(0).getReg();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
// Address operands
|
// Address operands
|
||||||
def op_addr_mode1 : Operand<iPTR> {
|
def op_addr_mode1 : Operand<iPTR> {
|
||||||
let PrintMethod = "printAddrMode1";
|
let PrintMethod = "printAddrMode1";
|
||||||
let NumMIOperands = 1;
|
let NumMIOperands = 3;
|
||||||
let MIOperandInfo = (ops ptr_rc);
|
let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
def memri : Operand<iPTR> {
|
def memri : Operand<iPTR> {
|
||||||
|
@ -27,7 +27,7 @@ def memri : Operand<iPTR> {
|
||||||
|
|
||||||
// Define ARM specific addressing mode.
|
// Define ARM specific addressing mode.
|
||||||
//Addressing Mode 1: data processing operands
|
//Addressing Mode 1: data processing operands
|
||||||
def addr_mode1 : ComplexPattern<iPTR, 1, "SelectAddrMode1", [imm]>;
|
def addr_mode1 : ComplexPattern<iPTR, 3, "SelectAddrMode1", [imm, sra, shl, srl]>;
|
||||||
|
|
||||||
//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]>;
|
||||||
|
@ -119,21 +119,6 @@ def AND : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
|
||||||
"and $dst, $a, $b",
|
"and $dst, $a, $b",
|
||||||
[(set IntRegs:$dst, (and IntRegs:$a, addr_mode1:$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
|
|
||||||
def SHL : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
|
|
||||||
"mov $dst, $a, lsl $b",
|
|
||||||
[(set IntRegs:$dst, (shl IntRegs:$a, IntRegs:$b))]>;
|
|
||||||
|
|
||||||
def SRA : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
|
|
||||||
"mov $dst, $a, asr $b",
|
|
||||||
[(set IntRegs:$dst, (sra IntRegs:$a, IntRegs:$b))]>;
|
|
||||||
|
|
||||||
def SRL : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
|
|
||||||
"mov $dst, $a, lsr $b",
|
|
||||||
[(set IntRegs:$dst, (srl IntRegs:$a, IntRegs:$b))]>;
|
|
||||||
|
|
||||||
|
|
||||||
def EOR : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
|
def EOR : InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
|
||||||
"eor $dst, $a, $b",
|
"eor $dst, $a, $b",
|
||||||
[(set IntRegs:$dst, (xor IntRegs:$a, addr_mode1:$b))]>;
|
[(set IntRegs:$dst, (xor IntRegs:$a, addr_mode1:$b))]>;
|
||||||
|
|
|
@ -48,7 +48,8 @@ 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::MOV, 1, DestReg).addReg(SrcReg);
|
BuildMI(MBB, I, ARM::MOV, 3, DestReg).addReg(SrcReg).addImm(0)
|
||||||
|
.addImm(ARMShift::LSL);
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
|
MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
|
||||||
|
@ -114,7 +115,8 @@ 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::ADD, 2, ARM::R12).addReg(ARM::R13).addImm(Offset);
|
BuildMI(*MBB2, II, ARM::ADD, 4, ARM::R12).addReg(ARM::R13).addImm(Offset)
|
||||||
|
.addImm(0).addImm(ARMShift::LSL);
|
||||||
|
|
||||||
// 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 +142,8 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
MFI->setStackSize(NumBytes);
|
MFI->setStackSize(NumBytes);
|
||||||
|
|
||||||
//sub sp, sp, #NumBytes
|
//sub sp, sp, #NumBytes
|
||||||
BuildMI(MBB, MBBI, ARM::SUB, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes);
|
BuildMI(MBB, MBBI, ARM::SUB, 4, ARM::R13).addReg(ARM::R13).addImm(NumBytes)
|
||||||
|
.addImm(0).addImm(ARMShift::LSL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
|
@ -153,7 +156,8 @@ 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::ADD, 2, ARM::R13).addReg(ARM::R13).addImm(NumBytes);
|
BuildMI(MBB, MBBI, ARM::ADD, 4, ARM::R13).addReg(ARM::R13).addImm(NumBytes)
|
||||||
|
.addImm(0).addImm(ARMShift::LSL);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ARMRegisterInfo::getRARegister() const {
|
unsigned ARMRegisterInfo::getRARegister() const {
|
||||||
|
|
Loading…
Reference in New Issue