diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -6449,7 +6449,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")) { @@ -6488,9 +6489,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) { @@ -6523,7 +6531,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) && diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp @@ -1278,10 +1278,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)) { diff --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h --- a/llvm/lib/Target/AMDGPU/SIDefines.h +++ b/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_) diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h +++ b/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_]; diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp @@ -13,25 +13,30 @@ 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, isGFX8Plus}, + {{"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_] = { @@ -60,11 +65,7 @@ {{"HW_REG_MODE"}, ID_MODE}, {{"HW_REG_STATUS"}, ID_STATUS}, {{"HW_REG_TRAPSTS"}, ID_TRAPSTS}, - {{"HW_REG_HW_ID"}, ID_HW_ID, - [](const MCSubtargetInfo &STI) { - return isSI(STI) || isCI(STI) || - isVI(STI) || isGFX9(STI); - }}, + {{"HW_REG_HW_ID"}, ID_HW_ID, isNotGFX10Plus}, {{"HW_REG_GPR_ALLOC"}, ID_GPR_ALLOC}, {{"HW_REG_LDS_ALLOC"}, ID_LDS_ALLOC}, {{"HW_REG_IB_STS"}, ID_IB_STS}, @@ -82,11 +83,7 @@ {{"HW_REG_TMA_HI"}, ID_TMA_HI, isGFX9_GFX10}, {{"HW_REG_FLAT_SCR_LO"}, ID_FLAT_SCR_LO, isGFX10Plus}, {{"HW_REG_FLAT_SCR_HI"}, ID_FLAT_SCR_HI, isGFX10Plus}, - {{"HW_REG_XNACK_MASK"}, ID_XNACK_MASK, - [](const MCSubtargetInfo &STI) { - return isGFX10(STI) && - !AMDGPU::isGFX10_BEncoding(STI); - }}, + {{"HW_REG_XNACK_MASK"}, ID_XNACK_MASK, isGFX10Before1030}, {{"HW_REG_HW_ID1"}, ID_HW_ID1, isGFX10Plus}, {{"HW_REG_HW_ID2"}, ID_HW_ID2, isGFX10Plus}, {{"HW_REG_POPS_PACKER"}, ID_POPS_PACKER, isGFX10}, diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -673,19 +673,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, @@ -767,9 +767,12 @@ bool isVI(const MCSubtargetInfo &STI); bool isGFX9(const MCSubtargetInfo &STI); bool isGFX9_GFX10(const MCSubtargetInfo &STI); +bool isGFX8Plus(const MCSubtargetInfo &STI); bool isGFX9Plus(const MCSubtargetInfo &STI); bool isGFX10(const MCSubtargetInfo &STI); bool isGFX10Plus(const MCSubtargetInfo &STI); +bool isNotGFX10Plus(const MCSubtargetInfo &STI); +bool isGFX10Before1030(const MCSubtargetInfo &STI); bool isGCN3Encoding(const MCSubtargetInfo &STI); bool isGFX10_AEncoding(const MCSubtargetInfo &STI); bool isGFX10_BEncoding(const MCSubtargetInfo &STI); diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -1287,40 +1287,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) { @@ -1337,7 +1315,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); @@ -1523,6 +1501,10 @@ return isGFX9(STI) || isGFX10(STI); } +bool isGFX8Plus(const MCSubtargetInfo &STI) { + return isVI(STI) || isGFX9Plus(STI); +} + bool isGFX9Plus(const MCSubtargetInfo &STI) { return isGFX9(STI) || isGFX10Plus(STI); } @@ -1533,6 +1515,14 @@ bool isGFX10Plus(const MCSubtargetInfo &STI) { return isGFX10(STI); } +bool isNotGFX10Plus(const MCSubtargetInfo &STI) { + return isSI(STI) || isCI(STI) || isVI(STI) || isGFX9(STI); +} + +bool isGFX10Before1030(const MCSubtargetInfo &STI) { + return isGFX10(STI) && !AMDGPU::isGFX10_BEncoding(STI); +} + bool isGCN3Encoding(const MCSubtargetInfo &STI) { return STI.getFeatureBits()[AMDGPU::FeatureGCN3Encoding]; } diff --git a/llvm/test/MC/AMDGPU/sopp-err.s b/llvm/test/MC/AMDGPU/sopp-err.s --- a/llvm/test/MC/AMDGPU/sopp-err.s +++ b/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 diff --git a/llvm/test/MC/AMDGPU/sopp.s b/llvm/test/MC/AMDGPU/sopp.s --- a/llvm/test/MC/AMDGPU/sopp.s +++ b/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