mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Second attempt at converting Thumb2's LDRpci, including updating the gazillion places that need to know about it.
llvm-svn: 121082
This commit is contained in:
parent
7a95053a98
commit
81f8b084e6
@ -605,7 +605,11 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF,
|
||||
|
||||
case ARM::LDRi12:
|
||||
case ARM::LDRcp:
|
||||
case ARM::t2LDRpci:
|
||||
case ARM::t2LDRi12:
|
||||
case ARM::t2LDRHi12:
|
||||
case ARM::t2LDRBi12:
|
||||
case ARM::t2LDRSHi12:
|
||||
case ARM::t2LDRSBi12:
|
||||
Bits = 12; // +-offset_12
|
||||
NegOk = true;
|
||||
break;
|
||||
|
@ -699,16 +699,48 @@ 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();
|
||||
MachineInstrBuilder MIB =
|
||||
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
||||
TII->get(NewLdOpc), DstReg)
|
||||
.addReg(ARM::PC)
|
||||
.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)
|
||||
? ARM::tLDRpci : ARM::t2LDRpci;
|
||||
? ARM::tLDRpci : ARM::t2LDRi12;
|
||||
unsigned DstReg = MI.getOperand(0).getReg();
|
||||
bool DstIsDead = MI.getOperand(0).isDead();
|
||||
MachineInstrBuilder MIB1 =
|
||||
AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
||||
TII->get(NewLdOpc), DstReg)
|
||||
.addOperand(MI.getOperand(1)));
|
||||
BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
||||
TII->get(NewLdOpc), DstReg);
|
||||
if (Opcode == ARM::t2LDRpci_pic) MIB1.addReg(ARM::PC);
|
||||
MIB1.addOperand(MI.getOperand(1));
|
||||
AddDefaultPred(MIB1);
|
||||
(*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
|
||||
MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
||||
TII->get(ARM::tPICADD))
|
||||
|
@ -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.
|
||||
|
@ -462,13 +462,18 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
bool isAdd = true;
|
||||
// If The first operand isn't a register, we have a label reference.
|
||||
const MCOperand &MO = MI.getOperand(OpIdx);
|
||||
if (!MO.isReg()) {
|
||||
const MCOperand &MO2 = MI.getOperand(OpIdx+1);
|
||||
if (!MO.isReg() || (MO.getReg() == ARM::PC && MO2.isExpr())) {
|
||||
Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC.
|
||||
Imm12 = 0;
|
||||
isAdd = false ; // 'U' bit is set as part of the fixup.
|
||||
|
||||
assert(MO.isExpr() && "Unexpected machine operand type!");
|
||||
const MCExpr *Expr = MO.getExpr();
|
||||
const MCExpr *Expr = 0;
|
||||
if (!MO.isReg())
|
||||
Expr = MO.getExpr();
|
||||
else
|
||||
Expr = MO2.getExpr();
|
||||
|
||||
MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
|
||||
Fixups.push_back(MCFixup::Create(0, Expr, Kind));
|
||||
|
||||
|
@ -256,27 +256,27 @@ static unsigned T2Morph2LoadLiteral(unsigned Opcode) {
|
||||
case ARM::t2LDR_POST: case ARM::t2LDR_PRE:
|
||||
case ARM::t2LDRi12: case ARM::t2LDRi8:
|
||||
case ARM::t2LDRs: case ARM::t2LDRT:
|
||||
return ARM::t2LDRpci;
|
||||
return ARM::t2LDRi12;
|
||||
|
||||
case ARM::t2LDRB_POST: case ARM::t2LDRB_PRE:
|
||||
case ARM::t2LDRBi12: case ARM::t2LDRBi8:
|
||||
case ARM::t2LDRBs: case ARM::t2LDRBT:
|
||||
return ARM::t2LDRBpci;
|
||||
return ARM::t2LDRBi12;
|
||||
|
||||
case ARM::t2LDRH_POST: case ARM::t2LDRH_PRE:
|
||||
case ARM::t2LDRHi12: case ARM::t2LDRHi8:
|
||||
case ARM::t2LDRHs: case ARM::t2LDRHT:
|
||||
return ARM::t2LDRHpci;
|
||||
return ARM::t2LDRHi12;
|
||||
|
||||
case ARM::t2LDRSB_POST: case ARM::t2LDRSB_PRE:
|
||||
case ARM::t2LDRSBi12: case ARM::t2LDRSBi8:
|
||||
case ARM::t2LDRSBs: case ARM::t2LDRSBT:
|
||||
return ARM::t2LDRSBpci;
|
||||
return ARM::t2LDRSBi12;
|
||||
|
||||
case ARM::t2LDRSH_POST: case ARM::t2LDRSH_PRE:
|
||||
case ARM::t2LDRSHi12: case ARM::t2LDRSHi8:
|
||||
case ARM::t2LDRSHs: case ARM::t2LDRSHT:
|
||||
return ARM::t2LDRSHpci;
|
||||
return ARM::t2LDRSHi12;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1777,37 +1777,6 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
|
||||
return true;
|
||||
}
|
||||
|
||||
// A8.6.63 LDRB (literal)
|
||||
// A8.6.79 LDRSB (literal)
|
||||
// A8.6.75 LDRH (literal)
|
||||
// A8.6.83 LDRSH (literal)
|
||||
// A8.6.59 LDR (literal)
|
||||
//
|
||||
// These instrs calculate an address from the PC value and an immediate offset.
|
||||
// Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
|
||||
static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
|
||||
uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
|
||||
|
||||
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
|
||||
if (!OpInfo) return false;
|
||||
|
||||
assert(NumOps >= 2 &&
|
||||
OpInfo[0].RegClass == ARM::GPRRegClassID &&
|
||||
OpInfo[1].RegClass < 0 &&
|
||||
"Expect >= 2 operands, first as reg, and second as imm operand");
|
||||
|
||||
// Build the register operand, followed by the (+/-)imm12 immediate.
|
||||
|
||||
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
|
||||
decodeRd(insn))));
|
||||
|
||||
MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
|
||||
|
||||
NumOpsAdded = 2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// A6.3.10 Store single data item
|
||||
// A6.3.9 Load byte, memory hints
|
||||
// A6.3.8 Load halfword, memory hints
|
||||
@ -1843,10 +1812,6 @@ static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
|
||||
if (Thumb2PreloadOpcode(Opcode))
|
||||
return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
|
||||
|
||||
// See, for example, A6.3.7 Load word: Table A6-18 Load word.
|
||||
if (Load && Rn == 15)
|
||||
return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
|
||||
|
||||
const TargetInstrDesc &TID = ARMInsts[Opcode];
|
||||
const TargetOperandInfo *OpInfo = TID.OpInfo;
|
||||
unsigned &OpIdx = NumOpsAdded;
|
||||
|
@ -560,6 +560,9 @@ void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
|
||||
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
|
||||
printOperand(MI, OpNum, O);
|
||||
return;
|
||||
} else if (MO1.getReg() == ARM::PC && MO2.isExpr()) {
|
||||
printOperand(MI, OpNum+1, O);
|
||||
return;
|
||||
}
|
||||
|
||||
O << "[" << getRegisterName(MO1.getReg());
|
||||
|
@ -236,7 +236,7 @@ static bool VerifyLowRegs(MachineInstr *MI) {
|
||||
unsigned Opc = MI->getOpcode();
|
||||
bool isPCOk = (Opc == ARM::t2LDMIA_RET || Opc == ARM::t2LDMIA ||
|
||||
Opc == ARM::t2LDMDB || Opc == ARM::t2LDMIA_UPD ||
|
||||
Opc == ARM::t2LDMDB_UPD);
|
||||
Opc == ARM::t2LDMDB_UPD || Opc == ARM::t2LDRi12);
|
||||
bool isLROk = (Opc == ARM::t2STMIA_UPD || Opc == ARM::t2STMDB_UPD);
|
||||
bool isSPOk = isPCOk || isLROk || (Opc == ARM::t2ADDrSPi);
|
||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||
@ -270,10 +270,12 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||
return false;
|
||||
|
||||
unsigned Scale = 1;
|
||||
bool HasBaseReg = true;
|
||||
bool HasImmOffset = false;
|
||||
bool HasShift = false;
|
||||
bool HasOffReg = true;
|
||||
bool isLdStMul = false;
|
||||
bool InsertImmOffset = true;
|
||||
unsigned Opc = Entry.NarrowOpc1;
|
||||
unsigned OpNum = 3; // First 'rest' of operands.
|
||||
uint8_t ImmLimit = Entry.Imm1Limit;
|
||||
@ -290,17 +292,50 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||
HasOffReg = false;
|
||||
}
|
||||
Scale = 4;
|
||||
HasImmOffset = true;
|
||||
if (MI->getOperand(2).isImm())
|
||||
HasImmOffset = true;
|
||||
else {
|
||||
if (Entry.WideOpc == ARM::t2LDRi12) {
|
||||
Opc = ARM::tLDRpci;
|
||||
OpNum = 2;
|
||||
}
|
||||
HasImmOffset = false;
|
||||
InsertImmOffset = false;
|
||||
HasBaseReg = false;
|
||||
HasOffReg = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARM::t2LDRBi12:
|
||||
case ARM::t2STRBi12:
|
||||
HasImmOffset = true;
|
||||
if (MI->getOperand(2).isImm())
|
||||
HasImmOffset = true;
|
||||
else {
|
||||
if (Entry.WideOpc == ARM::t2LDRBi12) {
|
||||
Opc = ARM::tLDRpci;
|
||||
OpNum = 2;
|
||||
}
|
||||
HasImmOffset = false;
|
||||
InsertImmOffset = false;
|
||||
HasBaseReg = false;
|
||||
HasOffReg = false;
|
||||
}
|
||||
break;
|
||||
case ARM::t2LDRHi12:
|
||||
case ARM::t2STRHi12:
|
||||
Scale = 2;
|
||||
HasImmOffset = true;
|
||||
if (MI->getOperand(2).isImm())
|
||||
HasImmOffset = true;
|
||||
else {
|
||||
if (Entry.WideOpc == ARM::t2LDRHi12) {
|
||||
Opc = ARM::tLDRpci;
|
||||
OpNum = 2;
|
||||
}
|
||||
HasImmOffset = false;
|
||||
InsertImmOffset = false;
|
||||
HasBaseReg = false;
|
||||
HasOffReg = false;
|
||||
}
|
||||
break;
|
||||
case ARM::t2LDRs:
|
||||
case ARM::t2LDRBs:
|
||||
@ -388,8 +423,9 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||
DebugLoc dl = MI->getDebugLoc();
|
||||
MachineInstrBuilder MIB = BuildMI(MBB, *MI, dl, TII->get(Opc));
|
||||
if (!isLdStMul) {
|
||||
MIB.addOperand(MI->getOperand(0)).addOperand(MI->getOperand(1));
|
||||
if (Opc != ARM::tLDRSB && Opc != ARM::tLDRSH) {
|
||||
MIB.addOperand(MI->getOperand(0));
|
||||
if (HasBaseReg) MIB.addOperand(MI->getOperand(1));
|
||||
if (InsertImmOffset && Opc != ARM::tLDRSB && Opc != ARM::tLDRSH) {
|
||||
// tLDRSB and tLDRSH do not have an immediate offset field. On the other
|
||||
// hand, it must have an offset register.
|
||||
// FIXME: Remove this special case.
|
||||
|
@ -27,7 +27,7 @@
|
||||
# CHECK: ldmia r0!, {r1}
|
||||
0x02 0xc8
|
||||
|
||||
# CHECK: ldrb.w r8, #-24
|
||||
# CHECK: ldrb.w r8, [pc, #-24]
|
||||
0x1f 0xf8 0x18 0x80
|
||||
|
||||
# CHECK: ldrd r0, r1, [r7, #64]!
|
||||
|
Loading…
Reference in New Issue
Block a user