mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-30 07:33:23 +00:00
Get rid of the separate opcodes for the Darwin versions of tBL, tBLXi, and tBLXr, using pseudo-instructions to lower to the single final opcode. Update the ARM disassembler for this change.
llvm-svn: 135319
This commit is contained in:
parent
a44add3a49
commit
cd207640a2
@ -390,8 +390,8 @@ let isCall = 1,
|
||||
Uses = [SP] in {
|
||||
// Also used for Thumb2
|
||||
def tBL : TIx2<0b11110, 0b11, 1,
|
||||
(outs), (ins t_bltarget:$func, variable_ops), IIC_Br,
|
||||
"bl\t$func",
|
||||
(outs), (ins pred:$p, t_bltarget:$func, variable_ops), IIC_Br,
|
||||
"bl${p}\t$func",
|
||||
[(ARMtcall tglobaladdr:$func)]>,
|
||||
Requires<[IsThumb, IsNotDarwin]> {
|
||||
bits<21> func;
|
||||
@ -403,8 +403,8 @@ let isCall = 1,
|
||||
|
||||
// ARMv5T and above, also used for Thumb2
|
||||
def tBLXi : TIx2<0b11110, 0b11, 0,
|
||||
(outs), (ins t_blxtarget:$func, variable_ops), IIC_Br,
|
||||
"blx\t$func",
|
||||
(outs), (ins pred:$p, t_blxtarget:$func, variable_ops), IIC_Br,
|
||||
"blx${p}\t$func",
|
||||
[(ARMcall tglobaladdr:$func)]>,
|
||||
Requires<[IsThumb, HasV5T, IsNotDarwin]> {
|
||||
bits<21> func;
|
||||
@ -416,8 +416,8 @@ let isCall = 1,
|
||||
}
|
||||
|
||||
// Also used for Thumb2
|
||||
def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br,
|
||||
"blx\t$func",
|
||||
def tBLXr : TI<(outs), (ins pred:$p, GPR:$func, variable_ops), IIC_Br,
|
||||
"blx${p}\t$func",
|
||||
[(ARMtcall GPR:$func)]>,
|
||||
Requires<[IsThumb, HasV5T, IsNotDarwin]>,
|
||||
T1Special<{1,1,1,?}> { // A6.2.3 & A8.6.24;
|
||||
@ -440,43 +440,22 @@ let isCall = 1,
|
||||
Defs = [R0, R1, R2, R3, R9, R12, LR, QQQQ0, QQQQ2, QQQQ3, CPSR, FPSCR],
|
||||
Uses = [R7, SP] in {
|
||||
// Also used for Thumb2
|
||||
def tBLr9 : TIx2<0b11110, 0b11, 1,
|
||||
(outs), (ins pred:$p, t_bltarget:$func, variable_ops),
|
||||
IIC_Br, "bl${p}\t$func",
|
||||
[(ARMtcall tglobaladdr:$func)]>,
|
||||
Requires<[IsThumb, IsDarwin]> {
|
||||
bits<21> func;
|
||||
let Inst{25-16} = func{20-11};
|
||||
let Inst{13} = 1;
|
||||
let Inst{11} = 1;
|
||||
let Inst{10-0} = func{10-0};
|
||||
}
|
||||
def tBLr9 : tPseudoExpand<(outs), (ins pred:$p, t_bltarget:$func, variable_ops),
|
||||
4, IIC_Br, [(ARMtcall tglobaladdr:$func)],
|
||||
(tBL pred:$p, t_bltarget:$func)>,
|
||||
Requires<[IsThumb, IsDarwin]>;
|
||||
|
||||
// ARMv5T and above, also used for Thumb2
|
||||
def tBLXi_r9 : TIx2<0b11110, 0b11, 0,
|
||||
(outs), (ins pred:$p, t_blxtarget:$func, variable_ops),
|
||||
IIC_Br, "blx${p}\t$func",
|
||||
[(ARMcall tglobaladdr:$func)]>,
|
||||
Requires<[IsThumb, HasV5T, IsDarwin]> {
|
||||
bits<21> func;
|
||||
let Inst{25-16} = func{20-11};
|
||||
let Inst{13} = 1;
|
||||
let Inst{11} = 1;
|
||||
let Inst{10-1} = func{10-1};
|
||||
let Inst{0} = 0; // func{0} is assumed zero
|
||||
}
|
||||
def tBLXi_r9 : tPseudoExpand<(outs), (ins pred:$p, t_blxtarget:$func, variable_ops),
|
||||
4, IIC_Br, [(ARMcall tglobaladdr:$func)],
|
||||
(tBLXi pred:$p, t_blxtarget:$func)>,
|
||||
Requires<[IsThumb, HasV5T, IsDarwin]>;
|
||||
|
||||
// Also used for Thumb2
|
||||
def tBLXr_r9 : TI<(outs), (ins pred:$p, GPR:$func, variable_ops), IIC_Br,
|
||||
"blx${p}\t$func",
|
||||
[(ARMtcall GPR:$func)]>,
|
||||
Requires<[IsThumb, HasV5T, IsDarwin]>,
|
||||
T1Special<{1,1,1,?}> {
|
||||
// A6.2.3 & A8.6.24
|
||||
bits<4> func;
|
||||
let Inst{6-3} = func;
|
||||
let Inst{2-0} = 0b000;
|
||||
}
|
||||
def tBLXr_r9 : tPseudoExpand<(outs), (ins pred:$p, GPR:$func, variable_ops),
|
||||
2, IIC_Br, [(ARMtcall GPR:$func)],
|
||||
(tBLXr pred:$p, GPR:$func)>,
|
||||
Requires<[IsThumb, HasV5T, IsDarwin]>;
|
||||
|
||||
// ARMv4T
|
||||
def tBXr9_CALL : tPseudoInst<(outs), (ins tGPR:$func, variable_ops),
|
||||
@ -498,8 +477,8 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
||||
// Just a pseudo for a tBL instruction. Needed to let regalloc know about
|
||||
// the clobber of LR.
|
||||
let Defs = [LR] in
|
||||
def tBfar : tPseudoExpand<(outs), (ins t_bltarget:$target),
|
||||
4, IIC_Br, [], (tBL t_bltarget:$target)>;
|
||||
def tBfar : tPseudoExpand<(outs), (ins pred:$p, t_bltarget:$target),
|
||||
4, IIC_Br, [], (tBL pred:$p, t_bltarget:$target)>;
|
||||
|
||||
def tBR_JTr : tPseudoInst<(outs),
|
||||
(ins tGPR:$target, i32imm:$jt, i32imm:$id),
|
||||
|
@ -479,7 +479,7 @@ static bool DisassembleThumb1DP(MCInst &MI, unsigned Opcode, uint32_t insn,
|
||||
// tBX: Rm
|
||||
// tBX_RET: 0 operand
|
||||
// tBX_RET_vararg: Rm
|
||||
// tBLXr_r9: Rm
|
||||
// tBLXr: Rm
|
||||
// tBRIND: Rm
|
||||
static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
|
||||
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
|
||||
@ -489,8 +489,8 @@ static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
|
||||
return true;
|
||||
|
||||
// BX/BLX/tBRIND (indirect branch, i.e, mov pc, Rm) has 1 reg operand: Rm.
|
||||
if (Opcode==ARM::tBLXr_r9 || Opcode==ARM::tBX || Opcode==ARM::tBRIND) {
|
||||
if (Opcode == ARM::tBLXr_r9) {
|
||||
if (Opcode==ARM::tBLXr || Opcode==ARM::tBX || Opcode==ARM::tBRIND) {
|
||||
if (Opcode == ARM::tBLXr) {
|
||||
// Handling the two predicate operands before the reg operand.
|
||||
if (!B->DoPredicateOperands(MI, Opcode, insn, NumOps))
|
||||
return false;
|
||||
@ -1729,7 +1729,7 @@ static inline bool t2MiscCtrlInstr(uint32_t insn) {
|
||||
// Branches: t2TPsoft -> no operand
|
||||
//
|
||||
// A8.6.23 BL, BLX (immediate)
|
||||
// Branches (defined in ARMInstrThumb.td): tBLr9, tBLXi_r9 -> imm operand
|
||||
// Branches (defined in ARMInstrThumb.td): tBL, tBLXi -> imm operand
|
||||
//
|
||||
// A8.6.26
|
||||
// t2BXJ -> Rn
|
||||
@ -1844,7 +1844,7 @@ static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
|
||||
}
|
||||
|
||||
// Some instructions have predicate operands first before the immediate.
|
||||
if (Opcode == ARM::tBLXi_r9 || Opcode == ARM::tBLr9) {
|
||||
if (Opcode == ARM::tBLXi || Opcode == ARM::tBL) {
|
||||
// Handling the two predicate operands before the imm operand.
|
||||
if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
|
||||
NumOpsAdded += 2;
|
||||
@ -1867,10 +1867,10 @@ static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
|
||||
case ARM::t2Bcc:
|
||||
Offset = decodeImm32_B_EncodingT3(insn);
|
||||
break;
|
||||
case ARM::tBLr9:
|
||||
case ARM::tBL:
|
||||
Offset = decodeImm32_BL(insn);
|
||||
break;
|
||||
case ARM::tBLXi_r9:
|
||||
case ARM::tBLXi:
|
||||
Offset = decodeImm32_BLX(insn);
|
||||
break;
|
||||
}
|
||||
|
@ -1619,10 +1619,6 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI,
|
||||
if (Name == "tSTMIA")
|
||||
return false;
|
||||
|
||||
// On Darwin R9 is call-clobbered. Ignore the non-Darwin counterparts.
|
||||
if (Name == "tBL" || Name == "tBLXi" || Name == "tBLXr")
|
||||
return false;
|
||||
|
||||
// A8.6.25 BX. Use the generic tBX_Rm, ignore tBX_RET and tBX_RET_vararg.
|
||||
if (Name == "tBX_RET" || Name == "tBX_RET_vararg")
|
||||
return false;
|
||||
@ -1654,14 +1650,12 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI,
|
||||
|
||||
// Resolve conflicts:
|
||||
//
|
||||
// tBfar conflicts with tBLr9
|
||||
// t2LDMIA_RET conflict with t2LDM (ditto)
|
||||
// tMOVCCi conflicts with tMOVi8
|
||||
// tMOVCCr conflicts with tMOVgpr2gpr
|
||||
// tLDRcp conflicts with tLDRspi
|
||||
// t2MOVCCi16 conflicts with tMOVi16
|
||||
if (Name == "tBfar" ||
|
||||
Name == "t2LDMIA_RET" ||
|
||||
if (Name == "t2LDMIA_RET" ||
|
||||
Name == "tMOVCCi" || Name == "tMOVCCr" ||
|
||||
Name == "tLDRcp" ||
|
||||
Name == "t2MOVCCi16")
|
||||
|
Loading…
Reference in New Issue
Block a user