mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
add shifts to addressing mode 1
llvm-svn: 30291
This commit is contained in:
parent
fdf4c06dac
commit
1a3020bfcf
@ -41,6 +41,16 @@ namespace llvm {
|
||||
};
|
||||
}
|
||||
|
||||
namespace ARMShift {
|
||||
enum ShiftTypes {
|
||||
LSL,
|
||||
LSR,
|
||||
ASR,
|
||||
ROR,
|
||||
RRX
|
||||
};
|
||||
}
|
||||
|
||||
static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
|
||||
switch (CC) {
|
||||
default: assert(0 && "Unknown condition code");
|
||||
|
@ -158,13 +158,38 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
assert(MO1.isRegister());
|
||||
assert(Arg.isRegister());
|
||||
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);
|
||||
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
|
||||
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 "ARMGenDAGISel.inc"
|
||||
@ -480,17 +481,38 @@ static bool isInt12Immediate(SDOperand Op, short &Imm) {
|
||||
}
|
||||
|
||||
bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand N,
|
||||
SDOperand &Arg) {
|
||||
SDOperand &Arg,
|
||||
SDOperand &Shift,
|
||||
SDOperand &ShiftType) {
|
||||
switch(N.getOpcode()) {
|
||||
case ISD::Constant: {
|
||||
//TODO:check that we have a valid constant
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -33,15 +33,18 @@ bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
|
||||
unsigned &SrcReg, unsigned &DstReg) const {
|
||||
MachineOpCode oc = MI.getOpcode();
|
||||
switch (oc) {
|
||||
case ARM::MOV:
|
||||
assert(MI.getNumOperands() == 2 &&
|
||||
case ARM::MOV: {
|
||||
assert(MI.getNumOperands() == 4 &&
|
||||
MI.getOperand(0).isRegister() &&
|
||||
"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();
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
// Address operands
|
||||
def op_addr_mode1 : Operand<iPTR> {
|
||||
let PrintMethod = "printAddrMode1";
|
||||
let NumMIOperands = 1;
|
||||
let MIOperandInfo = (ops ptr_rc);
|
||||
let NumMIOperands = 3;
|
||||
let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm);
|
||||
}
|
||||
|
||||
def memri : Operand<iPTR> {
|
||||
@ -27,7 +27,7 @@ def memri : Operand<iPTR> {
|
||||
|
||||
// Define ARM specific addressing mode.
|
||||
//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
|
||||
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",
|
||||
[(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),
|
||||
"eor $dst, $a, $b",
|
||||
[(set IntRegs:$dst, (xor IntRegs:$a, addr_mode1:$b))]>;
|
||||
|
@ -48,7 +48,8 @@ void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
const TargetRegisterClass *RC) const {
|
||||
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,
|
||||
@ -114,7 +115,8 @@ ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
|
||||
// Insert a set of r12 with the full address
|
||||
// r12 = r13 + offset
|
||||
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
|
||||
MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
|
||||
@ -140,7 +142,8 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||
MFI->setStackSize(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,
|
||||
@ -153,7 +156,8 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||
int NumBytes = (int) MFI->getStackSize();
|
||||
|
||||
//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 {
|
||||
|
Loading…
Reference in New Issue
Block a user