[llvm] r364645 - [AMDGPU][MC] Enabled constant expressions as operands of sendmsg

Dmitry Preobrazhensky via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 28 07:14:03 PDT 2019


Author: dpreobra
Date: Fri Jun 28 07:14:02 2019
New Revision: 364645

URL: http://llvm.org/viewvc/llvm-project?rev=364645&view=rev
Log:
[AMDGPU][MC] Enabled constant expressions as operands of sendmsg

See bug 40820: https://bugs.llvm.org/show_bug.cgi?id=40820

Reviewers: artem.tamazov, arsenm

Differential Revision: https://reviews.llvm.org/D62735

Modified:
    llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
    llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
    llvm/trunk/lib/Target/AMDGPU/SIDefines.h
    llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
    llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
    llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.sendmsg.ll
    llvm/trunk/test/MC/AMDGPU/sopp-err.s
    llvm/trunk/test/MC/AMDGPU/sopp.s
    llvm/trunk/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt
    llvm/trunk/test/MC/Disassembler/AMDGPU/sopp_vi.txt

Modified: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Fri Jun 28 07:14:02 2019
@@ -1142,11 +1142,17 @@ private:
   struct OperandInfoTy {
     int64_t Id;
     bool IsSymbolic = false;
+    bool IsDefined = false;
 
     OperandInfoTy(int64_t Id_) : Id(Id_) {}
   };
 
-  bool parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &Operation, int64_t &StreamId);
+  bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &Op, OperandInfoTy &Stream);
+  void validateSendMsg(const OperandInfoTy &Msg,
+                       const OperandInfoTy &Op,
+                       const OperandInfoTy &Stream,
+                       const SMLoc Loc);
+
   bool parseHwregBody(OperandInfoTy &HwReg, int64_t &Offset, int64_t &Width);
   void validateHwreg(const OperandInfoTy &HwReg,
                      const int64_t Offset,
@@ -4705,107 +4711,99 @@ bool AMDGPUOperand::isHwreg() const {
 // sendmsg
 //===----------------------------------------------------------------------===//
 
-bool AMDGPUAsmParser::parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &Operation, int64_t &StreamId) {
+bool
+AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
+                                  OperandInfoTy &Op,
+                                  OperandInfoTy &Stream) {
   using namespace llvm::AMDGPU::SendMsg;
 
-  if (Parser.getTok().getString() != "sendmsg")
-    return true;
-  Parser.Lex();
+  if (isToken(AsmToken::Identifier) && (Msg.Id = getMsgId(getTokenStr())) >= 0) {
+    Msg.IsSymbolic = true;
+    lex(); // skip message name
+  } else if (!parseExpr(Msg.Id)) {
+    return false;
+  }
 
-  if (getLexer().isNot(AsmToken::LParen))
-    return true;
-  Parser.Lex();
+  if (trySkipToken(AsmToken::Comma)) {
+    Op.IsDefined = true;
+    if (isToken(AsmToken::Identifier) &&
+        (Op.Id = getMsgOpId(Msg.Id, getTokenStr())) >= 0) {
+      lex(); // skip operation name
+    } else if (!parseExpr(Op.Id)) {
+      return false;
+    }
 
-  if (getLexer().is(AsmToken::Identifier)) {
-    Msg.IsSymbolic = true;
-    Msg.Id = ID_UNKNOWN_;
-    const std::string tok = Parser.getTok().getString();
-    for (int i = ID_GAPS_FIRST_; i < ID_GAPS_LAST_; ++i) {
-      switch(i) {
-        default: continue; // Omit gaps.
-        case ID_GS_ALLOC_REQ:
-          if (isSI() || isCI() || isVI())
-            continue;
-          break;
-        case ID_INTERRUPT: case ID_GS: case ID_GS_DONE:
-        case ID_SYSMSG: break;
-      }
-      if (tok == IdSymbolic[i]) {
-        Msg.Id = i;
-        break;
-      }
+    if (trySkipToken(AsmToken::Comma)) {
+      Stream.IsDefined = true;
+      if (!parseExpr(Stream.Id))
+        return false;
     }
-    Parser.Lex();
-  } else {
-    Msg.IsSymbolic = false;
-    if (getLexer().isNot(AsmToken::Integer))
-      return true;
-    if (getParser().parseAbsoluteExpression(Msg.Id))
-      return true;
-    if (getLexer().is(AsmToken::Integer))
-      if (getParser().parseAbsoluteExpression(Msg.Id))
-        Msg.Id = ID_UNKNOWN_;
   }
-  if (Msg.Id == ID_UNKNOWN_) // Don't know how to parse the rest.
-    return false;
 
-  if (!(Msg.Id == ID_GS || Msg.Id == ID_GS_DONE || Msg.Id == ID_SYSMSG)) {
-    if (getLexer().isNot(AsmToken::RParen))
-      return true;
-    Parser.Lex();
-    return false;
-  }
+  return skipToken(AsmToken::RParen, "expected a closing parenthesis");
+}
 
-  if (getLexer().isNot(AsmToken::Comma))
-    return true;
-  Parser.Lex();
+void
+AMDGPUAsmParser::validateSendMsg(const OperandInfoTy &Msg,
+                                 const OperandInfoTy &Op,
+                                 const OperandInfoTy &Stream,
+                                 const SMLoc S) {
+  using namespace llvm::AMDGPU::SendMsg;
 
-  assert(Msg.Id == ID_GS || Msg.Id == ID_GS_DONE || Msg.Id == ID_SYSMSG);
-  Operation.Id = ID_UNKNOWN_;
-  if (getLexer().is(AsmToken::Identifier)) {
-    Operation.IsSymbolic = true;
-    const char* const *S = (Msg.Id == ID_SYSMSG) ? OpSysSymbolic : OpGsSymbolic;
-    const int F = (Msg.Id == ID_SYSMSG) ? OP_SYS_FIRST_ : OP_GS_FIRST_;
-    const int L = (Msg.Id == ID_SYSMSG) ? OP_SYS_LAST_ : OP_GS_LAST_;
-    const StringRef Tok = Parser.getTok().getString();
-    for (int i = F; i < L; ++i) {
-      if (Tok == S[i]) {
-        Operation.Id = i;
-        break;
-      }
-    }
-    Parser.Lex();
-  } else {
-    Operation.IsSymbolic = false;
-    if (getLexer().isNot(AsmToken::Integer))
-      return true;
-    if (getParser().parseAbsoluteExpression(Operation.Id))
-      return true;
+  // Validation strictness depends on whether message is specified
+  // in a symbolc or in a numeric form. In the latter case
+  // only encoding possibility is checked.
+  bool Strict = Msg.IsSymbolic;
+
+  if (!isValidMsgId(Msg.Id, getSTI(), Strict)) {
+    Error(S, "invalid message id");
+  } else if (Strict && (msgRequiresOp(Msg.Id) != Op.IsDefined)) {
+    Error(S, Op.IsDefined ?
+             "message does not support operations" :
+             "missing message operation");
+  } else if (!isValidMsgOp(Msg.Id, Op.Id, Strict)) {
+    Error(S, "invalid operation id");
+  } else if (Strict && !msgSupportsStream(Msg.Id, Op.Id) && Stream.IsDefined) {
+    Error(S, "message operation does not support streams");
+  } else if (!isValidMsgStream(Msg.Id, Op.Id, Stream.Id, Strict)) {
+    Error(S, "invalid message stream id");
   }
+}
 
-  if ((Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) && Operation.Id != OP_GS_NOP) {
-    // Stream id is optional.
-    if (getLexer().is(AsmToken::RParen)) {
-      Parser.Lex();
-      return false;
-    }
+OperandMatchResultTy
+AMDGPUAsmParser::parseSendMsgOp(OperandVector &Operands) {
+  using namespace llvm::AMDGPU::SendMsg;
 
-    if (getLexer().isNot(AsmToken::Comma))
-      return true;
-    Parser.Lex();
+  int64_t ImmVal = 0;
+  SMLoc Loc = getLoc();
 
-    if (getLexer().isNot(AsmToken::Integer))
-      return true;
-    if (getParser().parseAbsoluteExpression(StreamId))
-      return true;
+  // If parse failed, do not return error code
+  // to avoid excessive error messages.
+  if (trySkipId("sendmsg", AsmToken::LParen)) {
+    OperandInfoTy Msg(ID_UNKNOWN_);
+    OperandInfoTy Op(OP_NONE_);
+    OperandInfoTy Stream(STREAM_ID_NONE_);
+    if (parseSendMsgBody(Msg, Op, Stream)) {
+      validateSendMsg(Msg, Op, Stream, Loc);
+      ImmVal = encodeMsg(Msg.Id, Op.Id, Stream.Id);
+    }
+  } else if (parseExpr(ImmVal)) {
+    if (ImmVal < 0 || !isUInt<16>(ImmVal))
+      Error(Loc, "invalid immediate: only 16-bit values are legal");
   }
 
-  if (getLexer().isNot(AsmToken::RParen))
-    return true;
-  Parser.Lex();
-  return false;
+  Operands.push_back(AMDGPUOperand::CreateImm(this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
+  return MatchOperand_Success;
 }
 
+bool AMDGPUOperand::isSendMsg() const {
+  return isImmTy(ImmTySendMsg);
+}
+
+//===----------------------------------------------------------------------===//
+// v_interp
+//===----------------------------------------------------------------------===//
+
 OperandMatchResultTy AMDGPUAsmParser::parseInterpSlot(OperandVector &Operands) {
   if (getLexer().getKind() != AsmToken::Identifier)
     return MatchOperand_NoMatch;
@@ -4867,6 +4865,10 @@ OperandMatchResultTy AMDGPUAsmParser::pa
   return MatchOperand_Success;
 }
 
+//===----------------------------------------------------------------------===//
+// exp
+//===----------------------------------------------------------------------===//
+
 void AMDGPUAsmParser::errorExpTgt() {
   Error(Parser.getTok().getLoc(), "invalid exp target");
 }
@@ -4951,90 +4953,6 @@ OperandMatchResultTy AMDGPUAsmParser::pa
   return MatchOperand_Success;
 }
 
-OperandMatchResultTy
-AMDGPUAsmParser::parseSendMsgOp(OperandVector &Operands) {
-  using namespace llvm::AMDGPU::SendMsg;
-
-  int64_t Imm16Val = 0;
-  SMLoc S = Parser.getTok().getLoc();
-
-  switch(getLexer().getKind()) {
-  default:
-    return MatchOperand_NoMatch;
-  case AsmToken::Integer:
-    // The operand can be an integer value.
-    if (getParser().parseAbsoluteExpression(Imm16Val))
-      return MatchOperand_NoMatch;
-    if (Imm16Val < 0 || !isUInt<16>(Imm16Val)) {
-      Error(S, "invalid immediate: only 16-bit values are legal");
-      // Do not return error code, but create an imm operand anyway and proceed
-      // to the next operand, if any. That avoids unneccessary error messages.
-    }
-    break;
-  case AsmToken::Identifier: {
-      OperandInfoTy Msg(ID_UNKNOWN_);
-      OperandInfoTy Operation(OP_UNKNOWN_);
-      int64_t StreamId = STREAM_ID_DEFAULT_;
-      if (parseSendMsgConstruct(Msg, Operation, StreamId))
-        return MatchOperand_ParseFail;
-      do {
-        // Validate and encode message ID.
-        if (! ((ID_INTERRUPT <= Msg.Id && Msg.Id <= ID_GS_DONE)
-                || (Msg.Id == ID_GS_ALLOC_REQ && !isSI() && !isCI() && !isVI())
-                || Msg.Id == ID_SYSMSG)) {
-          if (Msg.IsSymbolic)
-            Error(S, "invalid/unsupported symbolic name of message");
-          else
-            Error(S, "invalid/unsupported code of message");
-          break;
-        }
-        Imm16Val = (Msg.Id << ID_SHIFT_);
-        // Validate and encode operation ID.
-        if (Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) {
-          if (! (OP_GS_FIRST_ <= Operation.Id && Operation.Id < OP_GS_LAST_)) {
-            if (Operation.IsSymbolic)
-              Error(S, "invalid symbolic name of GS_OP");
-            else
-              Error(S, "invalid code of GS_OP: only 2-bit values are legal");
-            break;
-          }
-          if (Operation.Id == OP_GS_NOP
-              && Msg.Id != ID_GS_DONE) {
-            Error(S, "invalid GS_OP: NOP is for GS_DONE only");
-            break;
-          }
-          Imm16Val |= (Operation.Id << OP_SHIFT_);
-        }
-        if (Msg.Id == ID_SYSMSG) {
-          if (! (OP_SYS_FIRST_ <= Operation.Id && Operation.Id < OP_SYS_LAST_)) {
-            if (Operation.IsSymbolic)
-              Error(S, "invalid/unsupported symbolic name of SYSMSG_OP");
-            else
-              Error(S, "invalid/unsupported code of SYSMSG_OP");
-            break;
-          }
-          Imm16Val |= (Operation.Id << OP_SHIFT_);
-        }
-        // Validate and encode stream ID.
-        if ((Msg.Id == ID_GS || Msg.Id == ID_GS_DONE) && Operation.Id != OP_GS_NOP) {
-          if (! (STREAM_ID_FIRST_ <= StreamId && StreamId < STREAM_ID_LAST_)) {
-            Error(S, "invalid stream id: only 2-bit values are legal");
-            break;
-          }
-          Imm16Val |= (StreamId << STREAM_ID_SHIFT_);
-        }
-      } while (false);
-    }
-    break;
-  }
-  Operands.push_back(AMDGPUOperand::CreateImm(this, Imm16Val, S, AMDGPUOperand::ImmTySendMsg));
-  return MatchOperand_Success;
-}
-
-bool AMDGPUOperand::isSendMsg() const {
-  return isImmTy(ImmTySendMsg);
-}
-
 //===----------------------------------------------------------------------===//
 // parser helpers
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp Fri Jun 28 07:14:02 2019
@@ -1234,42 +1234,29 @@ void AMDGPUInstPrinter::printSendMsg(con
                                      raw_ostream &O) {
   using namespace llvm::AMDGPU::SendMsg;
 
-  const unsigned SImm16 = MI->getOperand(OpNo).getImm();
-  const unsigned Id = SImm16 & ID_MASK_;
-  do {
-      if (Id == ID_INTERRUPT ||
-          (Id == ID_GS_ALLOC_REQ && !AMDGPU::isSI(STI) && !AMDGPU::isCI(STI) &&
-           !AMDGPU::isVI(STI))) {
-      if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0.
-        break;
-      O << "sendmsg(" << IdSymbolic[Id] << ')';
-      return;
-    }
-    if (Id == ID_GS || Id == ID_GS_DONE) {
-      if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0.
-        break;
-      const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_;
-      const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_;
-      if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only.
-        break;
-      if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits.
-        break;
-      O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs];
-      if (OpGs != OP_GS_NOP) {  O << ", " << StreamId; }
-      O << ')';
-      return;
-    }
-    if (Id == ID_SYSMSG) {
-      if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0.
-        break;
-      const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_;
-      if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown.
-        break;
-      O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')';
-      return;
+  const unsigned Imm16 = MI->getOperand(OpNo).getImm();
+
+  uint16_t MsgId;
+  uint16_t OpId;
+  uint16_t StreamId;
+  decodeMsg(Imm16, MsgId, OpId, StreamId);
+
+  if (isValidMsgId(MsgId, STI) &&
+      isValidMsgOp(MsgId, OpId) &&
+      isValidMsgStream(MsgId, OpId, StreamId)) {
+    O << "sendmsg(" << getMsgName(MsgId);
+    if (msgRequiresOp(MsgId)) {
+      O << ", " << getMsgOpName(MsgId, OpId);
+      if (msgSupportsStream(MsgId, OpId)) {
+        O << ", " << StreamId;
+      }
     }
-  } while (false);
-  O << SImm16; // Unknown simm16 code.
+    O << ')';
+  } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
+    O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
+  } else {
+    O << Imm16; // Unknown imm16 code.
+  }
 }
 
 static void printSwizzleBitmask(const uint16_t AndMask,

Modified: llvm/trunk/lib/Target/AMDGPU/SIDefines.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIDefines.h?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/SIDefines.h (original)
+++ llvm/trunk/lib/Target/AMDGPU/SIDefines.h Fri Jun 28 07:14:02 2019
@@ -260,27 +260,28 @@ enum Id { // Message ID, width(4) [3:0].
 enum Op { // Both GS and SYS operation IDs.
   OP_UNKNOWN_ = -1,
   OP_SHIFT_ = 4,
-  // width(2) [5:4]
+  OP_NONE_ = 0,
+  // Bits used for operation encoding
+  OP_WIDTH_ = 3,
+  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_LAST_,
   OP_GS_FIRST_ = OP_GS_NOP,
-  OP_GS_WIDTH_ = 2,
-  OP_GS_MASK_ = (((1 << OP_GS_WIDTH_) - 1) << OP_SHIFT_),
-  // width(3) [6:4]
+  // 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_LAST_,
   OP_SYS_FIRST_ = OP_SYS_ECC_ERR_INTERRUPT,
-  OP_SYS_WIDTH_ = 3,
-  OP_SYS_MASK_ = (((1 << OP_SYS_WIDTH_) - 1) << OP_SHIFT_)
 };
 
 enum StreamId : unsigned { // Stream ID, (2) [9:8].
+  STREAM_ID_NONE_ = 0,
   STREAM_ID_DEFAULT_ = 0,
   STREAM_ID_LAST_ = 4,
   STREAM_ID_FIRST_ = STREAM_ID_DEFAULT_,

Modified: llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp Fri Jun 28 07:14:02 2019
@@ -713,6 +713,114 @@ void decodeHwreg(unsigned Val, unsigned
 } // namespace Hwreg
 
 //===----------------------------------------------------------------------===//
+// SendMsg
+//===----------------------------------------------------------------------===//
+
+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_;
+}
+
+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) {
+  return Strict ?
+         isValidMsgId(MsgId) && (MsgId != ID_GS_ALLOC_REQ || isGFX9(STI) || isGFX10(STI)) :
+         0 <= MsgId && isUInt<ID_WIDTH_>(MsgId);
+}
+
+StringRef getMsgName(int64_t MsgId) {
+  return isValidMsgId(MsgId)? IdSymbolic[MsgId] : "";
+}
+
+int64_t getMsgOpId(int64_t MsgId, const StringRef Name) {
+  const char* const *S = (MsgId == ID_SYSMSG) ? OpSysSymbolic : OpGsSymbolic;
+  const int F = (MsgId == ID_SYSMSG) ? OP_SYS_FIRST_ : OP_GS_FIRST_;
+  const int L = (MsgId == ID_SYSMSG) ? OP_SYS_LAST_ : OP_GS_LAST_;
+  for (int i = F; i < L; ++i) {
+    if (Name == S[i]) {
+      return i;
+    }
+  }
+  return OP_UNKNOWN_;
+}
+
+bool isValidMsgOp(int64_t MsgId, int64_t OpId, bool Strict) {
+
+  if (!Strict)
+    return 0 <= OpId && isUInt<OP_WIDTH_>(OpId);
+
+  switch(MsgId)
+  {
+  case ID_GS:
+    return (OP_GS_FIRST_ <= OpId && OpId < OP_GS_LAST_) && OpId != OP_GS_NOP;
+  case ID_GS_DONE:
+    return OP_GS_FIRST_ <= OpId && OpId < OP_GS_LAST_;
+  case ID_SYSMSG:
+    return OP_SYS_FIRST_ <= OpId && OpId < OP_SYS_LAST_;
+  default:
+    return OpId == OP_NONE_;
+  }
+}
+
+StringRef getMsgOpName(int64_t MsgId, int64_t OpId) {
+  assert(msgRequiresOp(MsgId));
+  return (MsgId == ID_SYSMSG)? OpSysSymbolic[OpId] : OpGsSymbolic[OpId];
+}
+
+bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, bool Strict) {
+
+  if (!Strict)
+    return 0 <= StreamId && isUInt<STREAM_ID_WIDTH_>(StreamId);
+
+  switch(MsgId)
+  {
+  case ID_GS:
+    return STREAM_ID_FIRST_ <= StreamId && StreamId < STREAM_ID_LAST_;
+  case ID_GS_DONE:
+    return (OpId == OP_GS_NOP)?
+           (StreamId == STREAM_ID_NONE_) :
+           (STREAM_ID_FIRST_ <= StreamId && StreamId < STREAM_ID_LAST_);
+  default:
+    return StreamId == STREAM_ID_NONE_;
+  }
+}
+
+bool msgRequiresOp(int64_t MsgId) {
+  return MsgId == ID_GS || MsgId == ID_GS_DONE || MsgId == ID_SYSMSG;
+}
+
+bool msgSupportsStream(int64_t MsgId, int64_t OpId) {
+  return (MsgId == ID_GS || MsgId == ID_GS_DONE) && OpId != OP_GS_NOP;
+}
+
+void decodeMsg(unsigned Val,
+               uint16_t &MsgId,
+               uint16_t &OpId,
+               uint16_t &StreamId) {
+  MsgId = Val & ID_MASK_;
+  OpId = (Val & OP_MASK_) >> OP_SHIFT_;
+  StreamId = (Val & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_;
+}
+
+int64_t encodeMsg(int64_t MsgId,
+                  int64_t OpId,
+                  int64_t StreamId) {
+  return (MsgId << ID_SHIFT_) |
+         (OpId << OP_SHIFT_) |
+         (StreamId << STREAM_ID_SHIFT_);
+}
+
+} // namespace SendMsg
+
+//===----------------------------------------------------------------------===//
 //
 //===----------------------------------------------------------------------===//
 

Modified: llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h (original)
+++ llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h Fri Jun 28 07:14:02 2019
@@ -448,6 +448,48 @@ void decodeHwreg(unsigned Val, unsigned
 
 } // namespace Hwreg
 
+namespace SendMsg {
+
+LLVM_READONLY
+int64_t getMsgId(const StringRef Name);
+
+LLVM_READONLY
+int64_t getMsgOpId(int64_t MsgId, const StringRef Name);
+
+LLVM_READNONE
+StringRef getMsgName(int64_t MsgId);
+
+LLVM_READNONE
+StringRef getMsgOpName(int64_t MsgId, int64_t OpId);
+
+LLVM_READNONE
+bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI, bool Strict = true);
+
+LLVM_READNONE
+bool isValidMsgOp(int64_t MsgId, int64_t OpId, bool Strict = true);
+
+LLVM_READNONE
+bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, bool Strict = true);
+
+LLVM_READNONE
+bool msgRequiresOp(int64_t MsgId);
+
+LLVM_READNONE
+bool msgSupportsStream(int64_t MsgId, int64_t OpId);
+
+void decodeMsg(unsigned Val,
+               uint16_t &MsgId,
+               uint16_t &OpId,
+               uint16_t &StreamId);
+
+LLVM_READNONE
+int64_t encodeMsg(int64_t MsgId,
+                  int64_t OpId,
+                  int64_t StreamId);
+
+} // namespace SendMsg
+
+
 unsigned getInitialPSInputAddr(const Function &F);
 
 LLVM_READNONE

Modified: llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.sendmsg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.sendmsg.ll?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.sendmsg.ll (original)
+++ llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.sendmsg.ll Fri Jun 28 07:14:02 2019
@@ -56,7 +56,7 @@ body:
 ; GCN: s_mov_b32 m0, s0
 ; GCN-NOT: s_mov_b32 m0
 ; VIPLUS-NEXT: s_nop 0
-; SIVI: s_sendmsg 9
+; SIVI: s_sendmsg sendmsg(9, 0, 0)
 ; GFX9: s_sendmsg sendmsg(MSG_GS_ALLOC_REQ)
 define amdgpu_kernel void @test_gs_alloc_req(i32 inreg %a) {
 body:

Modified: llvm/trunk/test/MC/AMDGPU/sopp-err.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/sopp-err.s?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/sopp-err.s (original)
+++ llvm/trunk/test/MC/AMDGPU/sopp-err.s Fri Jun 28 07:14:02 2019
@@ -3,83 +3,112 @@
 // RUN: not llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=VI --check-prefix=SICIVI %s
 // RUN: not llvm-mc -arch=amdgcn -mcpu=gfx1010 -show-encoding %s 2>&1 | FileCheck --check-prefix=GCN %s
 
-s_sendmsg sendmsg(11)
-// GCN: error: invalid/unsupported code of message
+//===----------------------------------------------------------------------===//
+// sendmsg
+//===----------------------------------------------------------------------===//
 
 s_sendmsg sendmsg(MSG_INTERRUPTX)
-// GCN: error: invalid/unsupported symbolic name of message
+// GCN: error: expected absolute expression
+
+s_sendmsg sendmsg(1 -)
+// GCN: error: unknown token in expression
 
 s_sendmsg sendmsg(MSG_INTERRUPT, 0)
-// GCN: error: failed parsing operand
+// GCN: error: message does not support operations
+
+s_sendmsg sendmsg(MSG_INTERRUPT, 0, 0)
+// GCN: error: message does not support operations
 
 s_sendmsg sendmsg(MSG_GS)
-// GCN: error: failed parsing operand
+// GCN: error: missing message operation
 
 s_sendmsg sendmsg(MSG_GS, GS_OP_NOP)
-// GCN: error: invalid GS_OP: NOP is for GS_DONE only
+// GCN: error: invalid operation id
+
+s_sendmsg sendmsg(MSG_GS, SYSMSG_OP_ECC_ERR_INTERRUPT)
+// GCN: error: expected absolute expression
+
+s_sendmsg sendmsg(MSG_GS, 0)
+// GCN: error: invalid operation id
+
+s_sendmsg sendmsg(MSG_GS, -1)
+// GCN: error: invalid operation id
+
+s_sendmsg sendmsg(MSG_GS, 4)
+// GCN: error: invalid operation id
+
+s_sendmsg sendmsg(MSG_GS, 8)
+// GCN: error: invalid operation id
+
+s_sendmsg sendmsg(15, -1)
+// GCN: error: invalid operation id
+
+s_sendmsg sendmsg(15, 8)
+// GCN: error: invalid operation id
 
 s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0, 0)
-// GCN: error: failed parsing operand
+// GCN: error: expected a closing parenthesis
 
 s_sendmsg sendmsg(MSG_GSX, GS_OP_CUT, 0)
-// GCN: error: invalid/unsupported symbolic name of message
+// GCN: error: expected absolute expression
 
 s_sendmsg sendmsg(MSG_GS, GS_OP_CUTX, 0)
-// GCN: error: invalid symbolic name of GS_OP
+// GCN: error: expected absolute expression
 
-s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 4)
-// GCN: error: invalid stream id: only 2-bit values are legal
+s_sendmsg sendmsg(MSG_GS, 1 -)
+// GCN: error: unknown token in expression
 
-s_sendmsg sendmsg(2)
-// GCN: error: failed parsing operand
+s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 4)
+// GCN: error: invalid message stream id
 
-s_sendmsg sendmsg(2, 0)
-// GCN: error: invalid GS_OP: NOP is for GS_DONE only
+s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 1 -)
+// GCN: error: unknown token in expression
 
 s_sendmsg sendmsg(2, 3, 0, 0)
-// GCN: error: failed parsing operand
+// GCN: error: expected a closing parenthesis
 
-s_sendmsg sendmsg(2, 4, 1)
-// GCN: error: invalid code of GS_OP: only 2-bit values are legal
+s_sendmsg sendmsg(2, 2, -1)
+// GCN: error: invalid message stream id
 
 s_sendmsg sendmsg(2, 2, 4)
-// GCN: error: invalid stream id: only 2-bit values are legal
+// GCN: error: invalid message stream id
 
 s_sendmsg sendmsg(2, 2, 0, 0)
-// GCN: error: failed parsing operand
+// GCN: error: expected a closing parenthesis
 
 s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0)
-// GCN: error: failed parsing operand
+// GCN: error: message operation does not support streams
+
+s_sendmsg sendmsg(MSG_GS_DONE, 0, 0)
+// GCN: error: message operation does not support streams
 
 s_sendmsg sendmsg(MSG_GS_ALLOC_REQ)
-// SICIVI: error: invalid/unsupported symbolic name of message
+// SICIVI: error: invalid message id
 
 s_sendmsg sendmsg(MSG_GS_ALLOC_REQ, 0)
-// SICIVI: error: invalid/unsupported symbolic name of message
+// SICIVI: error: invalid message id
 
-s_sendmsg sendmsg(15)
-// GCN: error: failed parsing operand
+s_sendmsg sendmsg(-1)
+// SICIVI: error: invalid message id
 
-s_sendmsg sendmsg(15, 1, 0)
-// GCN: error: failed parsing operand
-
-s_sendmsg sendmsg(15, 0)
-// GCN: error: invalid/unsupported code of SYSMSG_OP
-
-s_sendmsg sendmsg(15, 5)
-// GCN: error: invalid/unsupported code of SYSMSG_OP
+s_sendmsg sendmsg(16)
+// SICIVI: error: invalid message id
 
 s_sendmsg sendmsg(MSG_SYSMSG)
-// GCN: error: failed parsing operand
+// GCN: error: missing message operation
 
 s_sendmsg sendmsg(MSG_SYSMSG, SYSMSG_OP_ECC_ERR_INTERRUPT, 0)
-// GCN: error: failed parsing operand
+// GCN: error: message operation does not support streams
 
 s_sendmsg sendmsg(MSG_SYSMSG, 0)
-// GCN: error: invalid/unsupported code of SYSMSG_OP
+// GCN: error: invalid operation id
 
 s_sendmsg sendmsg(MSG_SYSMSG, 5)
-// GCN: error: invalid/unsupported code of SYSMSG_OP
+// GCN: error: invalid operation id
+
+//===----------------------------------------------------------------------===//
+// waitcnt
+//===----------------------------------------------------------------------===//
 
 s_waitcnt lgkmcnt(16)
 // SICIVI: error: too large value for lgkmcnt

Modified: llvm/trunk/test/MC/AMDGPU/sopp.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/sopp.s?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/sopp.s (original)
+++ llvm/trunk/test/MC/AMDGPU/sopp.s Fri Jun 28 07:14:02 2019
@@ -167,8 +167,9 @@ s_sleep 10
 s_setprio 1
 // GCN: s_setprio 1 ; encoding: [0x01,0x00,0x8f,0xbf]
 
-s_sendmsg 2
-// GCN: s_sendmsg 2 ; encoding: [0x02,0x00,0x90,0xbf]
+//===----------------------------------------------------------------------===//
+// s_sendmsg
+//===----------------------------------------------------------------------===//
 
 s_sendmsg 0x1
 // GCN: s_sendmsg sendmsg(MSG_INTERRUPT) ; encoding: [0x01,0x00,0x90,0xbf]
@@ -185,9 +186,21 @@ s_sendmsg 0x12
 s_sendmsg sendmsg(2, 1)
 // GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0) ; encoding: [0x12,0x00,0x90,0xbf]
 
+s_sendmsg sendmsg(2, GS_OP_CUT)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0) ; encoding: [0x12,0x00,0x90,0xbf]
+
+s_sendmsg sendmsg(MSG_GS, GS_OP_CUT)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0) ; encoding: [0x12,0x00,0x90,0xbf]
+
 s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0)
 // GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0) ; encoding: [0x12,0x00,0x90,0xbf]
 
+s_sendmsg sendmsg(MSG_GS, 1)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0) ; encoding: [0x12,0x00,0x90,0xbf]
+
+s_sendmsg sendmsg(MSG_GS, 1, 1)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 1) ; encoding: [0x12,0x01,0x90,0xbf]
+
 s_sendmsg 0x122
 // GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_EMIT, 1) ; encoding: [0x22,0x01,0x90,0xbf]
 
@@ -215,15 +228,6 @@ s_sendmsg sendmsg(3, 0)
 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
-// GCN: s_sendmsg 4 ; encoding: [0x04,0x00,0x90,0xbf]
-
-s_sendmsg 9
-// GCN: s_sendmsg 9 ; encoding: [0x09,0x00,0x90,0xbf]
-
-s_sendmsg 11
-// GCN: s_sendmsg 11 ; encoding: [0x0b,0x00,0x90,0xbf]
-
 s_sendmsg 0x1f
 // GCN: s_sendmsg sendmsg(MSG_SYSMSG, SYSMSG_OP_ECC_ERR_INTERRUPT) ; encoding: [0x1f,0x00,0x90,0xbf]
 
@@ -233,15 +237,109 @@ s_sendmsg sendmsg(15, 1)
 s_sendmsg sendmsg(MSG_SYSMSG, SYSMSG_OP_ECC_ERR_INTERRUPT)
 // GCN: s_sendmsg sendmsg(MSG_SYSMSG, SYSMSG_OP_ECC_ERR_INTERRUPT) ; encoding: [0x1f,0x00,0x90,0xbf]
 
-s_sendmsg 0x6f
-// GCN: s_sendmsg 111 ; encoding: [0x6f,0x00,0x90,0xbf]
-
 s_sendmsghalt 3
 // GCN: s_sendmsghalt sendmsg(MSG_GS_DONE, GS_OP_NOP) ; encoding: [0x03,0x00,0x91,0xbf]
 
 s_sendmsghalt sendmsg(MSG_GS, GS_OP_EMIT, 1)
 // GCN: s_sendmsghalt sendmsg(MSG_GS, GS_OP_EMIT, 1) ; encoding: [0x22,0x01,0x91,0xbf]
 
+//===----------------------------------------------------------------------===//
+// s_sendmsg with a numeric message id (no validation)
+//===----------------------------------------------------------------------===//
+
+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]
+
+s_sendmsg 11
+// GCN: s_sendmsg sendmsg(11, 0, 0) ; encoding: [0x0b,0x00,0x90,0xbf]
+
+s_sendmsg 0x6f
+// GCN: s_sendmsg sendmsg(15, 6, 0) ; encoding: [0x6f,0x00,0x90,0xbf]
+
+s_sendmsg sendmsg(1, 3)
+// GCN: s_sendmsg sendmsg(1, 3, 0)      ; encoding: [0x31,0x00,0x90,0xbf]
+
+s_sendmsg sendmsg(1, 3, 2)
+// GCN: s_sendmsg sendmsg(1, 3, 2)      ; encoding: [0x31,0x02,0x90,0xbf]
+
+s_sendmsg sendmsg(2, 0, 1)
+// GCN: s_sendmsg sendmsg(2, 0, 1)      ; encoding: [0x02,0x01,0x90,0xbf]
+
+s_sendmsg sendmsg(15, 7, 3)
+// GCN: s_sendmsg sendmsg(15, 7, 3)     ; encoding: [0x7f,0x03,0x90,0xbf]
+
+s_sendmsg 4567
+// GCN: s_sendmsg 4567                  ; encoding: [0xd7,0x11,0x90,0xbf]
+
+//===----------------------------------------------------------------------===//
+// s_sendmsg with expressions
+//===----------------------------------------------------------------------===//
+
+sendmsg=2
+s_sendmsg sendmsg
+// GCN: s_sendmsg sendmsg(2, 0, 0) ; encoding: [0x02,0x00,0x90,0xbf]
+
+sendmsg=1
+s_sendmsg sendmsg+1
+// GCN: s_sendmsg sendmsg(2, 0, 0) ; encoding: [0x02,0x00,0x90,0xbf]
+
+s_sendmsg 1+sendmsg
+// GCN: s_sendmsg sendmsg(2, 0, 0) ; encoding: [0x02,0x00,0x90,0xbf]
+
+msg=1
+s_sendmsg sendmsg(msg)
+// GCN: s_sendmsg sendmsg(MSG_INTERRUPT) ; encoding: [0x01,0x00,0x90,0xbf]
+
+msg=0
+s_sendmsg sendmsg(msg+1)
+// GCN: s_sendmsg sendmsg(MSG_INTERRUPT) ; encoding: [0x01,0x00,0x90,0xbf]
+
+msg=0
+s_sendmsg sendmsg(1+msg)
+// GCN: s_sendmsg sendmsg(MSG_INTERRUPT) ; encoding: [0x01,0x00,0x90,0xbf]
+
+msg=2
+op=1
+s_sendmsg sendmsg(msg, op)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0) ; encoding: [0x12,0x00,0x90,0xbf]
+
+msg=1
+op=0
+s_sendmsg sendmsg(msg+1, op+1)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0) ; encoding: [0x12,0x00,0x90,0xbf]
+
+msg=1
+op=0
+s_sendmsg sendmsg(1+msg, 1+op)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 0) ; encoding: [0x12,0x00,0x90,0xbf]
+
+msg=1
+op=2
+stream=1
+s_sendmsg sendmsg(msg+1, op+1, stream+1)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_EMIT_CUT, 2) ; encoding: [0x32,0x02,0x90,0xbf]
+
+msg=1
+op=2
+stream=1
+s_sendmsg sendmsg(1+msg, 1+op, 1+stream)
+// GCN: s_sendmsg sendmsg(MSG_GS, GS_OP_EMIT_CUT, 2) ; encoding: [0x32,0x02,0x90,0xbf]
+
+MSG_GS=-1
+GS_OP_EMIT=-1
+s_sendmsghalt sendmsg(MSG_GS, GS_OP_EMIT, 1)
+// GCN: s_sendmsghalt sendmsg(MSG_GS, GS_OP_EMIT, 1) ; encoding: [0x22,0x01,0x91,0xbf]
+
+//===----------------------------------------------------------------------===//
+// misc sopp instructions
+//===----------------------------------------------------------------------===//
+
 s_trap 4
 // GCN: s_trap 4 ; encoding: [0x04,0x00,0x92,0xbf]
 

Modified: llvm/trunk/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt (original)
+++ llvm/trunk/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt Fri Jun 28 07:14:02 2019
@@ -18113,7 +18113,7 @@
 # GFX10: s_scratch_store_dwordx4 s[4:7], s[4:5], s0 glc ; encoding: [0x02,0x01,0x5d,0xf4,0x00,0x00,0x00,0x00]
 0x02,0x01,0x5d,0xf4,0x00,0x00,0x00,0x00
 
-# GFX10: s_sendmsg 0                     ; encoding: [0x00,0x00,0x90,0xbf]
+# GFX10: s_sendmsg sendmsg(0, 0, 0)      ; encoding: [0x00,0x00,0x90,0xbf]
 0x00,0x00,0x90,0xbf
 
 # GFX10: s_sendmsg 4660                  ; encoding: [0x34,0x12,0x90,0xbf]
@@ -18122,7 +18122,7 @@
 # GFX10: s_sendmsg 49617                 ; encoding: [0xd1,0xc1,0x90,0xbf]
 0xd1,0xc1,0x90,0xbf
 
-# GFX10: s_sendmsghalt 0                 ; encoding: [0x00,0x00,0x91,0xbf]
+# GFX10: s_sendmsghalt sendmsg(0, 0, 0)  ; encoding: [0x00,0x00,0x91,0xbf]
 0x00,0x00,0x91,0xbf
 
 # GFX10: s_sendmsghalt 4660              ; encoding: [0x34,0x12,0x91,0xbf]

Modified: llvm/trunk/test/MC/Disassembler/AMDGPU/sopp_vi.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/AMDGPU/sopp_vi.txt?rev=364645&r1=364644&r2=364645&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/AMDGPU/sopp_vi.txt (original)
+++ llvm/trunk/test/MC/Disassembler/AMDGPU/sopp_vi.txt Fri Jun 28 07:14:02 2019
@@ -75,7 +75,7 @@
 # GCN: s_setprio 1 ; encoding: [0x01,0x00,0x8f,0xbf]
 0x01 0x00 0x8f 0xbf
 
-# GCN: s_sendmsg 2 ; encoding: [0x02,0x00,0x90,0xbf]
+# GCN: s_sendmsg sendmsg(2, 0, 0) ; encoding: [0x02,0x00,0x90,0xbf]
 0x02 0x00 0x90 0xbf
 
 # GCN: s_sendmsg sendmsg(MSG_INTERRUPT) ; encoding: [0x01,0x00,0x90,0xbf]
@@ -93,13 +93,13 @@
 # GCN: s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP) ; encoding: [0x03,0x00,0x90,0xbf]
 0x03 0x00 0x90 0xbf
 
-# GCN: s_sendmsg 11 ; encoding: [0x0b,0x00,0x90,0xbf]
+# GCN: s_sendmsg sendmsg(11, 0, 0) ; encoding: [0x0b,0x00,0x90,0xbf]
 0x0b 0x00 0x90 0xbf
 
 # GCN: s_sendmsg sendmsg(MSG_SYSMSG, SYSMSG_OP_ECC_ERR_INTERRUPT) ; encoding: [0x1f,0x00,0x90,0xbf]
 0x1f 0x00 0x90 0xbf
 
-# GCN: s_sendmsg 111 ; encoding: [0x6f,0x00,0x90,0xbf]
+# GCN: s_sendmsg sendmsg(15, 6, 0) ; encoding: [0x6f,0x00,0x90,0xbf]
 0x6f 0x00 0x90 0xbf
 
 # GCN: s_sendmsghalt sendmsg(MSG_GS_DONE, GS_OP_NOP) ; encoding: [0x03,0x00,0x91,0xbf]
@@ -108,9 +108,24 @@
 # GCN: s_sendmsghalt sendmsg(MSG_GS, GS_OP_EMIT, 1) ; encoding: [0x22,0x01,0x91,0xbf]
 0x22 0x01 0x91 0xbf
 
-# GCN: s_sendmsghalt 111 ; encoding: [0x6f,0x00,0x91,0xbf]
+# GCN: s_sendmsghalt sendmsg(15, 6, 0) ; encoding: [0x6f,0x00,0x91,0xbf]
 0x6f 0x00 0x91 0xbf
 
+# GCN: s_sendmsg sendmsg(1, 3, 0)      ; encoding: [0x31,0x00,0x90,0xbf]
+0x31 0x00 0x90 0xbf
+
+# GCN: s_sendmsg sendmsg(1, 3, 2)      ; encoding: [0x31,0x02,0x90,0xbf]
+0x31 0x02 0x90 0xbf
+
+# GCN: s_sendmsg sendmsg(2, 0, 1)      ; encoding: [0x02,0x01,0x90,0xbf]
+0x02 0x01 0x90 0xbf
+
+# GCN: s_sendmsg sendmsg(15, 7, 3)     ; encoding: [0x7f,0x03,0x90,0xbf]
+0x7f 0x03 0x90 0xbf
+
+# GCN: s_sendmsg 4567                  ; encoding: [0xd7,0x11,0x90,0xbf]
+0xd7 0x11 0x90 0xbf
+
 # GCN: s_trap 4 ; encoding: [0x04,0x00,0x92,0xbf]
 0x04 0x00 0x92 0xbf
 




More information about the llvm-commits mailing list