Index: llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -6402,7 +6402,8 @@ using namespace llvm::AMDGPU::SendMsg; Msg.Loc = getLoc(); - if (isToken(AsmToken::Identifier) && (Msg.Id = getMsgId(getTokenStr())) >= 0) { + if (isToken(AsmToken::Identifier) && + (Msg.Id = getMsgId(getTokenStr(), getSTI())) != OPR_ID_UNKNOWN) { Msg.IsSymbolic = true; lex(); // skip message name } else if (!parseExpr(Msg.Id, "a message name")) { @@ -6441,9 +6442,16 @@ // only encoding possibility is checked. bool Strict = Msg.IsSymbolic; - if (!isValidMsgId(Msg.Id, getSTI(), Strict)) { - Error(Msg.Loc, "invalid message id"); - return false; + if (Strict) { + if (Msg.Id == OPR_ID_UNSUPPORTED) { + Error(Msg.Loc, "specified message id is not supported on this GPU"); + return false; + } + } else { + if (!isValidMsgId(Msg.Id)) { + Error(Msg.Loc, "invalid message id"); + return false; + } } if (Strict && (msgRequiresOp(Msg.Id) != Op.IsDefined)) { if (Op.IsDefined) { @@ -6476,7 +6484,7 @@ SMLoc Loc = getLoc(); if (trySkipId("sendmsg", AsmToken::LParen)) { - OperandInfoTy Msg(ID_UNKNOWN_); + OperandInfoTy Msg(OPR_ID_UNKNOWN); OperandInfoTy Op(OP_NONE_); OperandInfoTy Stream(STREAM_ID_NONE_); if (parseSendMsgBody(Msg, Op, Stream) && Index: llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp =================================================================== --- llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp +++ llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp @@ -1266,10 +1266,11 @@ uint16_t StreamId; decodeMsg(Imm16, MsgId, OpId, StreamId); - if (isValidMsgId(MsgId, STI) && - isValidMsgOp(MsgId, OpId, STI) && + StringRef MsgName = getMsgName(MsgId, STI); + + if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) && isValidMsgStream(MsgId, OpId, StreamId, STI)) { - O << "sendmsg(" << getMsgName(MsgId); + O << "sendmsg(" << MsgName; if (msgRequiresOp(MsgId)) { O << ", " << getMsgOpName(MsgId, OpId); if (msgSupportsStream(MsgId, OpId)) { Index: llvm/lib/Target/AMDGPU/SIDefines.h =================================================================== --- llvm/lib/Target/AMDGPU/SIDefines.h +++ llvm/lib/Target/AMDGPU/SIDefines.h @@ -305,7 +305,6 @@ namespace SendMsg { // Encoding of SIMM16 used in s_sendmsg* insns. enum Id { // Message ID, width(4) [3:0]. - ID_UNKNOWN_ = -1, ID_INTERRUPT = 1, ID_GS = 2, ID_GS_DONE = 3, @@ -318,8 +317,7 @@ ID_GET_DOORBELL = 10, // added in GFX9 ID_GET_DDID = 11, // added in GFX10 ID_SYSMSG = 15, - ID_GAPS_LAST_, // Indicate that sequence has gaps. - ID_GAPS_FIRST_ = ID_INTERRUPT, + ID_SHIFT_ = 0, ID_WIDTH_ = 4, ID_MASK_ = (((1 << ID_WIDTH_) - 1) << ID_SHIFT_) Index: llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h =================================================================== --- llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h +++ llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h @@ -31,7 +31,9 @@ namespace SendMsg { // Symbolic names for the sendmsg(...) syntax. -extern const char *const IdSymbolic[ID_GAPS_LAST_]; +extern const CustomOperand Msg[]; +extern const int MSG_SIZE; + extern const char *const OpSysSymbolic[OP_SYS_LAST_]; extern const char *const OpGsSymbolic[OP_GS_LAST_]; Index: llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp =================================================================== --- llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp +++ llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp @@ -13,25 +13,33 @@ namespace AMDGPU { namespace SendMsg { -// This must be in sync with llvm::AMDGPU::SendMsg::Id enum members, see SIDefines.h. -const char *const IdSymbolic[ID_GAPS_LAST_] = { - nullptr, - "MSG_INTERRUPT", - "MSG_GS", - "MSG_GS_DONE", - "MSG_SAVEWAVE", - "MSG_STALL_WAVE_GEN", - "MSG_HALT_WAVES", - "MSG_ORDERED_PS_DONE", - "MSG_EARLY_PRIM_DEALLOC", - "MSG_GS_ALLOC_REQ", - "MSG_GET_DOORBELL", - "MSG_GET_DDID", - nullptr, - nullptr, - nullptr, - "MSG_SYSMSG" +// Disable lint checking for this block since it makes the table unreadable. +// NOLINTBEGIN +const CustomOperand Msg[] = { + {{""}}, + {{"MSG_INTERRUPT"}, ID_INTERRUPT}, + {{"MSG_GS"}, ID_GS}, + {{"MSG_GS_DONE"}, ID_GS_DONE}, + {{"MSG_SAVEWAVE"}, ID_SAVEWAVE, + [](const MCSubtargetInfo &STI) { + return isVI(STI) || isGFX9Plus(STI); + }}, + {{"MSG_STALL_WAVE_GEN"}, ID_STALL_WAVE_GEN, isGFX9Plus}, + {{"MSG_HALT_WAVES"}, ID_HALT_WAVES, isGFX9Plus}, + {{"MSG_ORDERED_PS_DONE"}, ID_ORDERED_PS_DONE, isGFX9Plus}, + {{"MSG_EARLY_PRIM_DEALLOC"}, ID_EARLY_PRIM_DEALLOC, isGFX9}, + {{"MSG_GS_ALLOC_REQ"}, ID_GS_ALLOC_REQ, isGFX9Plus}, + {{"MSG_GET_DOORBELL"}, ID_GET_DOORBELL, isGFX9Plus}, + {{"MSG_GET_DDID"}, ID_GET_DDID, isGFX10Plus}, + {{""}}, + {{""}}, + {{""}}, + {{"MSG_SYSMSG"}, ID_SYSMSG}, }; +// NOLINTEND + +const int MSG_SIZE = static_cast( + sizeof(Msg) / sizeof(CustomOperand)); // These two must be in sync with llvm::AMDGPU::SendMsg::Op enum members, see SIDefines.h. const char *const OpSysSymbolic[OP_SYS_LAST_] = { Index: llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h =================================================================== --- llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -679,19 +679,19 @@ namespace SendMsg { LLVM_READONLY -int64_t getMsgId(const StringRef Name); +int64_t getMsgId(const StringRef Name, const MCSubtargetInfo &STI); LLVM_READONLY int64_t getMsgOpId(int64_t MsgId, const StringRef Name); LLVM_READNONE -StringRef getMsgName(int64_t MsgId); +StringRef getMsgName(int64_t MsgId, const MCSubtargetInfo &STI); LLVM_READNONE StringRef getMsgOpName(int64_t MsgId, int64_t OpId); LLVM_READNONE -bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI, bool Strict = true); +bool isValidMsgId(int64_t MsgId); LLVM_READNONE bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, Index: llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -1301,40 +1301,18 @@ namespace SendMsg { -int64_t getMsgId(const StringRef Name) { - for (int i = ID_GAPS_FIRST_; i < ID_GAPS_LAST_; ++i) { - if (IdSymbolic[i] && Name == IdSymbolic[i]) - return i; - } - return ID_UNKNOWN_; -} - -bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI, bool Strict) { - if (Strict) { - switch (MsgId) { - case ID_SAVEWAVE: - return isVI(STI) || isGFX9Plus(STI); - case ID_STALL_WAVE_GEN: - case ID_HALT_WAVES: - case ID_ORDERED_PS_DONE: - case ID_GS_ALLOC_REQ: - case ID_GET_DOORBELL: - return isGFX9Plus(STI); - case ID_EARLY_PRIM_DEALLOC: - return isGFX9(STI); - case ID_GET_DDID: - return isGFX10Plus(STI); - default: - return 0 <= MsgId && MsgId < ID_GAPS_LAST_ && IdSymbolic[MsgId]; - } - } else { - return 0 <= MsgId && isUInt(MsgId); - } +int64_t getMsgId(const StringRef Name, const MCSubtargetInfo &STI) { + int Idx = getOprIdx(Name, Msg, MSG_SIZE, STI); + return (Idx < 0) ? Idx : Msg[Idx].Encoding; +} + +bool isValidMsgId(int64_t MsgId) { + return 0 <= MsgId && isUInt(MsgId); } -StringRef getMsgName(int64_t MsgId) { - assert(0 <= MsgId && MsgId < ID_GAPS_LAST_); - return IdSymbolic[MsgId]; +StringRef getMsgName(int64_t MsgId, const MCSubtargetInfo &STI) { + int Idx = getOprIdx(MsgId, Msg, MSG_SIZE, STI); + return (Idx < 0) ? "" : Msg[Idx].Name; } int64_t getMsgOpId(int64_t MsgId, const StringRef Name) { @@ -1351,7 +1329,7 @@ bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict) { - assert(isValidMsgId(MsgId, STI, Strict)); + assert(isValidMsgId(MsgId)); if (!Strict) return 0 <= OpId && isUInt(OpId); Index: llvm/test/MC/AMDGPU/sopp-err.s =================================================================== --- llvm/test/MC/AMDGPU/sopp-err.s +++ llvm/test/MC/AMDGPU/sopp-err.s @@ -83,41 +83,41 @@ // GCN: error: message operation does not support streams s_sendmsg sendmsg(MSG_SAVEWAVE) -// SICI: error: invalid message id +// SICI: error: specified message id is not supported on this GPU s_sendmsg sendmsg(MSG_STALL_WAVE_GEN) -// SICI: error: invalid message id -// VI: error: invalid message id +// SICI: error: specified message id is not supported on this GPU +// VI: error: specified message id is not supported on this GPU s_sendmsg sendmsg(MSG_HALT_WAVES) -// SICI: error: invalid message id -// VI: error: invalid message id +// SICI: error: specified message id is not supported on this GPU +// VI: error: specified message id is not supported on this GPU s_sendmsg sendmsg(MSG_ORDERED_PS_DONE) -// SICI: error: invalid message id -// VI: error: invalid message id +// SICI: error: specified message id is not supported on this GPU +// VI: error: specified message id is not supported on this GPU s_sendmsg sendmsg(MSG_EARLY_PRIM_DEALLOC) -// SICI: error: invalid message id -// VI: error: invalid message id -// GFX10: error: invalid message id +// SICI: error: specified message id is not supported on this GPU +// VI: error: specified message id is not supported on this GPU +// GFX10: error: specified message id is not supported on this GPU s_sendmsg sendmsg(MSG_GS_ALLOC_REQ) -// VI: error: invalid message id -// SICI: error: invalid message id +// VI: error: specified message id is not supported on this GPU +// SICI: error: specified message id is not supported on this GPU s_sendmsg sendmsg(MSG_GS_ALLOC_REQ, 0) -// VI: error: invalid message id -// SICI: error: invalid message id +// VI: error: specified message id is not supported on this GPU +// SICI: error: specified message id is not supported on this GPU // GFX10: error: message does not support operations s_sendmsg sendmsg(MSG_GET_DOORBELL) -// SICI: error: invalid message id -// VI: error: invalid message id +// SICI: error: specified message id is not supported on this GPU +// VI: error: specified message id is not supported on this GPU s_sendmsg sendmsg(MSG_GET_DDID) -// SICI: error: invalid message id -// VI: error: invalid message id +// SICI: error: specified message id is not supported on this GPU +// VI: error: specified message id is not supported on this GPU s_sendmsg sendmsg(-1) // VI: error: invalid message id Index: llvm/test/MC/AMDGPU/sopp.s =================================================================== --- llvm/test/MC/AMDGPU/sopp.s +++ llvm/test/MC/AMDGPU/sopp.s @@ -237,7 +237,7 @@ // VI: s_sendmsg sendmsg(MSG_SAVEWAVE) ; encoding: [0x04,0x00,0x90,0xbf] s_sendmsg sendmsg(MSG_SAVEWAVE) -// NOSICI: error: invalid message id +// NOSICI: error: specified message id is not supported on this GPU // VI: s_sendmsg sendmsg(MSG_SAVEWAVE) ; encoding: [0x04,0x00,0x90,0xbf] s_sendmsg 0x1f