diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index d05997cacba0a..9c70d01abe225 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -453,6 +453,29 @@ DECODE_SDWA(Src32) DECODE_SDWA(Src16) DECODE_SDWA(VopcDst) +// The 3-bit SDWA sel fields only define values up to DWORD; 7 is reserved. +static DecodeStatus decodeSDWASel(MCInst &Inst, unsigned Imm, + uint64_t /* Addr */, + const MCDisassembler * /* Decoder */) { + using namespace AMDGPU::SDWA; + + if (Imm > SdwaSel::DWORD) + return MCDisassembler::Fail; + return addOperand(Inst, MCOperand::createImm(Imm)); +} + +// The 2-bit SDWA dst_unused field only defines values up to UNUSED_PRESERVE; +// 3 is reserved. +static DecodeStatus decodeSDWADstUnused(MCInst &Inst, unsigned Imm, + uint64_t /* Addr */, + const MCDisassembler * /* Decoder */) { + using namespace AMDGPU::SDWA; + + if (Imm > DstUnused::UNUSED_PRESERVE) + return MCDisassembler::Fail; + return addOperand(Inst, MCOperand::createImm(Imm)); +} + static DecodeStatus decodeVersionImm(MCInst &Inst, unsigned Imm, uint64_t /* Addr */, const MCDisassembler *Decoder) { diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index 5baf52dd12407..1f05bf8961f3b 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -1247,6 +1247,7 @@ class SDWAOperand let ParserMethod = "[this](OperandVector &Operands) -> ParseStatus { "# "return parseSDWASel(Operands, \""#Id#"\", AMDGPUOperand::"#ImmTy#"); }"; + let DecoderMethod = "decodeSDWASel"; } class ArrayOperand0 @@ -1312,7 +1313,9 @@ def Dim : CustomOperand; def dst_sel : SDWAOperand<"dst_sel", "SDWADstSel">; def src0_sel : SDWAOperand<"src0_sel", "SDWASrc0Sel">; def src1_sel : SDWAOperand<"src1_sel", "SDWASrc1Sel">; -def dst_unused : CustomOperand<1, "SDWADstUnused">; +def dst_unused : CustomOperand<1, "SDWADstUnused"> { + let DecoderMethod = "decodeSDWADstUnused"; +} def op_sel0 : ArrayOperand0<"op_sel", "OpSel">; def op_sel_hi0 : ArrayOperand0<"op_sel_hi", "OpSelHi">; diff --git a/llvm/test/MC/Disassembler/AMDGPU/decode-err.txt b/llvm/test/MC/Disassembler/AMDGPU/decode-err.txt index de9bf7bac9548..b4b65d029ce19 100644 --- a/llvm/test/MC/Disassembler/AMDGPU/decode-err.txt +++ b/llvm/test/MC/Disassembler/AMDGPU/decode-err.txt @@ -61,6 +61,20 @@ # GFX1250-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding 0xfc,0x0e,0x80,0xbe +# These are v_add_f32_sdwa with a reserved value in one of the SDWA fields: +# 7 in a 3-bit sel field and 3 in the 2-bit dst_unused field. +# GCN-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding +0xf9,0x04,0x00,0x02,0x01,0x07,0x06,0x06 + +# GCN-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding +0xf9,0x04,0x00,0x02,0x01,0x1e,0x06,0x06 + +# GCN-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding +0xf9,0x04,0x00,0x02,0x01,0x06,0x07,0x06 + +# GCN-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding +0xf9,0x04,0x00,0x02,0x01,0x06,0x06,0x07 + # W32: v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 0xaf123456 ; encoding: [0xff,0x04,0x02,0xc9,0x03,0x03,0x06,0x05,0x56,0x34,0x12,0xaf] # W64: [[@LINE+1]]:1: warning: invalid instruction encoding 0xff,0x04,0x02,0xc9,0x03,0x03,0x06,0x05,0x56,0x34,0x12,0xaf