[AMDGPU][MC][NFC] Refactored sendmsg(...) handling
authorDmitry Preobrazhensky <dmitry.preobrazhensky@amd.com>
Mon, 21 Mar 2022 12:23:44 +0000 (15:23 +0300)
committerDmitry Preobrazhensky <dmitry.preobrazhensky@amd.com>
Mon, 21 Mar 2022 12:37:30 +0000 (15:37 +0300)
Differential Revision: https://reviews.llvm.org/D121995

llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
llvm/lib/Target/AMDGPU/SIDefines.h
llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
llvm/test/MC/AMDGPU/sopp-err.s
llvm/test/MC/AMDGPU/sopp.s

index 348d2ff..ef7c336 100644 (file)
@@ -6449,7 +6449,8 @@ AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
   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 @@ AMDGPUAsmParser::validateSendMsg(const OperandInfoTy &Msg,
   // 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 @@ AMDGPUAsmParser::parseSendMsgOp(OperandVector &Operands) {
   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 c8306bc..50a7332 100644 (file)
@@ -1278,10 +1278,11 @@ void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
   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 52232d8..4450691 100644 (file)
@@ -305,7 +305,6 @@ enum CPol {
 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 @@ enum Id { // Message ID, width(4) [3:0].
   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 8809379..a26390b 100644 (file)
@@ -13,25 +13,30 @@ namespace llvm {
 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<const MCSubtargetInfo &> 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<int>(
+    sizeof(Msg) / sizeof(CustomOperand<const MCSubtargetInfo &>));
 
 // 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 @@ const CustomOperand<const MCSubtargetInfo &> Opr[] = {
   {{"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 @@ const CustomOperand<const MCSubtargetInfo &> Opr[] = {
   {{"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},
index ec05adb..32b439d 100644 (file)
@@ -31,7 +31,9 @@ template <class T> struct CustomOperand {
 
 namespace SendMsg { // Symbolic names for the sendmsg(...) syntax.
 
-extern const char *const IdSymbolic[ID_GAPS_LAST_];
+extern const CustomOperand<const MCSubtargetInfo &> Msg[];
+extern const int MSG_SIZE;
+
 extern const char *const OpSysSymbolic[OP_SYS_LAST_];
 extern const char *const OpGsSymbolic[OP_GS_LAST_];
 
index 155a352..b2dc9e1 100644 (file)
@@ -1287,40 +1287,18 @@ unsigned getDefaultFormatEncoding(const MCSubtargetInfo &STI) {
 
 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<ID_WIDTH_>(MsgId);
-  }
+int64_t getMsgId(const StringRef Name, const MCSubtargetInfo &STI) {
+  int Idx = getOprIdx<const MCSubtargetInfo &>(Name, Msg, MSG_SIZE, STI);
+  return (Idx < 0) ? Idx : Msg[Idx].Encoding;
+}
+
+bool isValidMsgId(int64_t MsgId) {
+  return 0 <= MsgId && isUInt<ID_WIDTH_>(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<const MCSubtargetInfo &>(MsgId, Msg, MSG_SIZE, STI);
+  return (Idx < 0) ? "" : Msg[Idx].Name;
 }
 
 int64_t getMsgOpId(int64_t MsgId, const StringRef Name) {
@@ -1337,7 +1315,7 @@ int64_t getMsgOpId(int64_t MsgId, const StringRef Name) {
 
 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<OP_WIDTH_>(OpId);
@@ -1523,6 +1501,10 @@ bool isGFX9_GFX10(const MCSubtargetInfo &STI) {
   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 isGFX10(const MCSubtargetInfo &STI) {
 
 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];
 }
index 118dbbf..b4d359e 100644 (file)
@@ -673,19 +673,19 @@ unsigned getDefaultFormatEncoding(const MCSubtargetInfo &STI);
 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 isCI(const MCSubtargetInfo &STI);
 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);
index 928a39b..c432b04 100644 (file)
@@ -83,41 +83,41 @@ 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
+// 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 aa23deb..ddc3cd6 100644 (file)
@@ -237,7 +237,7 @@ s_sendmsg sendmsg(4)
 // 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