Skip to content
Draft
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/include/llvm/MC/MCDecoderOps.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace llvm::MCD {
// enabled.
enum DecoderOps {
OPC_Scope = 1, // OPC_Scope(nts_t NumToSkip)
OPC_ScopeNoFail, // OPC_ScopeNoFail(nts_t NumToSkip)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC it shouldn't exist. If the scope can fall through, it is equivalent to having no scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above, maybe what needs to happen in TryDecode/Decode need to be non-terminal when under a scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@jurahul jurahul Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking that itself will help eliminate the AArch64 Fallback and AMDGPU Fake16 namespaces.

OPC_ExtractField, // OPC_ExtractField(uleb128 Start, uint8_t Len)
OPC_FilterValueOrSkip, // OPC_FilterValueOrSkip(uleb128 Val, nts_t NumToSkip)
OPC_FilterValue, // OPC_FilterValue(uleb128 Val)
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Target/Target.td
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,10 @@ class InstructionEncoding {
// where multiple ISA namespaces exist).
string DecoderNamespace = "";

// Within a namespace, DecodeOrder is used to order instructions when we need
// to attempt multiple encoding.
int DecodeOrder = 0;

// List of predicates which will be turned into isel matching code.
list<Predicate> Predicates = [];

Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Target/AArch64/AArch64InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@ class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
"mrs", "\t$Rt, $systemreg"> {
bits<16> systemreg;
let Inst{20-5} = systemreg;
let DecoderNamespace = "Fallback";
let DecodeOrder = 1;
// The MRS is set as a NZCV setting instruction. Not all MRS instructions
// require doing this. The alternative was to explicitly model each one, but
// it feels like it is unnecessary because it seems there are no negative
Expand All @@ -1972,7 +1972,7 @@ class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
"msr", "\t$systemreg, $Rt"> {
bits<16> systemreg;
let Inst{20-5} = systemreg;
let DecoderNamespace = "Fallback";
let DecodeOrder = 1;
}

def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
Expand Down Expand Up @@ -2045,7 +2045,8 @@ class MSRpstateImm0_1
// MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
// Fail the decoder should attempt to decode the instruction as MSRI.
let hasCompleteDecoder = false;
let DecoderNamespace = "Fallback";
let DecodeOrder = 1;

}

// SYS and SYSL generic system instructions.
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -10712,8 +10712,8 @@ def RPRFM:
let hasSideEffects = 1;
// RPRFM overlaps with PRFM (reg), when the decoder method of PRFM returns
// Fail, the decoder should attempt to decode RPRFM. This requires setting
// the decoder namespace to "Fallback".
let DecoderNamespace = "Fallback";
// the decode order for RPRFM to be 1 ( > decode order for PRFM).
let DecodeOrder = 1;
}

//===----------------------------------------------------------------------===//
Expand Down
62 changes: 28 additions & 34 deletions llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1578,43 +1578,37 @@ 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};

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

const MCInstrDesc &Desc = MCII->get(MI.getOpcode());

// For Scalable Matrix Extension (SME) instructions that have an implicit
// operand for the accumulator (ZA) or implicit immediate zero which isn't
// encoded, manually insert operand.
for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
switch (Desc.operands()[i].RegClass) {
default:
break;
case AArch64::MPRRegClassID:
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
break;
case AArch64::MPR8RegClassID:
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
break;
case AArch64::ZTRRegClassID:
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
break;
}
} else if (Desc.operands()[i].OperandType ==
AArch64::OPERAND_IMPLICIT_IMM_0) {
MI.insert(MI.begin() + i, MCOperand::createImm(0));
DecodeStatus Result =
decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
if (Result != Success)
return Result;

const MCInstrDesc &Desc = MCII->get(MI.getOpcode());

// For Scalable Matrix Extension (SME) instructions that have an implicit
// operand for the accumulator (ZA) or implicit immediate zero which isn't
// encoded, manually insert operand.
for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
switch (Desc.operands()[i].RegClass) {
default:
break;
case AArch64::MPRRegClassID:
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
break;
case AArch64::MPR8RegClassID:
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
break;
case AArch64::ZTRRegClassID:
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
break;
}
} else if (Desc.operands()[i].OperandType ==
AArch64::OPERAND_IMPLICIT_IMM_0) {
MI.insert(MI.begin() + i, MCOperand::createImm(0));
}

if (Result != MCDisassembler::Fail)
return Result;
}

return MCDisassembler::Fail;
return Success;
}

uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
Expand Down
43 changes: 9 additions & 34 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,18 +487,6 @@ DecodeStatus AMDGPUDisassembler::tryDecodeInst(const uint8_t *Table, MCInst &MI,
return MCDisassembler::Fail;
}

template <typename InsnType>
DecodeStatus
AMDGPUDisassembler::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;
}

template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) {
assert(Bytes.size() >= sizeof(T));
const auto Res =
Expand Down Expand Up @@ -617,18 +605,15 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
std::bitset<96> DecW = eat12Bytes(Bytes);

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

if (isGFX1250() &&
tryDecodeInst(DecoderTableGFX125096, DecoderTableGFX1250_FAKE1696, MI,
DecW, Address, CS))
tryDecodeInst(DecoderTableGFX125096, MI, DecW, Address, CS))
break;

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

if (isGFX12() &&
Expand Down Expand Up @@ -698,18 +683,13 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
break;

if (isGFX1250() &&
tryDecodeInst(DecoderTableGFX125064, DecoderTableGFX1250_FAKE1664, MI,
QW, Address, CS))
tryDecodeInst(DecoderTableGFX125064, MI, QW, Address, CS))
break;

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

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

if (isGFX11() &&
Expand Down Expand Up @@ -753,19 +733,14 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
if (isGFX10() && tryDecodeInst(DecoderTableGFX1032, MI, DW, Address, CS))
break;

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

if (isGFX1250() &&
tryDecodeInst(DecoderTableGFX125032, DecoderTableGFX1250_FAKE1632, MI,
DW, Address, CS))
tryDecodeInst(DecoderTableGFX125032, MI, DW, Address, CS))
break;

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

Expand Down
4 changes: 0 additions & 4 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ class AMDGPUDisassembler : public MCDisassembler {
template <typename InsnType>
DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, InsnType Inst,
uint64_t Address, raw_ostream &Comments) const;
template <typename InsnType>
DecodeStatus tryDecodeInst(const uint8_t *Table1, const uint8_t *Table2,
MCInst &MI, InsnType Inst, uint64_t Address,
raw_ostream &Comments) const;

Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/Target/AMDGPU/VINTERPInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,9 @@ defm : VInterpF16Pat<int_amdgcn_interp_p2_rtz_f16,

multiclass VINTERP_Real_gfx11 <bits<7> op, string asmName> {
defvar ps = !cast<VOP3_Pseudo>(NAME);
let AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11" #
!if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in {
let AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11",
// When decoding, attempt decoding IsRealTrue16 first, then the fake one.
DecodeOrder = !if(ps.Pfl.IsRealTrue16, 0, 1) in {
def _gfx11 :
VINTERP_Real<ps, SIEncodingFamily.GFX11, asmName>,
VINTERPe_gfx11<op, ps.Pfl>;
Expand All @@ -249,8 +250,9 @@ multiclass VINTERP_Real_gfx11 <bits<7> op, string asmName> {

multiclass VINTERP_Real_gfx12 <bits<7> op, string asmName> {
defvar ps = !cast<VOP3_Pseudo>(NAME);
let AssemblerPredicate = isGFX12Only, DecoderNamespace = "GFX12" #
!if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in {
let AssemblerPredicate = isGFX12Only, DecoderNamespace = "GFX12",
// When decoding, attempt decoding IsRealTrue16 first, then the fake one.
DecodeOrder = !if(ps.Pfl.IsRealTrue16, 0, 1) in {
def _gfx12 :
VINTERP_Real<ps, SIEncodingFamily.GFX12, asmName>,
VINTERPe_gfx12<op, ps.Pfl>;
Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/Target/AMDGPU/VOP1Instructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -940,8 +940,8 @@ multiclass VOP1_Real_e32_with_name<GFXGen Gen, bits<9> op, string opName,
string asmName> {
defvar ps = !cast<VOP1_Pseudo>(opName#"_e32");
let AsmString = asmName # ps.AsmOperands,
DecoderNamespace = Gen.DecoderNamespace #
!if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in {
DecoderNamespace = Gen.DecoderNamespace,
DecodeOrder = !if(ps.Pfl.IsRealTrue16, 0, 1) in {
defm NAME : VOP1_Real_e32<Gen, op, opName>;
}
}
Expand All @@ -961,8 +961,8 @@ multiclass VOP1_Real_dpp_with_name<GFXGen Gen, bits<9> op, string opName,
string asmName> {
defvar ps = !cast<VOP1_Pseudo>(opName#"_e32");
let AsmString = asmName # ps.Pfl.AsmDPP16,
DecoderNamespace = Gen.DecoderNamespace #
!if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in {
DecoderNamespace = Gen.DecoderNamespace,
DecodeOrder = !if(ps.Pfl.IsRealTrue16, 0, 1) in {
defm NAME : VOP1_Real_dpp<Gen, op, opName>;
}
}
Expand All @@ -977,8 +977,8 @@ multiclass VOP1_Real_dpp8_with_name<GFXGen Gen, bits<9> op, string opName,
string asmName> {
defvar ps = !cast<VOP1_Pseudo>(opName#"_e32");
let AsmString = asmName # ps.Pfl.AsmDPP8,
DecoderNamespace = Gen.DecoderNamespace #
!if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in {
DecoderNamespace = Gen.DecoderNamespace,
DecodeOrder = !if(ps.Pfl.IsRealTrue16, 0, 1) in {
if !not(ps.Pfl.HasExt64BitDPP) then
defm NAME : VOP1_Real_dpp8<Gen, op, opName>;
}
Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/Target/AMDGPU/VOP2Instructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ class VOP2_Real_Gen <VOP2_Pseudo ps, GFXGen Gen, string real_name = ps.Mnemonic>
VOP2_Real <ps, Gen.Subtarget, real_name> {
let AssemblerPredicate = Gen.AssemblerPredicate;
let True16Predicate = !if(ps.Pfl.IsRealTrue16, UseRealTrue16Insts, NoTrue16Predicate);
let DecoderNamespace = Gen.DecoderNamespace#
!if(ps.Pfl.IsRealTrue16, "", "_FAKE16");
let DecoderNamespace = Gen.DecoderNamespace;
let DecodeOrder = !if(ps.Pfl.IsRealTrue16, 0, 1);
}

class VOP2_SDWA_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[]> :
Expand Down Expand Up @@ -1517,8 +1517,8 @@ class VOP2_DPP16_Gen<bits<6> op, VOP2_DPP_Pseudo ps, GFXGen Gen,
VOP2_DPP16<op, ps, Gen.Subtarget, opName, p> {
let AssemblerPredicate = Gen.AssemblerPredicate;
let True16Predicate = !if(ps.Pfl.IsRealTrue16, UseRealTrue16Insts, NoTrue16Predicate);
let DecoderNamespace = Gen.DecoderNamespace#
!if(ps.Pfl.IsRealTrue16, "", "_FAKE16");
let DecoderNamespace = Gen.DecoderNamespace;
let DecodeOrder = !if(ps.Pfl.IsRealTrue16, 0, 1);
}

class VOP2_DPP8<bits<6> op, VOP2_Pseudo ps,
Expand Down Expand Up @@ -1547,8 +1547,8 @@ class VOP2_DPP8_Gen<bits<6> op, VOP2_Pseudo ps, GFXGen Gen,
VOP2_DPP8<op, ps, p> {
let AssemblerPredicate = Gen.AssemblerPredicate;
let True16Predicate = !if(ps.Pfl.IsRealTrue16, UseRealTrue16Insts, NoTrue16Predicate);
let DecoderNamespace = Gen.DecoderNamespace#
!if(ps.Pfl.IsRealTrue16, "", "_FAKE16");
let DecoderNamespace = Gen.DecoderNamespace;
let DecodeOrder = !if(ps.Pfl.IsRealTrue16, 0, 1);
}

//===----------------------------------------------------------------------===//
Expand Down
11 changes: 7 additions & 4 deletions llvm/lib/Target/AMDGPU/VOPCInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ class VOPCInstAlias <VOP3_Pseudo ps, Instruction inst,
let SubtargetPredicate = AssemblerPredicate;

string DecoderNamespace; // dummy
int DecodeOrder; // dummy
}

multiclass VOPCInstAliases <string old_name, string Arch, string real_name = old_name, string mnemonic_from = real_name> {
Expand Down Expand Up @@ -1677,7 +1678,8 @@ multiclass VOPC_Real_with_name<GFXGen Gen, bits<9> op, string OpName,
pseudo_mnemonic),
asm_name, ps64.AsmVariantName>;

let DecoderNamespace = Gen.DecoderNamespace # !if(ps32.Pfl.IsRealTrue16, "", "_FAKE16") in {
let DecoderNamespace = Gen.DecoderNamespace,
DecodeOrder = !if(ps32.Pfl.IsRealTrue16, 0, 1) in {
def _e32#Gen.Suffix :
// 32 and 64 bit forms of the instruction have _e32 and _e64
// respectively appended to their assembly mnemonic.
Expand Down Expand Up @@ -1753,7 +1755,7 @@ multiclass VOPC_Real_with_name<GFXGen Gen, bits<9> op, string OpName,
def _e64_dpp8#Gen.Suffix : VOPC64_DPP8_Dst<{0, op}, ps64, asm_name>;
}
} // end if ps64.Pfl.HasExtVOP3DPP
} // End DecoderNamespace
} // End DecoderOrder
} // End AssemblerPredicate
}

Expand Down Expand Up @@ -1824,7 +1826,8 @@ multiclass VOPCX_Real_with_name<GFXGen Gen, bits<9> op, string OpName,
pseudo_mnemonic),
asm_name, ps64.AsmVariantName>;

let DecoderNamespace = Gen.DecoderNamespace # !if(ps32.Pfl.IsRealTrue16, "", "_FAKE16") in {
let DecoderNamespace = Gen.DecoderNamespace,
DecodeOrder = !if(ps32.Pfl.IsRealTrue16, 0, 1) in {
def _e32#Gen.Suffix
: VOPC_Real<ps32, Gen.Subtarget, asm_name>,
VOPCe<op{7-0}> {
Expand Down Expand Up @@ -1880,7 +1883,7 @@ multiclass VOPCX_Real_with_name<GFXGen Gen, bits<9> op, string OpName,
}
}
} // End if ps64.Pfl.HasExtVOP3DPP
} // End DecoderNamespace
} // End DecodeOrder
} // End AssemblerPredicate
}

Expand Down
Loading