1212namespace llvm {
1313namespace AMDGPU {
1414
15+ // ===----------------------------------------------------------------------===//
16+ // Custom Operands.
17+ //
18+ // A table of custom operands shall describe "primary" operand names first
19+ // followed by aliases if any. It is not required but recommended to arrange
20+ // operands so that operand encoding match operand position in the table. This
21+ // will make getNameFromOperandTable() a bit more efficient. Unused slots in the
22+ // table shall have an empty name.
23+ //
24+ // ===----------------------------------------------------------------------===//
25+
26+ // / Map from the encoding of a sendmsg/hwreg asm operand to it's name.
27+ template <size_t N>
28+ static StringRef getNameFromOperandTable (const CustomOperand (&Table)[N],
29+ unsigned Encoding,
30+ const MCSubtargetInfo &STI) {
31+ auto isValidIndexForEncoding = [&](size_t Idx) {
32+ return Idx < N && Table[Idx].Encoding == Encoding &&
33+ !Table[Idx].Name .empty () &&
34+ (!Table[Idx].Cond || Table[Idx].Cond (STI));
35+ };
36+
37+ // This is an optimization that should work in most cases. As a side effect,
38+ // it may cause selection of an alias instead of a primary operand name in
39+ // case of sparse tables.
40+ if (isValidIndexForEncoding (Encoding))
41+ return Table[Encoding].Name ;
42+
43+ for (size_t Idx = 0 ; Idx != N; ++Idx)
44+ if (isValidIndexForEncoding (Idx))
45+ return Table[Idx].Name ;
46+
47+ return " " ;
48+ }
49+
50+ // / Map from a symbolic name for a sendmsg/hwreg asm operand to it's encoding.
51+ template <size_t N>
52+ static int64_t getEncodingFromOperandTable (const CustomOperand (&Table)[N],
53+ StringRef Name,
54+ const MCSubtargetInfo &STI) {
55+ int64_t InvalidEncoding = OPR_ID_UNKNOWN;
56+ for (const CustomOperand &Entry : Table) {
57+ if (Entry.Name != Name)
58+ continue ;
59+
60+ if (!Entry.Cond || Entry.Cond (STI))
61+ return Entry.Encoding ;
62+
63+ InvalidEncoding = OPR_ID_UNSUPPORTED;
64+ }
65+
66+ return InvalidEncoding;
67+ }
68+
1569namespace DepCtr {
1670
1771// NOLINTBEGIN
@@ -34,10 +88,11 @@ const int DEP_CTR_SIZE =
3488
3589namespace SendMsg {
3690
37- // Disable lint checking for this block since it makes the table unreadable.
91+ // Disable lint checking here since it makes these tables unreadable.
3892// NOLINTBEGIN
3993// clang-format off
40- const CustomOperand<const MCSubtargetInfo &> Msg[] = {
94+
95+ static constexpr CustomOperand MsgOperands[] = {
4196 {{" " }},
4297 {{" MSG_INTERRUPT" }, ID_INTERRUPT},
4398 {{" MSG_GS" }, ID_GS_PreGFX11, isNotGFX11Plus},
@@ -63,27 +118,47 @@ const CustomOperand<const MCSubtargetInfo &> Msg[] = {
63118 {{" MSG_RTN_GET_TBA_TO_PC" }, ID_RTN_GET_TBA_TO_PC, isGFX11Plus},
64119 {{" MSG_RTN_GET_SE_AID_ID" }, ID_RTN_GET_SE_AID_ID, isGFX12Plus},
65120};
121+
122+ static constexpr CustomOperand SysMsgOperands[] = {
123+ {{" " }},
124+ {{" SYSMSG_OP_ECC_ERR_INTERRUPT" }, OP_SYS_ECC_ERR_INTERRUPT},
125+ {{" SYSMSG_OP_REG_RD" }, OP_SYS_REG_RD},
126+ {{" SYSMSG_OP_HOST_TRAP_ACK" }, OP_SYS_HOST_TRAP_ACK, isNotGFX9Plus},
127+ {{" SYSMSG_OP_TTRACE_PC" }, OP_SYS_TTRACE_PC},
128+ };
129+
130+ static constexpr CustomOperand StreamMsgOperands[] = {
131+ {{" GS_OP_NOP" }, OP_GS_NOP},
132+ {{" GS_OP_CUT" }, OP_GS_CUT},
133+ {{" GS_OP_EMIT" }, OP_GS_EMIT},
134+ {{" GS_OP_EMIT_CUT" }, OP_GS_EMIT_CUT},
135+ };
136+
66137// clang-format on
67138// NOLINTEND
68139
69- const int MSG_SIZE = static_cast <int >(
70- sizeof (Msg) / sizeof (CustomOperand<const MCSubtargetInfo &>));
140+ int64_t getMsgId (StringRef Name, const MCSubtargetInfo &STI) {
141+ return getEncodingFromOperandTable (MsgOperands, Name, STI);
142+ }
71143
72- // These two must be in sync with llvm::AMDGPU::SendMsg::Op enum members, see SIDefines.h.
73- const char *const OpSysSymbolic[OP_SYS_LAST_] = {
74- nullptr ,
75- " SYSMSG_OP_ECC_ERR_INTERRUPT" ,
76- " SYSMSG_OP_REG_RD" ,
77- " SYSMSG_OP_HOST_TRAP_ACK" ,
78- " SYSMSG_OP_TTRACE_PC"
79- };
144+ StringRef getMsgName (uint64_t Encoding, const MCSubtargetInfo &STI) {
145+ return getNameFromOperandTable (MsgOperands, Encoding, STI);
146+ }
80147
81- const char *const OpGsSymbolic[OP_GS_LAST_] = {
82- " GS_OP_NOP" ,
83- " GS_OP_CUT" ,
84- " GS_OP_EMIT" ,
85- " GS_OP_EMIT_CUT"
86- };
148+ int64_t getMsgOpId (int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI) {
149+ if (MsgId == ID_SYSMSG)
150+ return getEncodingFromOperandTable (SysMsgOperands, Name, STI);
151+ return getEncodingFromOperandTable (StreamMsgOperands, Name, STI);
152+ }
153+
154+ StringRef getMsgOpName (int64_t MsgId, uint64_t Encoding,
155+ const MCSubtargetInfo &STI) {
156+ assert (msgRequiresOp (MsgId, STI) && " must have an operand" );
157+
158+ if (MsgId == ID_SYSMSG)
159+ return getNameFromOperandTable (SysMsgOperands, Encoding, STI);
160+ return getNameFromOperandTable (StreamMsgOperands, Encoding, STI);
161+ }
87162
88163} // namespace SendMsg
89164
@@ -92,7 +167,7 @@ namespace Hwreg {
92167// Disable lint checking for this block since it makes the table unreadable.
93168// NOLINTBEGIN
94169// clang-format off
95- const CustomOperand< const MCSubtargetInfo &> Opr [] = {
170+ static constexpr CustomOperand Operands [] = {
96171 {{" " }},
97172 {{" HW_REG_MODE" }, ID_MODE},
98173 {{" HW_REG_STATUS" }, ID_STATUS},
@@ -155,8 +230,13 @@ const CustomOperand<const MCSubtargetInfo &> Opr[] = {
155230// clang-format on
156231// NOLINTEND
157232
158- const int OPR_SIZE = static_cast <int >(
159- sizeof (Opr) / sizeof (CustomOperand<const MCSubtargetInfo &>));
233+ int64_t getHwregId (StringRef Name, const MCSubtargetInfo &STI) {
234+ return getEncodingFromOperandTable (Operands, Name, STI);
235+ }
236+
237+ StringRef getHwreg (uint64_t Encoding, const MCSubtargetInfo &STI) {
238+ return getNameFromOperandTable (Operands, Encoding, STI);
239+ }
160240
161241} // namespace Hwreg
162242
0 commit comments