Revamp our handling of tLDMIA[_UPD] and tSTMIA[_UPD] to avoid having multiple instructions with the same encoding. This resolves another conflict when bringing up the new-style disassembler.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135442 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson 2011-07-18 23:25:34 +00:00
parent c8c3acfea4
commit 565a036697
4 changed files with 40 additions and 17 deletions

View File

@ -717,7 +717,7 @@ def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i,
multiclass thumb_ldst_mult<string asm, InstrItinClass itin,
InstrItinClass itin_upd, bits<6> T1Enc,
bit L_bit> {
bit L_bit, string baseOpc> {
def IA :
T1I<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
itin, !strconcat(asm, "ia${p}\t$Rn, $regs"), []>,
@ -727,14 +727,19 @@ multiclass thumb_ldst_mult<string asm, InstrItinClass itin,
let Inst{10-8} = Rn;
let Inst{7-0} = regs;
}
def IA_UPD :
T1It<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
itin_upd, !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []>,
T1Encoding<T1Enc> {
bits<3> Rn;
bits<8> regs;
let Inst{10-8} = Rn;
let Inst{7-0} = regs;
InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
"$Rn = $wb", itin_upd>,
PseudoInstExpansion<(!cast<Instruction>(!strconcat(baseOpc, "IA"))
GPR:$Rn, pred:$p, reglist:$regs)> {
let Size = 2;
let OutOperandList = (outs GPR:$wb);
let InOperandList = (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops);
let Pattern = [];
let isCodeGenOnly = 1;
let isPseudo = 1;
list<Predicate> Predicates = [IsThumb];
}
}
@ -743,11 +748,11 @@ let neverHasSideEffects = 1 in {
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
defm tLDM : thumb_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu,
{1,1,0,0,1,?}, 1>;
{1,1,0,0,1,?}, 1, "tLDM">;
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
defm tSTM : thumb_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu,
{1,1,0,0,0,?}, 0>;
{1,1,0,0,0,?}, 0, "tSTM">;
} // neverHasSideEffects

View File

@ -891,8 +891,8 @@ static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
uint32_t insn, unsigned short NumOps,
unsigned &NumOpsAdded, BO B) {
assert((Opcode == ARM::tLDMIA || Opcode == ARM::tLDMIA_UPD ||
Opcode == ARM::tSTMIA_UPD) && "Unexpected opcode");
assert((Opcode == ARM::tLDMIA || Opcode == ARM::tSTMIA) &&
"Unexpected opcode");
unsigned tRt = getT1tRt(insn);
NumOpsAdded = 0;

View File

@ -109,6 +109,29 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
return;
}
if (Opcode == ARM::tLDMIA || Opcode == ARM::tSTMIA) {
bool Writeback = true;
unsigned BaseReg = MI->getOperand(0).getReg();
for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
if (MI->getOperand(i).getReg() == BaseReg)
Writeback = false;
}
if (Opcode == ARM::tLDMIA)
O << "\tldmia";
else if (Opcode == ARM::tSTMIA)
O << "\tstmia";
else
llvm_unreachable("Unknown opcode!");
printPredicateOperand(MI, 1, O);
O << '\t' << getRegisterName(BaseReg);
if (Writeback) O << "!";
O << ", ";
printRegisterList(MI, 3, O);
return;
}
printInstruction(MI, O);
}

View File

@ -1614,11 +1614,6 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI,
if (!thumbInstruction(Form))
return false;
// A8.6.189 STM / STMIA / STMEA -- Encoding T1
// There's only STMIA_UPD for Thumb1.
if (Name == "tSTMIA")
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;