From cd207640a29f499d7fa5128516bdc28a38bfaaa9 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 15 Jul 2011 22:49:31 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMInstrThumb.td | 61 ++++++------------- .../ARM/Disassembler/ThumbDisassemblerCore.h | 14 ++--- utils/TableGen/ARMDecoderEmitter.cpp | 8 +-- 3 files changed, 28 insertions(+), 55 deletions(-) diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index bfe83eceb13..0a13a3ab6af 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -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), diff --git a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h index 834c6f65295..9c3ebca52cf 100644 --- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h +++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h @@ -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; } diff --git a/utils/TableGen/ARMDecoderEmitter.cpp b/utils/TableGen/ARMDecoderEmitter.cpp index 8a5dc8ba154..2902af44740 100644 --- a/utils/TableGen/ARMDecoderEmitter.cpp +++ b/utils/TableGen/ARMDecoderEmitter.cpp @@ -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")