1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

Improve handling of Thumb2 PC-relative loads by converting LDRpci (and friends) to Pseudos.

llvm-svn: 121021
This commit is contained in:
Owen Anderson 2010-12-06 18:35:51 +00:00
parent 6c27b4f3cf
commit 0c51a02230
2 changed files with 34 additions and 20 deletions

View File

@ -699,6 +699,36 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
MI.eraseFromParent();
break;
}
case ARM::t2LDRHpci:
case ARM::t2LDRBpci:
case ARM::t2LDRSHpci:
case ARM::t2LDRSBpci:
case ARM::t2LDRpci: {
unsigned NewLdOpc;
if (Opcode == ARM::t2LDRpci)
NewLdOpc = ARM::t2LDRi12;
else if (Opcode == ARM::t2LDRHpci)
NewLdOpc = ARM::t2LDRHi12;
else if (Opcode == ARM::t2LDRBpci)
NewLdOpc = ARM::t2LDRBi12;
else if (Opcode == ARM::t2LDRSHpci)
NewLdOpc = ARM::t2LDRSHi12;
else if (Opcode == ARM::t2LDRSBpci)
NewLdOpc = ARM::t2LDRSBi12;
else
llvm_unreachable("Not a known opcode?");
unsigned DstReg = MI.getOperand(0).getReg();
bool DstIsDead = MI.getOperand(0).isDead();
MachineInstrBuilder MIB =
BuildMI(MBB, MBBI, MI.getDebugLoc(),
TII->get(NewLdOpc), DstReg)
.addOperand(MI.getOperand(1));
(*MIB).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
TransferImpOps(MI, MIB, MIB);
MI.eraseFromParent();
break;
}
case ARM::tLDRpci_pic:
case ARM::t2LDRpci_pic: {
unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
@ -706,9 +736,9 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
unsigned DstReg = MI.getOperand(0).getReg();
bool DstIsDead = MI.getOperand(0).isDead();
MachineInstrBuilder MIB1 =
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
BuildMI(MBB, MBBI, MI.getDebugLoc(),
TII->get(NewLdOpc), DstReg)
.addOperand(MI.getOperand(1)));
.addOperand(MI.getOperand(1));
(*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
TII->get(ARM::tPICADD))

View File

@ -888,24 +888,8 @@ multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
let Inst{5-4} = addr{1-0}; // imm
}
// FIXME: Is the pci variant actually needed?
def pci : T2Ipc <(outs GPR:$Rt), (ins i32imm:$addr), iii,
opc, ".w\t$Rt, $addr",
[(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> {
let isReMaterializable = 1;
let Inst{31-27} = 0b11111;
let Inst{26-25} = 0b00;
let Inst{24} = signed;
let Inst{23} = ?; // add = (U == '1')
let Inst{22-21} = opcod;
let Inst{20} = 1; // load
let Inst{19-16} = 0b1111; // Rn
bits<4> Rt;
bits<12> addr;
let Inst{15-12} = Rt{3-0};
let Inst{11-0} = addr{11-0};
}
def pci : tPseudoInst<(outs GPR:$Rt), (ins i32imm:$addr), Size4Bytes, iis,
[(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]>;
}
/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.