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 @@ -6062,7 +6062,7 @@ } return false; } - if (!isValidMsgOp(Msg.Id, Op.Id, Strict)) { + if (!isValidMsgOp(Msg.Id, Op.Id, getSTI(), Strict)) { Error(Op.Loc, "invalid operation id"); return false; } @@ -6070,7 +6070,7 @@ Error(Stream.Loc, "message operation does not support streams"); return false; } - if (!isValidMsgStream(Msg.Id, Op.Id, Stream.Id, Strict)) { + if (!isValidMsgStream(Msg.Id, Op.Id, Stream.Id, getSTI(), Strict)) { Error(Stream.Loc, "invalid message stream id"); return false; } 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 @@ -1266,8 +1266,8 @@ decodeMsg(Imm16, MsgId, OpId, StreamId); if (isValidMsgId(MsgId, STI) && - isValidMsgOp(MsgId, OpId) && - isValidMsgStream(MsgId, OpId, StreamId)) { + isValidMsgOp(MsgId, OpId, STI) && + isValidMsgStream(MsgId, OpId, StreamId, STI)) { O << "sendmsg(" << getMsgName(MsgId); if (msgRequiresOp(MsgId)) { O << ", " << getMsgOpName(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 @@ -281,10 +281,16 @@ enum Id { // Message ID, width(4) [3:0]. ID_UNKNOWN_ = -1, ID_INTERRUPT = 1, - ID_GS, - ID_GS_DONE, - ID_GS_ALLOC_REQ = 9, - ID_GET_DOORBELL = 10, + ID_GS = 2, + ID_GS_DONE = 3, + ID_SAVEWAVE = 4, // added in GFX8 + ID_STALL_WAVE_GEN = 5, // added in GFX9 + ID_HALT_WAVES = 6, // added in GFX9 + ID_ORDERED_PS_DONE = 7, // added in GFX9 + ID_EARLY_PRIM_DEALLOC = 8, // added in GFX9, removed in GFX10 + ID_GS_ALLOC_REQ = 9, // added in GFX9 + 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, @@ -302,16 +308,16 @@ OP_MASK_ = (((1 << OP_WIDTH_) - 1) << OP_SHIFT_), // GS operations are encoded in bits 5:4 OP_GS_NOP = 0, - OP_GS_CUT, - OP_GS_EMIT, - OP_GS_EMIT_CUT, + OP_GS_CUT = 1, + OP_GS_EMIT = 2, + OP_GS_EMIT_CUT = 3, OP_GS_LAST_, OP_GS_FIRST_ = OP_GS_NOP, // SYS operations are encoded in bits 6:4 OP_SYS_ECC_ERR_INTERRUPT = 1, - OP_SYS_REG_RD, - OP_SYS_HOST_TRAP_ACK, - OP_SYS_TTRACE_PC, + OP_SYS_REG_RD = 2, + OP_SYS_HOST_TRAP_ACK = 3, + OP_SYS_TTRACE_PC = 4, OP_SYS_LAST_, OP_SYS_FIRST_ = OP_SYS_ECC_ERR_INTERRUPT, }; 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 @@ -9,6 +9,8 @@ #ifndef LLVM_LIB_TARGET_AMDGPU_UTILS_AMDGPUASMUTILS_H #define LLVM_LIB_TARGET_AMDGPU_UTILS_AMDGPUASMUTILS_H +#include "SIDefines.h" + namespace llvm { class StringLiteral; @@ -17,9 +19,9 @@ namespace SendMsg { // Symbolic names for the sendmsg(...) syntax. -extern const char* const IdSymbolic[]; -extern const char* const OpSysSymbolic[]; -extern const char* const OpGsSymbolic[]; +extern const char *const IdSymbolic[ID_GAPS_LAST_]; +extern const char *const OpSysSymbolic[OP_SYS_LAST_]; +extern const char *const OpGsSymbolic[OP_GS_LAST_]; } // namespace SendMsg 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 @@ -15,19 +15,19 @@ namespace SendMsg { // This must be in sync with llvm::AMDGPU::SendMsg::Id enum members, see SIDefines.h. -const char* const IdSymbolic[] = { +const char *const IdSymbolic[ID_GAPS_LAST_] = { nullptr, "MSG_INTERRUPT", "MSG_GS", "MSG_GS_DONE", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + "MSG_SAVEWAVE", + "MSG_STALL_WAVE_GEN", + "MSG_HALT_WAVES", + "MSG_ORDERED_PS_DONE", + "MSG_EARLY_PRIM_DEALLOC", "MSG_GS_ALLOC_REQ", "MSG_GET_DOORBELL", - nullptr, + "MSG_GET_DDID", nullptr, nullptr, nullptr, @@ -35,7 +35,7 @@ }; // These two must be in sync with llvm::AMDGPU::SendMsg::Op enum members, see SIDefines.h. -const char* const OpSysSymbolic[] = { +const char *const OpSysSymbolic[OP_SYS_LAST_] = { nullptr, "SYSMSG_OP_ECC_ERR_INTERRUPT", "SYSMSG_OP_REG_RD", @@ -43,7 +43,7 @@ "SYSMSG_OP_TTRACE_PC" }; -const char* const OpGsSymbolic[] = { +const char *const OpGsSymbolic[OP_GS_LAST_] = { "GS_OP_NOP", "GS_OP_CUT", "GS_OP_EMIT", 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 @@ -627,10 +627,12 @@ bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI, bool Strict = true); LLVM_READNONE -bool isValidMsgOp(int64_t MsgId, int64_t OpId, bool Strict = true); +bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, + bool Strict = true); LLVM_READNONE -bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, bool Strict = true); +bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, + const MCSubtargetInfo &STI, bool Strict = true); LLVM_READNONE bool msgRequiresOp(int64_t MsgId); 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 @@ -1065,23 +1065,32 @@ return ID_UNKNOWN_; } -static bool isValidMsgId(int64_t MsgId) { - return (ID_GAPS_FIRST_ <= MsgId && MsgId < ID_GAPS_LAST_) && IdSymbolic[MsgId]; -} - bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI, bool Strict) { if (Strict) { - if (MsgId == ID_GS_ALLOC_REQ || MsgId == ID_GET_DOORBELL) + 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); - else - return isValidMsgId(MsgId); + 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); } } StringRef getMsgName(int64_t MsgId) { - return isValidMsgId(MsgId)? IdSymbolic[MsgId] : ""; + assert(0 <= MsgId && MsgId < ID_GAPS_LAST_); + return IdSymbolic[MsgId]; } int64_t getMsgOpId(int64_t MsgId, const StringRef Name) { @@ -1096,7 +1105,9 @@ return OP_UNKNOWN_; } -bool isValidMsgOp(int64_t MsgId, int64_t OpId, bool Strict) { +bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, + bool Strict) { + assert(isValidMsgId(MsgId, STI, Strict)); if (!Strict) return 0 <= OpId && isUInt(OpId); @@ -1119,7 +1130,9 @@ return (MsgId == ID_SYSMSG)? OpSysSymbolic[OpId] : OpGsSymbolic[OpId]; } -bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, bool Strict) { +bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, + const MCSubtargetInfo &STI, bool Strict) { + assert(isValidMsgOp(MsgId, OpId, STI, Strict)); if (!Strict) return 0 <= StreamId && isUInt(StreamId); 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 @@ -82,6 +82,26 @@ s_sendmsg sendmsg(MSG_GS_DONE, 0, 0) // GCN: error: message operation does not support streams +s_sendmsg sendmsg(MSG_SAVEWAVE) +// SICI: error: invalid message id + +s_sendmsg sendmsg(MSG_STALL_WAVE_GEN) +// SICI: error: invalid message id +// VI: error: invalid message id + +s_sendmsg sendmsg(MSG_HALT_WAVES) +// SICI: error: invalid message id +// VI: error: invalid message id + +s_sendmsg sendmsg(MSG_ORDERED_PS_DONE) +// SICI: error: invalid message id +// VI: error: invalid message id + +s_sendmsg sendmsg(MSG_EARLY_PRIM_DEALLOC) +// SICI: error: invalid message id +// VI: error: invalid message id +// GFX10: error: invalid message id + s_sendmsg sendmsg(MSG_GS_ALLOC_REQ) // VI: error: invalid message id // SICI: error: invalid message id @@ -91,6 +111,14 @@ // SICI: error: invalid message id // GFX10: error: message does not support operations +s_sendmsg sendmsg(MSG_GET_DOORBELL) +// SICI: error: invalid message id +// VI: error: invalid message id + +s_sendmsg sendmsg(MSG_GET_DDID) +// SICI: error: invalid message id +// VI: error: invalid message id + s_sendmsg sendmsg(-1) // VI: error: invalid message id // SICI: error: invalid message id diff --git a/llvm/test/MC/AMDGPU/sopp-gfx10.s b/llvm/test/MC/AMDGPU/sopp-gfx10.s --- a/llvm/test/MC/AMDGPU/sopp-gfx10.s +++ b/llvm/test/MC/AMDGPU/sopp-gfx10.s @@ -15,3 +15,9 @@ s_sendmsg sendmsg(MSG_GET_DOORBELL) // GFX10: s_sendmsg sendmsg(MSG_GET_DOORBELL) ; encoding: [0x0a,0x00,0x90,0xbf] + +s_sendmsg 11 +// GFX10: s_sendmsg sendmsg(MSG_GET_DDID) ; encoding: [0x0b,0x00,0x90,0xbf] + +s_sendmsg sendmsg(MSG_GET_DDID) +// GFX10: s_sendmsg sendmsg(MSG_GET_DDID) ; encoding: [0x0b,0x00,0x90,0xbf] diff --git a/llvm/test/MC/AMDGPU/sopp-gfx9.s b/llvm/test/MC/AMDGPU/sopp-gfx9.s --- a/llvm/test/MC/AMDGPU/sopp-gfx9.s +++ b/llvm/test/MC/AMDGPU/sopp-gfx9.s @@ -74,6 +74,30 @@ // s_sendmsg //===----------------------------------------------------------------------===// +s_sendmsg 5 +// GFX9: s_sendmsg sendmsg(MSG_STALL_WAVE_GEN) ; encoding: [0x05,0x00,0x90,0xbf] + +s_sendmsg sendmsg(MSG_STALL_WAVE_GEN) +// GFX9: s_sendmsg sendmsg(MSG_STALL_WAVE_GEN) ; encoding: [0x05,0x00,0x90,0xbf] + +s_sendmsg 6 +// GFX9: s_sendmsg sendmsg(MSG_HALT_WAVES) ; encoding: [0x06,0x00,0x90,0xbf] + +s_sendmsg sendmsg(MSG_HALT_WAVES) +// GFX9: s_sendmsg sendmsg(MSG_HALT_WAVES) ; encoding: [0x06,0x00,0x90,0xbf] + +s_sendmsg 7 +// GFX9: s_sendmsg sendmsg(MSG_ORDERED_PS_DONE) ; encoding: [0x07,0x00,0x90,0xbf] + +s_sendmsg sendmsg(MSG_ORDERED_PS_DONE) +// GFX9: s_sendmsg sendmsg(MSG_ORDERED_PS_DONE) ; encoding: [0x07,0x00,0x90,0xbf] + +s_sendmsg 8 +// GFX9: s_sendmsg sendmsg(MSG_EARLY_PRIM_DEALLOC) ; encoding: [0x08,0x00,0x90,0xbf] + +s_sendmsg sendmsg(MSG_EARLY_PRIM_DEALLOC) +// GFX9: s_sendmsg sendmsg(MSG_EARLY_PRIM_DEALLOC) ; encoding: [0x08,0x00,0x90,0xbf] + s_sendmsg 9 // GFX9: s_sendmsg sendmsg(MSG_GS_ALLOC_REQ) ; encoding: [0x09,0x00,0x90,0xbf] 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 @@ -1,4 +1,4 @@ -// RUN: not llvm-mc -arch=amdgcn -show-encoding %s | FileCheck --check-prefix=GCN %s +// RUN: not llvm-mc -arch=amdgcn -show-encoding %s | FileCheck --check-prefixes=GCN,SI %s // RUN: not llvm-mc -arch=amdgcn %s 2>&1 | FileCheck %s --check-prefix=NOSICI --implicit-check-not=error: // RUN: llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s | FileCheck --check-prefixes=GCN,VI %s @@ -228,6 +228,18 @@ s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP) // GCN: s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP) ; encoding: [0x03,0x00,0x90,0xbf] +s_sendmsg 0x4 +// SI: s_sendmsg sendmsg(4, 0, 0) ; encoding: [0x04,0x00,0x90,0xbf] +// VI: s_sendmsg sendmsg(MSG_SAVEWAVE) ; encoding: [0x04,0x00,0x90,0xbf] + +s_sendmsg sendmsg(4) +// SI: s_sendmsg sendmsg(4, 0, 0) ; encoding: [0x04,0x00,0x90,0xbf] +// VI: s_sendmsg sendmsg(MSG_SAVEWAVE) ; encoding: [0x04,0x00,0x90,0xbf] + +s_sendmsg sendmsg(MSG_SAVEWAVE) +// NOSICI: error: invalid message id +// VI: s_sendmsg sendmsg(MSG_SAVEWAVE) ; encoding: [0x04,0x00,0x90,0xbf] + s_sendmsg 0x1f // GCN: s_sendmsg sendmsg(MSG_SYSMSG, SYSMSG_OP_ECC_ERR_INTERRUPT) ; encoding: [0x1f,0x00,0x90,0xbf] @@ -250,9 +262,6 @@ s_sendmsg 2 // GCN: s_sendmsg sendmsg(2, 0, 0) ; encoding: [0x02,0x00,0x90,0xbf] -s_sendmsg 0x4 -// GCN: s_sendmsg sendmsg(4, 0, 0) ; encoding: [0x04,0x00,0x90,0xbf] - s_sendmsg 9 // GCN: s_sendmsg sendmsg(9, 0, 0) ; encoding: [0x09,0x00,0x90,0xbf] diff --git a/llvm/test/MC/Disassembler/AMDGPU/sopp_vi.txt b/llvm/test/MC/Disassembler/AMDGPU/sopp_vi.txt --- a/llvm/test/MC/Disassembler/AMDGPU/sopp_vi.txt +++ b/llvm/test/MC/Disassembler/AMDGPU/sopp_vi.txt @@ -93,6 +93,9 @@ # GCN: s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP) ; encoding: [0x03,0x00,0x90,0xbf] 0x03 0x00 0x90 0xbf +# GCN: s_sendmsg sendmsg(MSG_SAVEWAVE) ; encoding: [0x04,0x00,0x90,0xbf] +0x04 0x00 0x90 0xbf + # GCN: s_sendmsg sendmsg(11, 0, 0) ; encoding: [0x0b,0x00,0x90,0xbf] 0x0b 0x00 0x90 0xbf @@ -120,6 +123,9 @@ # GCN: s_sendmsg sendmsg(2, 0, 1) ; encoding: [0x02,0x01,0x90,0xbf] 0x02 0x01 0x90 0xbf +# GCN: s_sendmsg sendmsg(4, 0, 1) ; encoding: [0x04,0x01,0x90,0xbf] +0x04 0x01 0x90 0xbf + # GCN: s_sendmsg sendmsg(15, 7, 3) ; encoding: [0x7f,0x03,0x90,0xbf] 0x7f 0x03 0x90 0xbf