Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/lib/Target/ARM/ARMInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,7 @@ class Thumb1sI<dag oops, dag iops, AddrMode am, int sz,
InstrItinClass itin,
string opc, string asm, string cstr, list<dag> pattern>
: InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
bits<0> s;
let OutOperandList = !con(oops, (outs s_cc_out:$s));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(opc, "${s}${p}", asm);
Expand Down
41 changes: 13 additions & 28 deletions llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ class VPTStatus {
class ARMDisassembler : public MCDisassembler {
public:
std::unique_ptr<const MCInstrInfo> MCII;
mutable ITStatus ITBlock;
mutable VPTStatus VPTBlock;

ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
const MCInstrInfo *MCII)
Expand Down Expand Up @@ -146,10 +148,6 @@ class ARMDisassembler : public MCDisassembler {
ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &CStream) const;

mutable ITStatus ITBlock;
mutable VPTStatus VPTBlock;

void AddThumb1SBit(MCInst &MI, bool InITBlock) const;
bool isVectorPredicable(const MCInst &MI) const;
DecodeStatus AddThumbPredicate(MCInst&) const;
void UpdateThumbPredicate(DecodeStatus &S, MCInst &MI) const;
Expand Down Expand Up @@ -636,6 +634,17 @@ static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
return MCDisassembler::Success;
}

// This overload is called when decoding `s_cc_out` operand, which is not
// encoded into instruction. It is only used in Thumb1 instructions.
static DecodeStatus DecodeCCOutOperand(MCInst &Inst,
const MCDisassembler *Decoder) {
const auto *D = static_cast<const ARMDisassembler *>(Decoder);
// Thumb1 instructions define CPSR unless they are inside an IT block.
MCRegister CCR = D->ITBlock.instrInITBlock() ? ARM::NoRegister : ARM::CPSR;
Inst.addOperand(MCOperand::createReg(CCR));
return MCDisassembler::Success;
}

static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
uint64_t Address,
const MCDisassembler *Decoder) {
Expand Down Expand Up @@ -6130,26 +6139,6 @@ DecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
return MCDisassembler::Fail;
}

// Thumb1 instructions don't have explicit S bits. Rather, they
// implicitly set CPSR. Since it's not represented in the encoding, the
// auto-generated decoder won't inject the CPSR operand. We need to fix
// that as a post-pass.
void ARMDisassembler::AddThumb1SBit(MCInst &MI, bool InITBlock) const {
const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
MCInst::iterator I = MI.begin();
for (unsigned i = 0; i < MCID.NumOperands; ++i, ++I) {
if (I == MI.end()) break;
if (MCID.operands()[i].isOptionalDef() &&
MCID.operands()[i].RegClass == ARM::CCRRegClassID) {
if (i > 0 && MCID.operands()[i - 1].isPredicate())
continue;
MI.insert(I,
MCOperand::createReg(InITBlock ? ARM::NoRegister : ARM::CPSR));
return;
}
}
}

bool ARMDisassembler::isVectorPredicable(const MCInst &MI) const {
const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
for (unsigned i = 0; i < MCID.NumOperands; ++i) {
Expand Down Expand Up @@ -6343,9 +6332,7 @@ DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
STI);
if (Result) {
Size = 2;
bool InITBlock = ITBlock.instrInITBlock();
Check(Result, AddThumbPredicate(MI));
AddThumb1SBit(MI, InITBlock);
return Result;
}

Expand Down Expand Up @@ -6411,9 +6398,7 @@ DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
bool InITBlock = ITBlock.instrInITBlock();
Check(Result, AddThumbPredicate(MI));
AddThumb1SBit(MI, InITBlock);
return Result;
}

Expand Down