Skip to content

Commit b6c061e

Browse files
authored
[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.
1 parent 10847f5 commit b6c061e

File tree

2 files changed

+14
-28
lines changed

2 files changed

+14
-28
lines changed

llvm/lib/Target/ARM/ARMInstrFormats.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,7 @@ class Thumb1sI<dag oops, dag iops, AddrMode am, int sz,
12191219
InstrItinClass itin,
12201220
string opc, string asm, string cstr, list<dag> pattern>
12211221
: InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
1222+
bits<0> s;
12221223
let OutOperandList = !con(oops, (outs s_cc_out:$s));
12231224
let InOperandList = !con(iops, (ins pred:$p));
12241225
let AsmString = !strconcat(opc, "${s}${p}", asm);

llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ class VPTStatus {
119119
class ARMDisassembler : public MCDisassembler {
120120
public:
121121
std::unique_ptr<const MCInstrInfo> MCII;
122+
mutable ITStatus ITBlock;
123+
mutable VPTStatus VPTBlock;
122124

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

149-
mutable ITStatus ITBlock;
150-
mutable VPTStatus VPTBlock;
151-
152-
void AddThumb1SBit(MCInst &MI, bool InITBlock) const;
153151
bool isVectorPredicable(const MCInst &MI) const;
154152
DecodeStatus AddThumbPredicate(MCInst&) const;
155153
void UpdateThumbPredicate(DecodeStatus &S, MCInst &MI) const;
@@ -636,6 +634,17 @@ static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
636634
return MCDisassembler::Success;
637635
}
638636

637+
// This overload is called when decoding `s_cc_out` operand, which is not
638+
// encoded into instruction. It is only used in Thumb1 instructions.
639+
static DecodeStatus DecodeCCOutOperand(MCInst &Inst,
640+
const MCDisassembler *Decoder) {
641+
const auto *D = static_cast<const ARMDisassembler *>(Decoder);
642+
// Thumb1 instructions define CPSR unless they are inside an IT block.
643+
MCRegister CCR = D->ITBlock.instrInITBlock() ? ARM::NoRegister : ARM::CPSR;
644+
Inst.addOperand(MCOperand::createReg(CCR));
645+
return MCDisassembler::Success;
646+
}
647+
639648
static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
640649
uint64_t Address,
641650
const MCDisassembler *Decoder) {
@@ -6130,26 +6139,6 @@ DecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
61306139
return MCDisassembler::Fail;
61316140
}
61326141

6133-
// Thumb1 instructions don't have explicit S bits. Rather, they
6134-
// implicitly set CPSR. Since it's not represented in the encoding, the
6135-
// auto-generated decoder won't inject the CPSR operand. We need to fix
6136-
// that as a post-pass.
6137-
void ARMDisassembler::AddThumb1SBit(MCInst &MI, bool InITBlock) const {
6138-
const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
6139-
MCInst::iterator I = MI.begin();
6140-
for (unsigned i = 0; i < MCID.NumOperands; ++i, ++I) {
6141-
if (I == MI.end()) break;
6142-
if (MCID.operands()[i].isOptionalDef() &&
6143-
MCID.operands()[i].RegClass == ARM::CCRRegClassID) {
6144-
if (i > 0 && MCID.operands()[i - 1].isPredicate())
6145-
continue;
6146-
MI.insert(I,
6147-
MCOperand::createReg(InITBlock ? ARM::NoRegister : ARM::CPSR));
6148-
return;
6149-
}
6150-
}
6151-
}
6152-
61536142
bool ARMDisassembler::isVectorPredicable(const MCInst &MI) const {
61546143
const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
61556144
for (unsigned i = 0; i < MCID.NumOperands; ++i) {
@@ -6343,9 +6332,7 @@ DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
63436332
STI);
63446333
if (Result) {
63456334
Size = 2;
6346-
bool InITBlock = ITBlock.instrInITBlock();
63476335
Check(Result, AddThumbPredicate(MI));
6348-
AddThumb1SBit(MI, InITBlock);
63496336
return Result;
63506337
}
63516338

@@ -6411,9 +6398,7 @@ DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
64116398
decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
64126399
if (Result != MCDisassembler::Fail) {
64136400
Size = 4;
6414-
bool InITBlock = ITBlock.instrInITBlock();
64156401
Check(Result, AddThumbPredicate(MI));
6416-
AddThumb1SBit(MI, InITBlock);
64176402
return Result;
64186403
}
64196404

0 commit comments

Comments
 (0)