Skip to content

[LLVM][TableGen] Parameterize NumToSkip in DecoderEmitter #136187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
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
2 changes: 1 addition & 1 deletion llvm/lib/Target/AArch64/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ tablegen(LLVM AArch64GenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM AArch64GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1)
tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv)
tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel)
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler --num-to-skip-size=3)
tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel)
tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
tablegen(LLVM AArch64GenO0PreLegalizeGICombiner.inc -gen-global-isel-combiner
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
uint32_t Insn =
(Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);

const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
const DecoderTable3Bytes Tables[] = {DecoderTable32, DecoderTableFallback32};

for (const auto *Table : Tables) {
for (const auto Table : Tables) {
DecodeStatus Result =
decodeInstruction(Table, MI, Insn, Address, this, STI);

Expand Down
98 changes: 72 additions & 26 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,47 @@ static DecodeStatus decodeVersionImm(MCInst &Inst, unsigned Imm,
//
//===----------------------------------------------------------------------===//

template <typename InsnType>
static DecodeStatus tryDecodeInst(DecoderTable2Bytes Table, MCInst &MI,
InsnType Inst, uint64_t Address,
raw_ostream &Comments,
const AMDGPUDisassembler *Asm) {
assert(MI.getOpcode() == 0);
assert(MI.getNumOperands() == 0);
MCInst TmpInst;
Asm->setHasLiteral(false);
const auto SavedBytes = Asm->getBytes();

SmallString<64> LocalComments;
raw_svector_ostream LocalCommentStream(LocalComments);
Asm->CommentStream = &LocalCommentStream;

DecodeStatus Res = decodeInstruction(Table, TmpInst, Inst, Address, Asm,
Asm->getSubtargetInfo());

Asm->CommentStream = nullptr;

if (Res != MCDisassembler::Fail) {
MI = TmpInst;
Comments << LocalComments;
return MCDisassembler::Success;
}
Asm->setBytes(SavedBytes);
return MCDisassembler::Fail;
}

template <typename InsnType>
static DecodeStatus
tryDecodeInst(DecoderTable2Bytes Table1, DecoderTable2Bytes Table2, MCInst &MI,
InsnType Inst, uint64_t Address, raw_ostream &Comments,
const AMDGPUDisassembler *Asm) {
for (DecoderTable2Bytes T : {Table1, Table2}) {
if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments, Asm))
return Res;
}
return MCDisassembler::Fail;
}

template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) {
assert(Bytes.size() >= sizeof(T));
const auto Res =
Expand Down Expand Up @@ -539,16 +580,16 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,

if (isGFX11() &&
tryDecodeInst(DecoderTableGFX1196, DecoderTableGFX11_FAKE1696, MI,
DecW, Address, CS))
DecW, Address, CS, this))
break;

if (isGFX12() &&
tryDecodeInst(DecoderTableGFX1296, DecoderTableGFX12_FAKE1696, MI,
DecW, Address, CS))
DecW, Address, CS, this))
break;

if (isGFX12() &&
tryDecodeInst(DecoderTableGFX12W6496, MI, DecW, Address, CS))
tryDecodeInst(DecoderTableGFX12W6496, MI, DecW, Address, CS, this))
break;

// Reinitialize Bytes
Expand All @@ -557,7 +598,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
} else if (Bytes.size() >= 16 &&
STI.hasFeature(AMDGPU::FeatureGFX950Insts)) {
DecoderUInt128 DecW = eat16Bytes(Bytes);
if (tryDecodeInst(DecoderTableGFX940128, MI, DecW, Address, CS))
if (tryDecodeInst(DecoderTableGFX940128, MI, DecW, Address, CS, this))
break;

// Reinitialize Bytes
Expand All @@ -568,58 +609,61 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
const uint64_t QW = eatBytes<uint64_t>(Bytes);

if (STI.hasFeature(AMDGPU::FeatureGFX10_BEncoding) &&
tryDecodeInst(DecoderTableGFX10_B64, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX10_B64, MI, QW, Address, CS, this))
break;

if (STI.hasFeature(AMDGPU::FeatureUnpackedD16VMem) &&
tryDecodeInst(DecoderTableGFX80_UNPACKED64, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX80_UNPACKED64, MI, QW, Address, CS,
this))
break;

if (STI.hasFeature(AMDGPU::FeatureGFX950Insts) &&
tryDecodeInst(DecoderTableGFX95064, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX95064, MI, QW, Address, CS, this))
break;

// Some GFX9 subtargets repurposed the v_mad_mix_f32, v_mad_mixlo_f16 and
// v_mad_mixhi_f16 for FMA variants. Try to decode using this special
// table first so we print the correct name.
if (STI.hasFeature(AMDGPU::FeatureFmaMixInsts) &&
tryDecodeInst(DecoderTableGFX9_DL64, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX9_DL64, MI, QW, Address, CS, this))
break;

if (STI.hasFeature(AMDGPU::FeatureGFX940Insts) &&
tryDecodeInst(DecoderTableGFX94064, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX94064, MI, QW, Address, CS, this))
break;

if (STI.hasFeature(AMDGPU::FeatureGFX90AInsts) &&
tryDecodeInst(DecoderTableGFX90A64, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX90A64, MI, QW, Address, CS, this))
break;

if ((isVI() || isGFX9()) &&
tryDecodeInst(DecoderTableGFX864, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX864, MI, QW, Address, CS, this))
break;

if (isGFX9() && tryDecodeInst(DecoderTableGFX964, MI, QW, Address, CS))
if (isGFX9() &&
tryDecodeInst(DecoderTableGFX964, MI, QW, Address, CS, this))
break;

if (isGFX10() && tryDecodeInst(DecoderTableGFX1064, MI, QW, Address, CS))
if (isGFX10() &&
tryDecodeInst(DecoderTableGFX1064, MI, QW, Address, CS, this))
break;

if (isGFX12() &&
tryDecodeInst(DecoderTableGFX1264, DecoderTableGFX12_FAKE1664, MI, QW,
Address, CS))
Address, CS, this))
break;

if (isGFX11() &&
tryDecodeInst(DecoderTableGFX1164, DecoderTableGFX11_FAKE1664, MI, QW,
Address, CS))
Address, CS, this))
break;

if (isGFX11() &&
tryDecodeInst(DecoderTableGFX11W6464, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX11W6464, MI, QW, Address, CS, this))
break;

if (isGFX12() &&
tryDecodeInst(DecoderTableGFX12W6464, MI, QW, Address, CS))
tryDecodeInst(DecoderTableGFX12W6464, MI, QW, Address, CS, this))
break;

// Reinitialize Bytes
Expand All @@ -631,38 +675,40 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
const uint32_t DW = eatBytes<uint32_t>(Bytes);

if ((isVI() || isGFX9()) &&
tryDecodeInst(DecoderTableGFX832, MI, DW, Address, CS))
tryDecodeInst(DecoderTableGFX832, MI, DW, Address, CS, this))
break;

if (tryDecodeInst(DecoderTableAMDGPU32, MI, DW, Address, CS))
if (tryDecodeInst(DecoderTableAMDGPU32, MI, DW, Address, CS, this))
break;

if (isGFX9() && tryDecodeInst(DecoderTableGFX932, MI, DW, Address, CS))
if (isGFX9() &&
tryDecodeInst(DecoderTableGFX932, MI, DW, Address, CS, this))
break;

if (STI.hasFeature(AMDGPU::FeatureGFX950Insts) &&
tryDecodeInst(DecoderTableGFX95032, MI, DW, Address, CS))
tryDecodeInst(DecoderTableGFX95032, MI, DW, Address, CS, this))
break;

if (STI.hasFeature(AMDGPU::FeatureGFX90AInsts) &&
tryDecodeInst(DecoderTableGFX90A32, MI, DW, Address, CS))
tryDecodeInst(DecoderTableGFX90A32, MI, DW, Address, CS, this))
break;

if (STI.hasFeature(AMDGPU::FeatureGFX10_BEncoding) &&
tryDecodeInst(DecoderTableGFX10_B32, MI, DW, Address, CS))
tryDecodeInst(DecoderTableGFX10_B32, MI, DW, Address, CS, this))
break;

if (isGFX10() && tryDecodeInst(DecoderTableGFX1032, MI, DW, Address, CS))
if (isGFX10() &&
tryDecodeInst(DecoderTableGFX1032, MI, DW, Address, CS, this))
break;

if (isGFX11() &&
tryDecodeInst(DecoderTableGFX1132, DecoderTableGFX11_FAKE1632, MI, DW,
Address, CS))
Address, CS, this))
break;

if (isGFX12() &&
tryDecodeInst(DecoderTableGFX1232, DecoderTableGFX12_FAKE1632, MI, DW,
Address, CS))
Address, CS, this))
break;
}

Expand Down
42 changes: 4 additions & 38 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,44 +128,6 @@ class AMDGPUDisassembler : public MCDisassembler {

MCOperand errOperand(unsigned V, const Twine& ErrMsg) const;

template <typename InsnType>
DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
uint64_t Address, raw_ostream &Comments) const {
assert(MI.getOpcode() == 0);
assert(MI.getNumOperands() == 0);
MCInst TmpInst;
HasLiteral = false;
const auto SavedBytes = Bytes;

SmallString<64> LocalComments;
raw_svector_ostream LocalCommentStream(LocalComments);
CommentStream = &LocalCommentStream;

DecodeStatus Res =
decodeInstruction(Table, TmpInst, Inst, Address, this, STI);

CommentStream = nullptr;

if (Res != Fail) {
MI = TmpInst;
Comments << LocalComments;
return MCDisassembler::Success;
}
Bytes = SavedBytes;
return MCDisassembler::Fail;
}

template <typename InsnType>
DecodeStatus tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
MCInst &MI, InsnType Inst, uint64_t Address,
raw_ostream &Comments) const {
for (const uint8_t *T : {Table1, Table2}) {
if (DecodeStatus Res = tryDecodeInst(T, MI, Inst, Address, Comments))
return Res;
}
return MCDisassembler::Fail;
}

Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
uint64_t Address) const override;
Expand Down Expand Up @@ -294,6 +256,10 @@ class AMDGPUDisassembler : public MCDisassembler {
bool hasKernargPreload() const;

bool isMacDPP(MCInst &MI) const;

void setHasLiteral(bool Val) const { HasLiteral = Val; }
void setBytes(ArrayRef<uint8_t> Val) const { Bytes = Val; }
ArrayRef<uint8_t> getBytes() const { return Bytes; }
};

//===----------------------------------------------------------------------===//
Expand Down
19 changes: 7 additions & 12 deletions llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,25 +809,20 @@ DecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
}

struct DecodeTable {
const uint8_t *P;
bool DecodePred;
};

const DecodeTable Tables[] = {
constexpr std::pair<DecoderTable2Bytes, bool> Tables[] = {
{DecoderTableVFP32, false}, {DecoderTableVFPV832, false},
{DecoderTableNEONData32, true}, {DecoderTableNEONLoadStore32, true},
{DecoderTableNEONDup32, true}, {DecoderTablev8NEON32, false},
{DecoderTablev8Crypto32, false},
};

for (auto Table : Tables) {
Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI);
for (auto [Table, DecodePred] : Tables) {
Result = decodeInstruction(Table, MI, Insn, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
// Add a fake predicate operand, because we share these instruction
// definitions with Thumb2 where these instructions are predicable.
if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
if (DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
return MCDisassembler::Fail;
return Result;
}
Expand Down Expand Up @@ -1254,9 +1249,9 @@ DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
}

uint32_t Coproc = fieldFromInstruction(Insn32, 8, 4);
const uint8_t *DecoderTable = ARM::isCDECoproc(Coproc, STI)
? DecoderTableThumb2CDE32
: DecoderTableThumb2CoProc32;
const auto DecoderTable = ARM::isCDECoproc(Coproc, STI)
? DecoderTableThumb2CDE32
: DecoderTableThumb2CoProc32;
Result =
decodeInstruction(DecoderTable, MI, Insn32, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,7 @@ static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
return MCDisassembler::Success;
}

static const uint8_t *getDecoderTable(uint64_t Size) {

static DecoderTable2Bytes getDecoderTable(uint64_t Size) {
switch (Size) {
case 2:
return DecoderTable16;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ DecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB,
if ((Instruction & HexagonII::INST_PARSE_MASK) ==
HexagonII::INST_PARSE_DUPLEX) {
unsigned duplexIClass;
uint8_t const *DecodeLow, *DecodeHigh;
DecoderTable2Bytes DecodeLow, DecodeHigh;
duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
switch (duplexIClass) {
default:
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ static AddrMode DecodeDstAddrMode(unsigned Insn) {
return Ad ? amIndexed : amRegister;
}

static const uint8_t *getDecoderTable(AddrMode SrcAM, unsigned Words) {
static DecoderTable2Bytes getDecoderTable(AddrMode SrcAM, unsigned Words) {
assert(0 < Words && Words < 4 && "Incorrect number of words");
switch (SrcAM) {
default:
Expand Down Expand Up @@ -308,7 +308,8 @@ DecodeStatus MSP430Disassembler::getInstructionII(MCInst &MI, uint64_t &Size,
break;
}

const uint8_t *DecoderTable = Words == 2 ? DecoderTable32 : DecoderTable16;
DecoderTable2Bytes DecoderTable =
Words == 2 ? DecoderTable32 : DecoderTable16;
DecodeStatus Result = decodeInstruction(DecoderTable, MI, Insn, Address,
this, STI);
if (Result != MCDisassembler::Fail) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ void RISCVDisassembler::addSPOperands(MCInst &MI) const {
namespace {

struct DecoderListEntry {
const uint8_t *Table;
DecoderTable2Bytes Table;
FeatureBitset ContainedFeatures;
const char *Desc;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
return MCDisassembler::Fail;

// The top 2 bits of the first byte specify the size.
const uint8_t *Table;
DecoderTable2Bytes Table;
if (Bytes[0] < 0x40) {
Size = 2;
Table = DecoderTable16;
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/TableGen/VarLenDecoder.td
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def FOO32 : MyVarInst<MemOp32> {
}

// CHECK: MCD::OPC_ExtractField, 3, 5, // Inst{7-3} ...
// CHECK-NEXT: MCD::OPC_FilterValue, 8, 4, 0, 0, // Skip to: 12
// CHECK-NEXT: MCD::OPC_FilterValue, 8, 4, 0, // Skip to: 11
// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16
// CHECK-NEXT: MCD::OPC_FilterValue, 9, 4, 0, 0, // Skip to: 21
// CHECK-NEXT: MCD::OPC_FilterValue, 9, 4, 0, // Skip to: 19
// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32
// CHECK-NEXT: MCD::OPC_Fail,

Expand Down
Loading
Loading