diff options
author | Sergei Barannikov <barannikov88@gmail.com> | 2025-09-23 12:44:29 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-23 09:44:29 +0000 |
commit | b6c061e6a9f4243d31c30c466d6f0268eca69751 (patch) | |
tree | 7ea4f46f97e687c1529dc402aa4bb3903511f00e /llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | |
parent | 10847f526eebe9912226d18ef36f98243b1658c5 (diff) | |
download | llvm-b6c061e6a9f4243d31c30c466d6f0268eca69751.zip llvm-b6c061e6a9f4243d31c30c466d6f0268eca69751.tar.gz llvm-b6c061e6a9f4243d31c30c466d6f0268eca69751.tar.bz2 |
[ARM] Auto-decode s_cc_out operand (#159956)
The operand can be decoded automatically, without the need for
post-decoding instruction modification.
Part of #156540.
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 41 |
1 files changed, 13 insertions, 28 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 5611211..b25b7e7 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -119,6 +119,8 @@ private: 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) @@ -146,10 +148,6 @@ private: 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; @@ -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) { @@ -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) { @@ -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; } @@ -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; } |