1//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9def isWave32 : Predicate<"Subtarget->getWavefrontSize() == 32">,
10  AssemblerPredicate <"FeatureWavefrontSize32">;
11def isWave64 : Predicate<"Subtarget->getWavefrontSize() == 64">,
12  AssemblerPredicate <"FeatureWavefrontSize64">;
13
14def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">;
15
16class GCNPredicateControl : PredicateControl {
17  Predicate SIAssemblerPredicate = isGFX6GFX7;
18  Predicate VIAssemblerPredicate = isGFX8GFX9;
19}
20
21// Execpt for the NONE field, this must be kept in sync with the
22// SIEncodingFamily enum in AMDGPUInstrInfo.cpp
23def SIEncodingFamily {
24  int NONE = -1;
25  int SI = 0;
26  int VI = 1;
27  int SDWA = 2;
28  int SDWA9 = 3;
29  int GFX80 = 4;
30  int GFX9 = 5;
31  int GFX10 = 6;
32  int SDWA10 = 7;
33}
34
35//===----------------------------------------------------------------------===//
36// SI DAG Nodes
37//===----------------------------------------------------------------------===//
38
39def AMDGPUclamp : SDNode<"AMDGPUISD::CLAMP", SDTFPUnaryOp>;
40
41def SIsbuffer_load : SDNode<"AMDGPUISD::SBUFFER_LOAD",
42  SDTypeProfile<1, 4, [SDTCisVT<1, v4i32>, SDTCisVT<2, i32>, SDTCisVT<3, i1>,
43                       SDTCisVT<4, i1>]>,
44  [SDNPMayLoad, SDNPMemOperand]
45>;
46
47def SIds_ordered_count : SDNode<"AMDGPUISD::DS_ORDERED_COUNT",
48  SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i16>]>,
49  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain, SDNPInGlue]
50>;
51
52def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2,
53  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
54>;
55
56def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2,
57  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
58>;
59
60def SDTAtomic2_f32 : SDTypeProfile<1, 2, [
61  SDTCisSameAs<0,2>, SDTCisFP<0>, SDTCisPtrTy<1>
62]>;
63
64def SIatomic_fmin : SDNode<"AMDGPUISD::ATOMIC_LOAD_FMIN", SDTAtomic2_f32,
65  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
66>;
67
68def SIatomic_fmax : SDNode<"AMDGPUISD::ATOMIC_LOAD_FMAX", SDTAtomic2_f32,
69  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
70>;
71
72// load_d16_{lo|hi} ptr, tied_input
73def SIload_d16 : SDTypeProfile<1, 2, [
74  SDTCisPtrTy<1>,
75  SDTCisSameAs<0, 2>
76]>;
77
78
79def SDTtbuffer_load : SDTypeProfile<1, 8,
80  [                     // vdata
81   SDTCisVT<1, v4i32>,  // rsrc
82   SDTCisVT<2, i32>,    // vindex(VGPR)
83   SDTCisVT<3, i32>,    // voffset(VGPR)
84   SDTCisVT<4, i32>,    // soffset(SGPR)
85   SDTCisVT<5, i32>,    // offset(imm)
86   SDTCisVT<6, i32>,    // format(imm)
87   SDTCisVT<7, i32>,    // cachecontrol(imm)
88   SDTCisVT<8, i1>      // idxen(imm)
89  ]>;
90
91def SItbuffer_load :   SDNode<"AMDGPUISD::TBUFFER_LOAD_FORMAT", SDTtbuffer_load,
92                              [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]>;
93def SItbuffer_load_d16 : SDNode<"AMDGPUISD::TBUFFER_LOAD_FORMAT_D16",
94                                SDTtbuffer_load,
95                                [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]>;
96
97def SDTtbuffer_store : SDTypeProfile<0, 9,
98    [                     // vdata
99     SDTCisVT<1, v4i32>,  // rsrc
100     SDTCisVT<2, i32>,    // vindex(VGPR)
101     SDTCisVT<3, i32>,    // voffset(VGPR)
102     SDTCisVT<4, i32>,    // soffset(SGPR)
103     SDTCisVT<5, i32>,    // offset(imm)
104     SDTCisVT<6, i32>,    // format(imm)
105     SDTCisVT<7, i32>,    // cachecontrol(imm)
106     SDTCisVT<8, i1>      // idxen(imm)
107    ]>;
108
109def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT", SDTtbuffer_store,
110                             [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
111def SItbuffer_store_d16 : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT_D16",
112                                SDTtbuffer_store,
113                                [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
114
115def SDTBufferLoad : SDTypeProfile<1, 7,
116    [                    // vdata
117     SDTCisVT<1, v4i32>, // rsrc
118     SDTCisVT<2, i32>,   // vindex(VGPR)
119     SDTCisVT<3, i32>,   // voffset(VGPR)
120     SDTCisVT<4, i32>,   // soffset(SGPR)
121     SDTCisVT<5, i32>,   // offset(imm)
122     SDTCisVT<6, i32>,   // cachepolicy(imm)
123     SDTCisVT<7, i1>]>;  // idxen(imm)
124
125def SIbuffer_load : SDNode <"AMDGPUISD::BUFFER_LOAD", SDTBufferLoad,
126                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
127def SIbuffer_load_ubyte : SDNode <"AMDGPUISD::BUFFER_LOAD_UBYTE", SDTBufferLoad,
128                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
129def SIbuffer_load_ushort : SDNode <"AMDGPUISD::BUFFER_LOAD_USHORT", SDTBufferLoad,
130                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
131def SIbuffer_load_byte : SDNode <"AMDGPUISD::BUFFER_LOAD_BYTE", SDTBufferLoad,
132                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
133def SIbuffer_load_short: SDNode <"AMDGPUISD::BUFFER_LOAD_SHORT", SDTBufferLoad,
134                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
135def SIbuffer_load_format : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT", SDTBufferLoad,
136                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
137def SIbuffer_load_format_d16 : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT_D16",
138                                SDTBufferLoad,
139                                [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
140
141def SDTBufferStore : SDTypeProfile<0, 8,
142    [                    // vdata
143     SDTCisVT<1, v4i32>, // rsrc
144     SDTCisVT<2, i32>,   // vindex(VGPR)
145     SDTCisVT<3, i32>,   // voffset(VGPR)
146     SDTCisVT<4, i32>,   // soffset(SGPR)
147     SDTCisVT<5, i32>,   // offset(imm)
148     SDTCisVT<6, i32>,   // cachepolicy(imm)
149     SDTCisVT<7, i1>]>;  // idxen(imm)
150
151def SIbuffer_store : SDNode <"AMDGPUISD::BUFFER_STORE", SDTBufferStore,
152                             [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
153def SIbuffer_store_byte: SDNode <"AMDGPUISD::BUFFER_STORE_BYTE",
154                         SDTBufferStore,
155                         [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
156def SIbuffer_store_short : SDNode <"AMDGPUISD::BUFFER_STORE_SHORT",
157                           SDTBufferStore,
158                           [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
159def SIbuffer_store_format : SDNode <"AMDGPUISD::BUFFER_STORE_FORMAT",
160                            SDTBufferStore,
161                            [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
162def SIbuffer_store_format_d16 : SDNode <"AMDGPUISD::BUFFER_STORE_FORMAT_D16",
163                            SDTBufferStore,
164                            [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
165
166class SDBufferAtomic<string opcode> : SDNode <opcode,
167  SDTypeProfile<1, 8,
168       [SDTCisVT<2, v4i32>, // rsrc
169       SDTCisVT<3, i32>,   // vindex(VGPR)
170       SDTCisVT<4, i32>,   // voffset(VGPR)
171       SDTCisVT<5, i32>,   // soffset(SGPR)
172       SDTCisVT<6, i32>,   // offset(imm)
173       SDTCisVT<7, i32>,   // cachepolicy(imm)
174       SDTCisVT<8, i1>]>,  // idxen(imm)
175  [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore]
176>;
177
178class SDBufferAtomicNoRtn<string opcode, ValueType ty> : SDNode <opcode,
179  SDTypeProfile<0, 8,
180      [SDTCisVT<0, ty>,    // vdata
181       SDTCisVT<1, v4i32>, // rsrc
182       SDTCisVT<2, i32>,   // vindex(VGPR)
183       SDTCisVT<3, i32>,   // voffset(VGPR)
184       SDTCisVT<4, i32>,   // soffset(SGPR)
185       SDTCisVT<5, i32>,   // offset(imm)
186       SDTCisVT<6, i32>,   // cachepolicy(imm)
187       SDTCisVT<7, i1>]>,  // idxen(imm)
188  [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore]
189>;
190
191def SIbuffer_atomic_swap : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SWAP">;
192def SIbuffer_atomic_add : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_ADD">;
193def SIbuffer_atomic_sub : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SUB">;
194def SIbuffer_atomic_smin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SMIN">;
195def SIbuffer_atomic_umin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_UMIN">;
196def SIbuffer_atomic_smax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SMAX">;
197def SIbuffer_atomic_umax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_UMAX">;
198def SIbuffer_atomic_and : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_AND">;
199def SIbuffer_atomic_or : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_OR">;
200def SIbuffer_atomic_xor : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_XOR">;
201def SIbuffer_atomic_fadd : SDBufferAtomicNoRtn <"AMDGPUISD::BUFFER_ATOMIC_FADD", f32>;
202def SIbuffer_atomic_pk_fadd : SDBufferAtomicNoRtn <"AMDGPUISD::BUFFER_ATOMIC_PK_FADD", v2f16>;
203
204def SIbuffer_atomic_cmpswap : SDNode <"AMDGPUISD::BUFFER_ATOMIC_CMPSWAP",
205  SDTypeProfile<1, 9,
206    [SDTCisVT<0, i32>,   // dst
207     SDTCisVT<1, i32>,   // src
208     SDTCisVT<2, i32>,   // cmp
209     SDTCisVT<3, v4i32>, // rsrc
210     SDTCisVT<4, i32>,   // vindex(VGPR)
211     SDTCisVT<5, i32>,   // voffset(VGPR)
212     SDTCisVT<6, i32>,   // soffset(SGPR)
213     SDTCisVT<7, i32>,   // offset(imm)
214     SDTCisVT<8, i32>,   // cachepolicy(imm)
215     SDTCisVT<9, i1>]>,  // idxen(imm)
216  [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore]
217>;
218
219class SDGlobalAtomicNoRtn<string opcode, ValueType ty> : SDNode <opcode,
220  SDTypeProfile<0, 2,
221      [SDTCisPtrTy<0>,     // vaddr
222       SDTCisVT<1, ty>]>,  // vdata
223  [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore]
224>;
225
226def SIglobal_atomic_fadd    : SDGlobalAtomicNoRtn <"AMDGPUISD::ATOMIC_FADD", f32>;
227def SIglobal_atomic_pk_fadd : SDGlobalAtomicNoRtn <"AMDGPUISD::ATOMIC_PK_FADD", v2f16>;
228
229def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET",
230  SDTypeProfile<1, 2, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]>
231>;
232
233def SIlds : SDNode<"AMDGPUISD::LDS",
234  SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>]>
235>;
236
237def SIload_d16_lo : SDNode<"AMDGPUISD::LOAD_D16_LO",
238  SIload_d16,
239  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
240>;
241
242def SIload_d16_lo_u8 : SDNode<"AMDGPUISD::LOAD_D16_LO_U8",
243  SIload_d16,
244  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
245>;
246
247def SIload_d16_lo_i8 : SDNode<"AMDGPUISD::LOAD_D16_LO_I8",
248  SIload_d16,
249  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
250>;
251
252def SIload_d16_hi : SDNode<"AMDGPUISD::LOAD_D16_HI",
253  SIload_d16,
254  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
255>;
256
257def SIload_d16_hi_u8 : SDNode<"AMDGPUISD::LOAD_D16_HI_U8",
258  SIload_d16,
259  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
260>;
261
262def SIload_d16_hi_i8 : SDNode<"AMDGPUISD::LOAD_D16_HI_I8",
263  SIload_d16,
264  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
265>;
266
267//===----------------------------------------------------------------------===//
268// ValueType helpers
269//===----------------------------------------------------------------------===//
270
271// Returns 1 if the source arguments have modifiers, 0 if they do not.
272// XXX - do f16 instructions?
273class isFloatType<ValueType SrcVT> {
274  bit ret =
275    !if(!eq(SrcVT.Value, f16.Value), 1,
276    !if(!eq(SrcVT.Value, f32.Value), 1,
277    !if(!eq(SrcVT.Value, f64.Value), 1,
278    !if(!eq(SrcVT.Value, v2f16.Value), 1,
279    !if(!eq(SrcVT.Value, v4f16.Value), 1,
280    0)))));
281}
282
283class isIntType<ValueType SrcVT> {
284  bit ret =
285    !if(!eq(SrcVT.Value, i16.Value), 1,
286    !if(!eq(SrcVT.Value, i32.Value), 1,
287    !if(!eq(SrcVT.Value, i64.Value), 1,
288    0)));
289}
290
291class isPackedType<ValueType SrcVT> {
292  bit ret =
293    !if(!eq(SrcVT.Value, v2i16.Value), 1,
294      !if(!eq(SrcVT.Value, v2f16.Value), 1,
295        !if(!eq(SrcVT.Value, v4f16.Value), 1, 0)
296    ));
297}
298
299//===----------------------------------------------------------------------===//
300// PatFrags for global memory operations
301//===----------------------------------------------------------------------===//
302
303defm atomic_inc_global : global_binary_atomic_op<SIatomic_inc>;
304defm atomic_dec_global : global_binary_atomic_op<SIatomic_dec>;
305
306def atomic_inc_local : local_binary_atomic_op<SIatomic_inc>;
307def atomic_dec_local : local_binary_atomic_op<SIatomic_dec>;
308def atomic_load_fadd_local : local_binary_atomic_op<atomic_load_fadd>;
309def atomic_load_fmin_local : local_binary_atomic_op<SIatomic_fmin>;
310def atomic_load_fmax_local : local_binary_atomic_op<SIatomic_fmax>;
311
312//===----------------------------------------------------------------------===//
313// SDNodes PatFrags for loads/stores with a glue input.
314// This is for SDNodes and PatFrag for local loads and stores to
315// enable s_mov_b32 m0, -1 to be glued to the memory instructions.
316//
317// These mirror the regular load/store PatFrags and rely on special
318// processing during Select() to add the glued copy.
319//
320//===----------------------------------------------------------------------===//
321
322def AMDGPUld_glue : SDNode <"ISD::LOAD", SDTLoad,
323  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
324>;
325
326def AMDGPUatomic_ld_glue : SDNode <"ISD::ATOMIC_LOAD", SDTAtomicLoad,
327  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
328>;
329
330def unindexedload_glue : PatFrag <(ops node:$ptr), (AMDGPUld_glue node:$ptr)> {
331  let IsUnindexed = 1;
332}
333
334def load_glue : PatFrag <(ops node:$ptr), (unindexedload_glue node:$ptr)> {
335  let IsNonExtLoad = 1;
336}
337
338def atomic_load_32_glue : PatFrag<(ops node:$ptr),
339  (AMDGPUatomic_ld_glue node:$ptr)> {
340  let IsAtomic = 1;
341  let MemoryVT = i32;
342}
343
344def atomic_load_64_glue : PatFrag<(ops node:$ptr),
345  (AMDGPUatomic_ld_glue node:$ptr)> {
346  let IsAtomic = 1;
347  let MemoryVT = i64;
348}
349
350def extload_glue : PatFrag<(ops node:$ptr), (load_glue node:$ptr)> {
351  let IsLoad = 1;
352  let IsAnyExtLoad = 1;
353}
354
355def sextload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr), [{
356  return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
357}]>;
358
359def zextload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr)> {
360  let IsLoad = 1;
361  let IsZeroExtLoad = 1;
362}
363
364def extloadi8_glue : PatFrag<(ops node:$ptr), (extload_glue node:$ptr)> {
365  let IsLoad = 1;
366  let MemoryVT = i8;
367}
368
369def zextloadi8_glue : PatFrag<(ops node:$ptr), (zextload_glue node:$ptr)> {
370  let IsLoad = 1;
371  let MemoryVT = i8;
372}
373
374def extloadi16_glue : PatFrag<(ops node:$ptr), (extload_glue node:$ptr)> {
375  let IsLoad = 1;
376  let MemoryVT = i16;
377}
378
379def zextloadi16_glue : PatFrag<(ops node:$ptr), (zextload_glue node:$ptr)> {
380  let IsLoad = 1;
381  let MemoryVT = i16;
382}
383
384def sextloadi8_glue : PatFrag<(ops node:$ptr), (sextload_glue node:$ptr)> {
385  let IsLoad = 1;
386  let MemoryVT = i8;
387}
388
389def sextloadi16_glue : PatFrag<(ops node:$ptr), (sextload_glue node:$ptr)> {
390  let IsLoad = 1;
391  let MemoryVT = i16;
392}
393
394def load_glue_align8 : Aligned8Bytes <
395  (ops node:$ptr), (load_glue node:$ptr)
396>;
397def load_glue_align16 : Aligned16Bytes <
398  (ops node:$ptr), (load_glue node:$ptr)
399>;
400
401
402def load_local_m0 : LoadFrag<load_glue>, LocalAddress;
403def sextloadi8_local_m0 : LoadFrag<sextloadi8_glue>, LocalAddress;
404def sextloadi16_local_m0 : LoadFrag<sextloadi16_glue>, LocalAddress;
405def extloadi8_local_m0 : LoadFrag<extloadi8_glue>, LocalAddress;
406def zextloadi8_local_m0 : LoadFrag<zextloadi8_glue>, LocalAddress;
407def extloadi16_local_m0 : LoadFrag<extloadi16_glue>, LocalAddress;
408def zextloadi16_local_m0 : LoadFrag<zextloadi16_glue>, LocalAddress;
409def load_align8_local_m0 : LoadFrag <load_glue_align8>, LocalAddress;
410def load_align16_local_m0 : LoadFrag <load_glue_align16>, LocalAddress;
411def atomic_load_32_local_m0 : LoadFrag<atomic_load_32_glue>, LocalAddress;
412def atomic_load_64_local_m0 : LoadFrag<atomic_load_64_glue>, LocalAddress;
413
414
415def AMDGPUst_glue : SDNode <"ISD::STORE", SDTStore,
416  [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
417>;
418
419def AMDGPUatomic_st_glue : SDNode <"ISD::ATOMIC_STORE", SDTAtomicStore,
420  [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
421>;
422
423def atomic_store_glue : PatFrag<(ops node:$ptr, node:$val),
424  (AMDGPUatomic_st_glue node:$ptr, node:$val)> {
425}
426
427def unindexedstore_glue : PatFrag<(ops node:$val, node:$ptr),
428                                   (AMDGPUst_glue node:$val, node:$ptr), [{
429  return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
430}]>;
431
432def store_glue : PatFrag<(ops node:$val, node:$ptr),
433                      (unindexedstore_glue node:$val, node:$ptr), [{
434  return !cast<StoreSDNode>(N)->isTruncatingStore();
435}]>;
436
437def truncstore_glue : PatFrag<(ops node:$val, node:$ptr),
438  (unindexedstore_glue node:$val, node:$ptr), [{
439  return cast<StoreSDNode>(N)->isTruncatingStore();
440}]>;
441
442def truncstorei8_glue : PatFrag<(ops node:$val, node:$ptr),
443                           (truncstore_glue node:$val, node:$ptr), [{
444  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
445}]>;
446
447def truncstorei16_glue : PatFrag<(ops node:$val, node:$ptr),
448                           (truncstore_glue node:$val, node:$ptr), [{
449  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
450}]>;
451
452def store_glue_align8 : Aligned8Bytes <
453  (ops node:$value, node:$ptr), (store_glue node:$value, node:$ptr)
454>;
455
456def store_glue_align16 : Aligned16Bytes <
457  (ops node:$value, node:$ptr), (store_glue node:$value, node:$ptr)
458>;
459
460def store_local_m0 : StoreFrag<store_glue>, LocalAddress;
461def truncstorei8_local_m0 : StoreFrag<truncstorei8_glue>, LocalAddress;
462def truncstorei16_local_m0 : StoreFrag<truncstorei16_glue>, LocalAddress;
463def atomic_store_local_m0 : StoreFrag<AMDGPUatomic_st_glue>, LocalAddress;
464
465def store_align8_local_m0 : StoreFrag<store_glue_align8>, LocalAddress;
466def store_align16_local_m0 : StoreFrag<store_glue_align16>, LocalAddress;
467
468def si_setcc_uniform : PatFrag <
469  (ops node:$lhs, node:$rhs, node:$cond),
470  (setcc node:$lhs, node:$rhs, node:$cond), [{
471  for (SDNode *Use : N->uses()) {
472    if (Use->isMachineOpcode() || Use->getOpcode() != ISD::CopyToReg)
473      return false;
474
475    unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
476    if (Reg != AMDGPU::SCC)
477      return false;
478  }
479  return true;
480}]>;
481
482//===----------------------------------------------------------------------===//
483// SDNodes PatFrags for d16 loads
484//===----------------------------------------------------------------------===//
485
486class LoadD16Frag <SDPatternOperator op> : PatFrag<(ops node:$ptr, node:$tied_in), (op node:$ptr, node:$tied_in)>;
487class LocalLoadD16 <SDPatternOperator op> : LoadD16Frag <op>, LocalAddress;
488class GlobalLoadD16 <SDPatternOperator op> : LoadD16Frag <op>, GlobalLoadAddress;
489class PrivateLoadD16 <SDPatternOperator op> : LoadD16Frag <op>, PrivateAddress;
490class FlatLoadD16 <SDPatternOperator op> : LoadD16Frag <op>, FlatLoadAddress;
491
492def load_d16_hi_local : LocalLoadD16 <SIload_d16_hi>;
493def az_extloadi8_d16_hi_local : LocalLoadD16 <SIload_d16_hi_u8>;
494def sextloadi8_d16_hi_local : LocalLoadD16 <SIload_d16_hi_i8>;
495
496def load_d16_hi_global : GlobalLoadD16 <SIload_d16_hi>;
497def az_extloadi8_d16_hi_global : GlobalLoadD16 <SIload_d16_hi_u8>;
498def sextloadi8_d16_hi_global : GlobalLoadD16 <SIload_d16_hi_i8>;
499
500def load_d16_hi_private : PrivateLoadD16 <SIload_d16_hi>;
501def az_extloadi8_d16_hi_private : PrivateLoadD16 <SIload_d16_hi_u8>;
502def sextloadi8_d16_hi_private : PrivateLoadD16 <SIload_d16_hi_i8>;
503
504def load_d16_hi_flat : FlatLoadD16 <SIload_d16_hi>;
505def az_extloadi8_d16_hi_flat : FlatLoadD16 <SIload_d16_hi_u8>;
506def sextloadi8_d16_hi_flat : FlatLoadD16 <SIload_d16_hi_i8>;
507
508
509def load_d16_lo_local : LocalLoadD16 <SIload_d16_lo>;
510def az_extloadi8_d16_lo_local : LocalLoadD16 <SIload_d16_lo_u8>;
511def sextloadi8_d16_lo_local : LocalLoadD16 <SIload_d16_lo_i8>;
512
513def load_d16_lo_global : GlobalLoadD16 <SIload_d16_lo>;
514def az_extloadi8_d16_lo_global : GlobalLoadD16 <SIload_d16_lo_u8>;
515def sextloadi8_d16_lo_global : GlobalLoadD16 <SIload_d16_lo_i8>;
516
517def load_d16_lo_private : PrivateLoadD16 <SIload_d16_lo>;
518def az_extloadi8_d16_lo_private : PrivateLoadD16 <SIload_d16_lo_u8>;
519def sextloadi8_d16_lo_private : PrivateLoadD16 <SIload_d16_lo_i8>;
520
521def load_d16_lo_flat : FlatLoadD16 <SIload_d16_lo>;
522def az_extloadi8_d16_lo_flat : FlatLoadD16 <SIload_d16_lo_u8>;
523def sextloadi8_d16_lo_flat : FlatLoadD16 <SIload_d16_lo_i8>;
524
525
526
527def lshr_rev : PatFrag <
528  (ops node:$src1, node:$src0),
529  (srl $src0, $src1)
530>;
531
532def ashr_rev : PatFrag <
533  (ops node:$src1, node:$src0),
534  (sra $src0, $src1)
535>;
536
537def lshl_rev : PatFrag <
538  (ops node:$src1, node:$src0),
539  (shl $src0, $src1)
540>;
541
542multiclass SIAtomicM0Glue2 <string op_name, bit is_amdgpu = 0,
543                            SDTypeProfile tc = SDTAtomic2> {
544
545  def _glue : SDNode <
546    !if(is_amdgpu, "AMDGPUISD", "ISD")#"::ATOMIC_"#op_name, tc,
547    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
548  >;
549
550  def _local_m0 : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>;
551  def _region_m0 : region_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>;
552}
553
554defm atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
555defm atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
556defm atomic_inc : SIAtomicM0Glue2 <"INC", 1>;
557defm atomic_dec : SIAtomicM0Glue2 <"DEC", 1>;
558defm atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
559defm atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
560defm atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
561defm atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
562defm atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
563defm atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
564defm atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
565defm atomic_swap : SIAtomicM0Glue2 <"SWAP">;
566defm atomic_load_fadd : SIAtomicM0Glue2 <"LOAD_FADD", 0, SDTAtomic2_f32>;
567defm atomic_load_fmin : SIAtomicM0Glue2 <"LOAD_FMIN", 1, SDTAtomic2_f32>;
568defm atomic_load_fmax : SIAtomicM0Glue2 <"LOAD_FMAX", 1, SDTAtomic2_f32>;
569
570def atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3,
571  [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
572>;
573
574def atomic_cmp_swap_local_m0 : AtomicCmpSwapLocal<atomic_cmp_swap_glue>;
575def atomic_cmp_swap_region_m0 : AtomicCmpSwapRegion<atomic_cmp_swap_glue>;
576
577
578def as_i1imm : SDNodeXForm<imm, [{
579  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
580}]>;
581
582def as_i8imm : SDNodeXForm<imm, [{
583  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
584}]>;
585
586def as_i16imm : SDNodeXForm<imm, [{
587  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
588}]>;
589
590def as_i32imm: SDNodeXForm<imm, [{
591  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
592}]>;
593
594def as_i64imm: SDNodeXForm<imm, [{
595  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
596}]>;
597
598def cond_as_i32imm: SDNodeXForm<cond, [{
599  return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32);
600}]>;
601
602// Copied from the AArch64 backend:
603def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
604return CurDAG->getTargetConstant(
605  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
606}]>;
607
608def frameindex_to_targetframeindex : SDNodeXForm<frameindex, [{
609  auto FI = cast<FrameIndexSDNode>(N);
610  return CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32);
611}]>;
612
613// Copied from the AArch64 backend:
614def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
615return CurDAG->getTargetConstant(
616  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
617}]>;
618
619class bitextract_imm<int bitnum> : SDNodeXForm<imm, [{
620  uint64_t Imm = N->getZExtValue();
621  unsigned Bit = (Imm >> }] # bitnum # [{ ) & 1;
622  return CurDAG->getTargetConstant(Bit, SDLoc(N), MVT::i1);
623}]>;
624
625def SIMM16bit : ImmLeaf <i32,
626  [{return isInt<16>(Imm);}]
627>;
628
629def UIMM16bit : ImmLeaf <i32,
630  [{return isUInt<16>(Imm); }]
631>;
632
633class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
634  return isInlineImmediate(N);
635}]>;
636
637class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
638  return isInlineImmediate(N);
639}]>;
640
641class VGPRImm <dag frag> : PatLeaf<frag, [{
642  return isVGPRImm(N);
643}]>;
644
645def NegateImm : SDNodeXForm<imm, [{
646  return CurDAG->getConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
647}]>;
648
649// TODO: When FP inline imm values work?
650def NegSubInlineConst32 : ImmLeaf<i32, [{
651  return Imm < -16 && Imm >= -64;
652}], NegateImm>;
653
654def NegSubInlineConst16 : ImmLeaf<i16, [{
655  return Imm < -16 && Imm >= -64;
656}], NegateImm>;
657
658def ShiftAmt32Imm : PatLeaf <(imm), [{
659  return N->getZExtValue() < 32;
660}]>;
661
662def getNegV2I16Imm : SDNodeXForm<build_vector, [{
663  return SDValue(packNegConstantV2I16(N, *CurDAG), 0);
664}]>;
665
666def NegSubInlineConstV216 : PatLeaf<(build_vector), [{
667  assert(N->getNumOperands() == 2);
668  assert(N->getOperand(0).getValueType().getSizeInBits() == 16);
669  SDValue Src0 = N->getOperand(0);
670  SDValue Src1 = N->getOperand(1);
671  if (Src0 == Src1)
672    return isNegInlineImmediate(Src0.getNode());
673
674  return (isNullConstantOrUndef(Src0) && isNegInlineImmediate(Src1.getNode())) ||
675         (isNullConstantOrUndef(Src1) && isNegInlineImmediate(Src0.getNode()));
676}], getNegV2I16Imm>;
677
678//===----------------------------------------------------------------------===//
679// Custom Operands
680//===----------------------------------------------------------------------===//
681
682def SoppBrTarget : AsmOperandClass {
683  let Name = "SoppBrTarget";
684  let ParserMethod = "parseSOppBrTarget";
685}
686
687def sopp_brtarget : Operand<OtherVT> {
688  let EncoderMethod = "getSOPPBrEncoding";
689  let DecoderMethod = "decodeSoppBrTarget";
690  let OperandType = "OPERAND_PCREL";
691  let ParserMatchClass = SoppBrTarget;
692}
693
694def si_ga : Operand<iPTR>;
695
696def InterpSlotMatchClass : AsmOperandClass {
697  let Name = "InterpSlot";
698  let PredicateMethod = "isInterpSlot";
699  let ParserMethod = "parseInterpSlot";
700  let RenderMethod = "addImmOperands";
701}
702
703def InterpSlot : Operand<i32> {
704  let PrintMethod = "printInterpSlot";
705  let ParserMatchClass = InterpSlotMatchClass;
706  let OperandType = "OPERAND_IMMEDIATE";
707}
708
709def AttrMatchClass : AsmOperandClass {
710  let Name = "Attr";
711  let PredicateMethod = "isInterpAttr";
712  let ParserMethod = "parseInterpAttr";
713  let RenderMethod = "addImmOperands";
714}
715
716// It appears to be necessary to create a separate operand for this to
717// be able to parse attr<num> with no space.
718def Attr : Operand<i32> {
719  let PrintMethod = "printInterpAttr";
720  let ParserMatchClass = AttrMatchClass;
721  let OperandType = "OPERAND_IMMEDIATE";
722}
723
724def AttrChanMatchClass : AsmOperandClass {
725  let Name = "AttrChan";
726  let PredicateMethod = "isAttrChan";
727  let RenderMethod = "addImmOperands";
728}
729
730def AttrChan : Operand<i32> {
731  let PrintMethod = "printInterpAttrChan";
732  let ParserMatchClass = AttrChanMatchClass;
733  let OperandType = "OPERAND_IMMEDIATE";
734}
735
736def SendMsgMatchClass : AsmOperandClass {
737  let Name = "SendMsg";
738  let PredicateMethod = "isSendMsg";
739  let ParserMethod = "parseSendMsgOp";
740  let RenderMethod = "addImmOperands";
741}
742
743def SwizzleMatchClass : AsmOperandClass {
744  let Name = "Swizzle";
745  let PredicateMethod = "isSwizzle";
746  let ParserMethod = "parseSwizzleOp";
747  let RenderMethod = "addImmOperands";
748  let IsOptional = 1;
749}
750
751def EndpgmMatchClass : AsmOperandClass {
752  let Name = "EndpgmImm";
753  let PredicateMethod = "isEndpgm";
754  let ParserMethod = "parseEndpgmOp";
755  let RenderMethod = "addImmOperands";
756  let IsOptional = 1;
757}
758
759def ExpTgtMatchClass : AsmOperandClass {
760  let Name = "ExpTgt";
761  let PredicateMethod = "isExpTgt";
762  let ParserMethod = "parseExpTgt";
763  let RenderMethod = "printExpTgt";
764}
765
766def SendMsgImm : Operand<i32> {
767  let PrintMethod = "printSendMsg";
768  let ParserMatchClass = SendMsgMatchClass;
769}
770
771def SwizzleImm : Operand<i16> {
772  let PrintMethod = "printSwizzle";
773  let ParserMatchClass = SwizzleMatchClass;
774}
775
776def EndpgmImm : Operand<i16> {
777  let PrintMethod = "printEndpgm";
778  let ParserMatchClass = EndpgmMatchClass;
779}
780
781def SWaitMatchClass : AsmOperandClass {
782  let Name = "SWaitCnt";
783  let RenderMethod = "addImmOperands";
784  let ParserMethod = "parseSWaitCntOps";
785}
786
787def VReg32OrOffClass : AsmOperandClass {
788  let Name = "VReg32OrOff";
789  let ParserMethod = "parseVReg32OrOff";
790}
791
792def WAIT_FLAG : Operand <i32> {
793  let ParserMatchClass = SWaitMatchClass;
794  let PrintMethod = "printWaitFlag";
795  let OperandType = "OPERAND_IMMEDIATE";
796}
797
798include "SIInstrFormats.td"
799include "VIInstrFormats.td"
800
801def BoolReg : AsmOperandClass {
802  let Name = "BoolReg";
803  let ParserMethod = "parseBoolReg";
804  let RenderMethod = "addRegOperands";
805}
806
807class BoolRC : RegisterOperand<SReg_1> {
808  let ParserMatchClass = BoolReg;
809  let DecoderMethod = "decodeBoolReg";
810}
811
812def SSrc_i1 : RegisterOperand<SReg_1_XEXEC> {
813  let ParserMatchClass = BoolReg;
814  let DecoderMethod = "decodeBoolReg";
815}
816
817def VOPDstS64orS32 : BoolRC {
818  let PrintMethod = "printVOPDst";
819}
820
821// SCSrc_i1 is the operand for pseudo instructions only.
822// Boolean immeadiates shall not be exposed to codegen instructions.
823def SCSrc_i1 : RegisterOperand<SReg_1_XEXEC> {
824  let OperandNamespace = "AMDGPU";
825  let OperandType = "OPERAND_REG_IMM_INT32";
826  let ParserMatchClass = BoolReg;
827  let DecoderMethod = "decodeBoolReg";
828}
829
830// ===----------------------------------------------------------------------===//
831// ExpSrc* Special cases for exp src operands which are printed as
832// "off" depending on en operand.
833// ===----------------------------------------------------------------------===//
834
835def ExpSrc0 : RegisterOperand<VGPR_32> {
836  let PrintMethod = "printExpSrc0";
837  let ParserMatchClass = VReg32OrOffClass;
838}
839
840def ExpSrc1 : RegisterOperand<VGPR_32> {
841  let PrintMethod = "printExpSrc1";
842  let ParserMatchClass = VReg32OrOffClass;
843}
844
845def ExpSrc2 : RegisterOperand<VGPR_32> {
846  let PrintMethod = "printExpSrc2";
847  let ParserMatchClass = VReg32OrOffClass;
848}
849
850def ExpSrc3 : RegisterOperand<VGPR_32> {
851  let PrintMethod = "printExpSrc3";
852  let ParserMatchClass = VReg32OrOffClass;
853}
854
855class SDWASrc<ValueType vt> : RegisterOperand<VS_32> {
856  let OperandNamespace = "AMDGPU";
857  string Type = !if(isFloatType<vt>.ret, "FP", "INT");
858  let OperandType = "OPERAND_REG_INLINE_C_"#Type#vt.Size;
859  let DecoderMethod = "decodeSDWASrc"#vt.Size;
860  let EncoderMethod = "getSDWASrcEncoding";
861}
862
863def SDWASrc_i32 : SDWASrc<i32>;
864def SDWASrc_i16 : SDWASrc<i16>;
865def SDWASrc_f32 : SDWASrc<f32>;
866def SDWASrc_f16 : SDWASrc<f16>;
867
868def SDWAVopcDst : BoolRC {
869  let OperandNamespace = "AMDGPU";
870  let OperandType = "OPERAND_SDWA_VOPC_DST";
871  let EncoderMethod = "getSDWAVopcDstEncoding";
872  let DecoderMethod = "decodeSDWAVopcDst";
873  let PrintMethod = "printVOPDst";
874}
875
876class NamedMatchClass<string CName, bit Optional = 1> : AsmOperandClass {
877  let Name = "Imm"#CName;
878  let PredicateMethod = "is"#CName;
879  let ParserMethod = !if(Optional, "parseOptionalOperand", "parse"#CName);
880  let RenderMethod = "addImmOperands";
881  let IsOptional = Optional;
882  let DefaultMethod = !if(Optional, "default"#CName, ?);
883}
884
885class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> {
886  let PrintMethod = "print"#Name;
887  let ParserMatchClass = MatchClass;
888}
889
890class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> {
891  let PrintMethod = "print"#Name;
892  let ParserMatchClass = MatchClass;
893}
894
895class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> {
896  let PrintMethod = "print"#Name;
897  let ParserMatchClass = MatchClass;
898}
899
900class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> {
901  let PrintMethod = "print"#Name;
902  let ParserMatchClass = MatchClass;
903}
904
905class NamedOperandU32Default0<string Name, AsmOperandClass MatchClass> :
906  OperandWithDefaultOps<i32, (ops (i32 0))> {
907  let PrintMethod = "print"#Name;
908  let ParserMatchClass = MatchClass;
909}
910
911let OperandType = "OPERAND_IMMEDIATE" in {
912
913def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>;
914def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>;
915def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>;
916
917def flat_offset : NamedOperandU16<"FlatOffset", NamedMatchClass<"FlatOffset">>;
918def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>;
919def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>;
920def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>;
921
922def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>;
923
924def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>;
925def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>;
926def highmod : NamedOperandBit<"High", NamedMatchClass<"High">>;
927
928def DLC : NamedOperandBit<"DLC", NamedMatchClass<"DLC">>;
929def GLC : NamedOperandBit<"GLC", NamedMatchClass<"GLC">>;
930def SLC : NamedOperandBit<"SLC", NamedMatchClass<"SLC">>;
931def TFE : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>;
932def UNorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>;
933def DA : NamedOperandBit<"DA", NamedMatchClass<"DA">>;
934def R128A16 : NamedOperandBit<"R128A16", NamedMatchClass<"R128A16">>;
935def D16 : NamedOperandBit<"D16", NamedMatchClass<"D16">>;
936def LWE : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>;
937def exp_compr : NamedOperandBit<"ExpCompr", NamedMatchClass<"ExpCompr">>;
938def exp_vm : NamedOperandBit<"ExpVM", NamedMatchClass<"ExpVM">>;
939
940def FORMAT : NamedOperandU8<"FORMAT", NamedMatchClass<"FORMAT">>;
941
942def DMask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>;
943def Dim : NamedOperandU8<"Dim", NamedMatchClass<"Dim", 0>>;
944
945def dpp8 : NamedOperandU32<"DPP8", NamedMatchClass<"DPP8", 0>>;
946
947def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>;
948def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>;
949def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>;
950def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>;
951def FI : NamedOperandU32<"FI", NamedMatchClass<"FI">>;
952
953def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>;
954def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>;
955def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>;
956def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>;
957
958def op_sel : NamedOperandU32Default0<"OpSel", NamedMatchClass<"OpSel">>;
959def op_sel_hi : NamedOperandU32Default0<"OpSelHi", NamedMatchClass<"OpSelHi">>;
960def neg_lo : NamedOperandU32Default0<"NegLo", NamedMatchClass<"NegLo">>;
961def neg_hi : NamedOperandU32Default0<"NegHi", NamedMatchClass<"NegHi">>;
962
963def blgp : NamedOperandU32<"BLGP", NamedMatchClass<"BLGP">>;
964def cbsz : NamedOperandU32<"CBSZ", NamedMatchClass<"CBSZ">>;
965def abid : NamedOperandU32<"ABID", NamedMatchClass<"ABID">>;
966
967def hwreg : NamedOperandU16<"Hwreg", NamedMatchClass<"Hwreg", 0>>;
968
969def exp_tgt : NamedOperandU8<"ExpTgt", NamedMatchClass<"ExpTgt", 0>> {
970
971}
972
973} // End OperandType = "OPERAND_IMMEDIATE"
974
975class KImmMatchClass<int size> : AsmOperandClass {
976  let Name = "KImmFP"#size;
977  let PredicateMethod = "isKImmFP"#size;
978  let ParserMethod = "parseImm";
979  let RenderMethod = "addKImmFP"#size#"Operands";
980}
981
982class kimmOperand<ValueType vt> : Operand<vt> {
983  let OperandNamespace = "AMDGPU";
984  let OperandType = "OPERAND_KIMM"#vt.Size;
985  let PrintMethod = "printU"#vt.Size#"ImmOperand";
986  let ParserMatchClass = !cast<AsmOperandClass>("KImmFP"#vt.Size#"MatchClass");
987}
988
989// 32-bit VALU immediate operand that uses the constant bus.
990def KImmFP32MatchClass : KImmMatchClass<32>;
991def f32kimm : kimmOperand<i32>;
992
993// 32-bit VALU immediate operand with a 16-bit value that uses the
994// constant bus.
995def KImmFP16MatchClass : KImmMatchClass<16>;
996def f16kimm : kimmOperand<i16>;
997
998class FPInputModsMatchClass <int opSize> : AsmOperandClass {
999  let Name = "RegOrImmWithFP"#opSize#"InputMods";
1000  let ParserMethod = "parseRegOrImmWithFPInputMods";
1001  let PredicateMethod = "isRegOrImmWithFP"#opSize#"InputMods";
1002}
1003
1004def FP16InputModsMatchClass : FPInputModsMatchClass<16>;
1005def FP32InputModsMatchClass : FPInputModsMatchClass<32>;
1006def FP64InputModsMatchClass : FPInputModsMatchClass<64>;
1007
1008class InputMods <AsmOperandClass matchClass> : Operand <i32> {
1009  let OperandNamespace = "AMDGPU";
1010  let OperandType = "OPERAND_INPUT_MODS";
1011  let ParserMatchClass = matchClass;
1012}
1013
1014class FPInputMods <FPInputModsMatchClass matchClass> : InputMods <matchClass> {
1015  let PrintMethod = "printOperandAndFPInputMods";
1016}
1017
1018def FP16InputMods : FPInputMods<FP16InputModsMatchClass>;
1019def FP32InputMods : FPInputMods<FP32InputModsMatchClass>;
1020def FP64InputMods : FPInputMods<FP64InputModsMatchClass>;
1021
1022class IntInputModsMatchClass <int opSize> : AsmOperandClass {
1023  let Name = "RegOrImmWithInt"#opSize#"InputMods";
1024  let ParserMethod = "parseRegOrImmWithIntInputMods";
1025  let PredicateMethod = "isRegOrImmWithInt"#opSize#"InputMods";
1026}
1027def Int32InputModsMatchClass : IntInputModsMatchClass<32>;
1028def Int64InputModsMatchClass : IntInputModsMatchClass<64>;
1029
1030class IntInputMods <IntInputModsMatchClass matchClass> : InputMods <matchClass> {
1031  let PrintMethod = "printOperandAndIntInputMods";
1032}
1033def Int32InputMods : IntInputMods<Int32InputModsMatchClass>;
1034def Int64InputMods : IntInputMods<Int64InputModsMatchClass>;
1035
1036class OpSelModsMatchClass : AsmOperandClass {
1037  let Name = "OpSelMods";
1038  let ParserMethod = "parseRegOrImm";
1039  let PredicateMethod = "isRegOrImm";
1040}
1041
1042def IntOpSelModsMatchClass : OpSelModsMatchClass;
1043def IntOpSelMods : InputMods<IntOpSelModsMatchClass>;
1044
1045class FPSDWAInputModsMatchClass <int opSize> : AsmOperandClass {
1046  let Name = "SDWAWithFP"#opSize#"InputMods";
1047  let ParserMethod = "parseRegOrImmWithFPInputMods";
1048  let PredicateMethod = "isSDWAFP"#opSize#"Operand";
1049}
1050
1051def FP16SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<16>;
1052def FP32SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<32>;
1053
1054class FPSDWAInputMods <FPSDWAInputModsMatchClass matchClass> :
1055  InputMods <matchClass> {
1056  let PrintMethod = "printOperandAndFPInputMods";
1057}
1058
1059def FP16SDWAInputMods : FPSDWAInputMods<FP16SDWAInputModsMatchClass>;
1060def FP32SDWAInputMods : FPSDWAInputMods<FP32SDWAInputModsMatchClass>;
1061
1062def FPVRegInputModsMatchClass : AsmOperandClass {
1063  let Name = "VRegWithFPInputMods";
1064  let ParserMethod = "parseRegWithFPInputMods";
1065  let PredicateMethod = "isVReg32";
1066}
1067
1068def FPVRegInputMods : InputMods <FPVRegInputModsMatchClass> {
1069  let PrintMethod = "printOperandAndFPInputMods";
1070}
1071
1072class IntSDWAInputModsMatchClass <int opSize> : AsmOperandClass {
1073  let Name = "SDWAWithInt"#opSize#"InputMods";
1074  let ParserMethod = "parseRegOrImmWithIntInputMods";
1075  let PredicateMethod = "isSDWAInt"#opSize#"Operand";
1076}
1077
1078def Int16SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<16>;
1079def Int32SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<32>;
1080
1081class IntSDWAInputMods <IntSDWAInputModsMatchClass matchClass> :
1082  InputMods <matchClass> {
1083  let PrintMethod = "printOperandAndIntInputMods";
1084}
1085
1086def Int16SDWAInputMods : IntSDWAInputMods<Int16SDWAInputModsMatchClass>;
1087def Int32SDWAInputMods : IntSDWAInputMods<Int32SDWAInputModsMatchClass>;
1088
1089def IntVRegInputModsMatchClass : AsmOperandClass {
1090  let Name = "VRegWithIntInputMods";
1091  let ParserMethod = "parseRegWithIntInputMods";
1092  let PredicateMethod = "isVReg32";
1093}
1094
1095def IntVRegInputMods : InputMods <IntVRegInputModsMatchClass> {
1096  let PrintMethod = "printOperandAndIntInputMods";
1097}
1098
1099class PackedFPInputModsMatchClass <int opSize> : AsmOperandClass {
1100  let Name = "PackedFP"#opSize#"InputMods";
1101  let ParserMethod = "parseRegOrImm";
1102  let PredicateMethod = "isRegOrImm";
1103//  let PredicateMethod = "isPackedFP"#opSize#"InputMods";
1104}
1105
1106class PackedIntInputModsMatchClass <int opSize> : AsmOperandClass {
1107  let Name = "PackedInt"#opSize#"InputMods";
1108  let ParserMethod = "parseRegOrImm";
1109  let PredicateMethod = "isRegOrImm";
1110//  let PredicateMethod = "isPackedInt"#opSize#"InputMods";
1111}
1112
1113def PackedF16InputModsMatchClass : PackedFPInputModsMatchClass<16>;
1114def PackedI16InputModsMatchClass : PackedIntInputModsMatchClass<16>;
1115
1116class PackedFPInputMods <PackedFPInputModsMatchClass matchClass> : InputMods <matchClass> {
1117//  let PrintMethod = "printPackedFPInputMods";
1118}
1119
1120class PackedIntInputMods <PackedIntInputModsMatchClass matchClass> : InputMods <matchClass> {
1121  //let PrintMethod = "printPackedIntInputMods";
1122}
1123
1124def PackedF16InputMods : PackedFPInputMods<PackedF16InputModsMatchClass>;
1125def PackedI16InputMods : PackedIntInputMods<PackedI16InputModsMatchClass>;
1126
1127//===----------------------------------------------------------------------===//
1128// Complex patterns
1129//===----------------------------------------------------------------------===//
1130
1131def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
1132def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
1133
1134def MOVRELOffset : ComplexPattern<i32, 2, "SelectMOVRELOffset">;
1135
1136def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
1137def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
1138def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
1139def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
1140def VOP3NoMods : ComplexPattern<untyped, 1, "SelectVOP3NoMods">;
1141// VOP3Mods, but the input source is known to never be NaN.
1142def VOP3Mods_nnan : ComplexPattern<fAny, 2, "SelectVOP3Mods_NNaN">;
1143// VOP3Mods, but only allowed for f32 operands.
1144def VOP3Mods_f32 : ComplexPattern<fAny, 2, "SelectVOP3Mods_f32">;
1145
1146def VOP3OMods : ComplexPattern<untyped, 3, "SelectVOP3OMods">;
1147
1148def VOP3PMods  : ComplexPattern<untyped, 2, "SelectVOP3PMods">;
1149def VOP3PMods0 : ComplexPattern<untyped, 3, "SelectVOP3PMods0">;
1150
1151def VOP3OpSel  : ComplexPattern<untyped, 2, "SelectVOP3OpSel">;
1152def VOP3OpSel0 : ComplexPattern<untyped, 3, "SelectVOP3OpSel0">;
1153
1154def VOP3OpSelMods  : ComplexPattern<untyped, 2, "SelectVOP3OpSelMods">;
1155def VOP3OpSelMods0 : ComplexPattern<untyped, 3, "SelectVOP3OpSelMods0">;
1156
1157def VOP3PMadMixMods  : ComplexPattern<untyped, 2, "SelectVOP3PMadMixMods">;
1158
1159
1160def Hi16Elt  : ComplexPattern<untyped, 1, "SelectHi16Elt">;
1161
1162//===----------------------------------------------------------------------===//
1163// SI assembler operands
1164//===----------------------------------------------------------------------===//
1165
1166def SIOperand {
1167  int ZERO = 0x80;
1168  int VCC = 0x6A;
1169  int FLAT_SCR = 0x68;
1170}
1171
1172// This should be kept in sync with SISrcMods enum
1173def SRCMODS {
1174  int NONE = 0;
1175  int NEG = 1;
1176  int ABS = 2;
1177  int NEG_ABS = 3;
1178
1179  int NEG_HI = ABS;
1180  int OP_SEL_0 = 4;
1181  int OP_SEL_1 = 8;
1182  int DST_OP_SEL = 8;
1183}
1184
1185def DSTCLAMP {
1186  int NONE = 0;
1187  int ENABLE = 1;
1188}
1189
1190def DSTOMOD {
1191  int NONE = 0;
1192}
1193
1194def TRAPID{
1195  int LLVM_TRAP = 2;
1196  int LLVM_DEBUG_TRAP = 3;
1197}
1198
1199def HWREG {
1200  int MODE = 1;
1201  int STATUS = 2;
1202  int TRAPSTS = 3;
1203  int HW_ID = 4;
1204  int GPR_ALLOC = 5;
1205  int LDS_ALLOC = 6;
1206  int IB_STS = 7;
1207  int MEM_BASES = 15;
1208  int TBA_LO = 16;
1209  int TBA_HI = 17;
1210  int TMA_LO = 18;
1211  int TMA_HI = 19;
1212  int FLAT_SCR_LO = 20;
1213  int FLAT_SCR_HI = 21;
1214  int XNACK_MASK = 22;
1215  int POPS_PACKER = 25;
1216}
1217
1218class getHwRegImm<int Reg, int Offset = 0, int Size = 32> {
1219  int ret = !or(Reg,
1220                !or(!shl(Offset, 6),
1221                    !shl(!add(Size, -1), 11)));
1222}
1223
1224//===----------------------------------------------------------------------===//
1225//
1226// SI Instruction multiclass helpers.
1227//
1228// Instructions with _32 take 32-bit operands.
1229// Instructions with _64 take 64-bit operands.
1230//
1231// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
1232// encoding is the standard encoding, but instruction that make use of
1233// any of the instruction modifiers must use the 64-bit encoding.
1234//
1235// Instructions with _e32 use the 32-bit encoding.
1236// Instructions with _e64 use the 64-bit encoding.
1237//
1238//===----------------------------------------------------------------------===//
1239
1240class SIMCInstr <string pseudo, int subtarget> {
1241  string PseudoInstr = pseudo;
1242  int Subtarget = subtarget;
1243}
1244
1245//===----------------------------------------------------------------------===//
1246// EXP classes
1247//===----------------------------------------------------------------------===//
1248
1249class EXP_Helper<bit done, SDPatternOperator node = null_frag> : EXPCommon<
1250  (outs),
1251  (ins exp_tgt:$tgt,
1252       ExpSrc0:$src0, ExpSrc1:$src1, ExpSrc2:$src2, ExpSrc3:$src3,
1253       exp_vm:$vm, exp_compr:$compr, i8imm:$en),
1254  "exp$tgt $src0, $src1, $src2, $src3"#!if(done, " done", "")#"$compr$vm",
1255  [(node (i8 timm:$tgt), (i8 timm:$en),
1256         f32:$src0, f32:$src1, f32:$src2, f32:$src3,
1257         (i1 timm:$compr), (i1 timm:$vm))]> {
1258  let AsmMatchConverter = "cvtExp";
1259}
1260
1261// Split EXP instruction into EXP and EXP_DONE so we can set
1262// mayLoad for done=1.
1263multiclass EXP_m<bit done, SDPatternOperator node> {
1264  let mayLoad = done, DisableWQM = 1 in {
1265    let isPseudo = 1, isCodeGenOnly = 1 in {
1266      def "" : EXP_Helper<done, node>,
1267               SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.NONE>;
1268    }
1269
1270    let done = done in {
1271      def _si : EXP_Helper<done>,
1272                SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.SI>,
1273                EXPe {
1274        let AssemblerPredicates = [isGFX6GFX7];
1275        let DecoderNamespace = "GFX6GFX7";
1276        let DisableDecoder = DisableSIDecoder;
1277      }
1278
1279      def _vi : EXP_Helper<done>,
1280                SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.VI>,
1281                EXPe_vi {
1282        let AssemblerPredicates = [isGFX8GFX9];
1283        let DecoderNamespace = "GFX8";
1284        let DisableDecoder = DisableVIDecoder;
1285      }
1286
1287      def _gfx10 : EXP_Helper<done>,
1288                SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.GFX10>,
1289                EXPe {
1290        let AssemblerPredicates = [isGFX10Plus];
1291        let DecoderNamespace = "GFX10";
1292        let DisableDecoder = DisableSIDecoder;
1293      }
1294    }
1295  }
1296}
1297
1298//===----------------------------------------------------------------------===//
1299// Vector ALU classes
1300//===----------------------------------------------------------------------===//
1301
1302class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
1303  int ret =
1304    !if (!eq(Src0.Value, untyped.Value),      0,
1305      !if (!eq(Src1.Value, untyped.Value),    1,   // VOP1
1306         !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
1307                                              3))); // VOP3
1308}
1309
1310// Returns the register class to use for the destination of VOP[123C]
1311// instructions for the given VT.
1312class getVALUDstForVT<ValueType VT> {
1313  RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
1314                          !if(!eq(VT.Size, 128), VOPDstOperand<VReg_128>,
1315                            !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
1316                              !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>,
1317                              VOPDstS64orS32)))); // else VT == i1
1318}
1319
1320// Returns true if VT is floating point.
1321class getIsFP<ValueType VT> {
1322  bit ret = !if(!eq(VT.Value, f16.Value), 1,
1323            !if(!eq(VT.Value, v2f16.Value), 1,
1324            !if(!eq(VT.Value, v4f16.Value), 1,
1325            !if(!eq(VT.Value, f32.Value), 1,
1326            !if(!eq(VT.Value, v2f32.Value), 1,
1327            !if(!eq(VT.Value, f64.Value), 1,
1328            !if(!eq(VT.Value, v2f64.Value), 1,
1329            0)))))));
1330}
1331
1332// Returns the register class to use for the destination of VOP[12C]
1333// instructions with SDWA extension
1334class getSDWADstForVT<ValueType VT> {
1335  RegisterOperand ret = !if(!eq(VT.Size, 1),
1336                            SDWAVopcDst, // VOPC
1337                            VOPDstOperand<VGPR_32>); // VOP1/2 32-bit dst
1338}
1339
1340// Returns the register class to use for source 0 of VOP[12C]
1341// instructions for the given VT.
1342class getVOPSrc0ForVT<ValueType VT> {
1343  bit isFP = getIsFP<VT>.ret;
1344
1345  RegisterOperand ret =
1346    !if(isFP,
1347      !if(!eq(VT.Size, 64),
1348         VSrc_f64,
1349         !if(!eq(VT.Value, f16.Value),
1350            VSrc_f16,
1351            !if(!eq(VT.Value, v2f16.Value),
1352               VSrc_v2f16,
1353               !if(!eq(VT.Value, v4f16.Value),
1354                 AVSrc_64,
1355                 VSrc_f32
1356               )
1357            )
1358         )
1359       ),
1360       !if(!eq(VT.Size, 64),
1361          VSrc_b64,
1362          !if(!eq(VT.Value, i16.Value),
1363             VSrc_b16,
1364             !if(!eq(VT.Value, v2i16.Value),
1365                VSrc_v2b16,
1366                VSrc_b32
1367             )
1368          )
1369       )
1370    );
1371}
1372
1373// Returns the vreg register class to use for source operand given VT
1374class getVregSrcForVT<ValueType VT> {
1375  RegisterClass ret = !if(!eq(VT.Size, 128), VReg_128,
1376                        !if(!eq(VT.Size, 64), VReg_64, VGPR_32));
1377}
1378
1379class getSDWASrcForVT <ValueType VT> {
1380  bit isFP = getIsFP<VT>.ret;
1381  RegisterOperand retFlt = !if(!eq(VT.Size, 16), SDWASrc_f16, SDWASrc_f32);
1382  RegisterOperand retInt = !if(!eq(VT.Size, 16), SDWASrc_i16, SDWASrc_i32);
1383  RegisterOperand ret = !if(isFP, retFlt, retInt);
1384}
1385
1386// Returns the register class to use for sources of VOP3 instructions for the
1387// given VT.
1388class getVOP3SrcForVT<ValueType VT> {
1389  bit isFP = getIsFP<VT>.ret;
1390  RegisterOperand ret =
1391  !if(!eq(VT.Size, 128),
1392     VSrc_128,
1393     !if(!eq(VT.Size, 64),
1394        !if(isFP,
1395           VSrc_f64,
1396           VSrc_b64),
1397        !if(!eq(VT.Value, i1.Value),
1398           SSrc_i1,
1399           !if(isFP,
1400              !if(!eq(VT.Value, f16.Value),
1401                 VSrc_f16,
1402                 !if(!eq(VT.Value, v2f16.Value),
1403                    VSrc_v2f16,
1404                    !if(!eq(VT.Value, v4f16.Value),
1405                      AVSrc_64,
1406                      VSrc_f32
1407                    )
1408                 )
1409              ),
1410              !if(!eq(VT.Value, i16.Value),
1411                 VSrc_b16,
1412                 !if(!eq(VT.Value, v2i16.Value),
1413                    VSrc_v2b16,
1414                    VSrc_b32
1415                 )
1416              )
1417           )
1418        )
1419     )
1420  );
1421}
1422
1423// Float or packed int
1424class isModifierType<ValueType SrcVT> {
1425  bit ret =
1426    !if(!eq(SrcVT.Value, f16.Value), 1,
1427    !if(!eq(SrcVT.Value, f32.Value), 1,
1428    !if(!eq(SrcVT.Value, f64.Value), 1,
1429    !if(!eq(SrcVT.Value, v2f16.Value), 1,
1430    !if(!eq(SrcVT.Value, v2i16.Value), 1,
1431    0)))));
1432}
1433
1434// Return type of input modifiers operand for specified input operand
1435class getSrcMod <ValueType VT, bit EnableF32SrcMods> {
1436  bit isFP = getIsFP<VT>.ret;
1437  bit isPacked = isPackedType<VT>.ret;
1438  Operand ret =  !if(!eq(VT.Size, 64),
1439                     !if(isFP, FP64InputMods, Int64InputMods),
1440                       !if(isFP,
1441                         !if(!eq(VT.Value, f16.Value),
1442                            FP16InputMods,
1443                            FP32InputMods
1444                          ),
1445                         !if(EnableF32SrcMods, FP32InputMods, Int32InputMods))
1446                     );
1447}
1448
1449class getOpSelMod <ValueType VT> {
1450  Operand ret = !if(!eq(VT.Value, f16.Value), FP16InputMods, IntOpSelMods);
1451}
1452
1453// Return type of input modifiers operand specified input operand for DPP
1454class getSrcModExt <ValueType VT> {
1455  bit isFP = getIsFP<VT>.ret;
1456  Operand ret = !if(isFP, FPVRegInputMods, IntVRegInputMods);
1457}
1458
1459// Return type of input modifiers operand specified input operand for SDWA
1460class getSrcModSDWA <ValueType VT> {
1461  Operand ret = !if(!eq(VT.Value, f16.Value), FP16SDWAInputMods,
1462                !if(!eq(VT.Value, f32.Value), FP32SDWAInputMods,
1463                !if(!eq(VT.Value, i16.Value), Int16SDWAInputMods,
1464                Int32SDWAInputMods)));
1465}
1466
1467// Returns the input arguments for VOP[12C] instructions for the given SrcVT.
1468class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
1469  dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
1470            !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
1471                                    (ins)));
1472}
1473
1474// Returns the input arguments for VOP3 instructions for the given SrcVT.
1475class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
1476                RegisterOperand Src2RC, int NumSrcArgs,
1477                bit HasIntClamp, bit HasModifiers, bit HasSrc2Mods, bit HasOMod,
1478                Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1479
1480  dag ret =
1481    !if (!eq(NumSrcArgs, 0),
1482      // VOP1 without input operands (V_NOP, V_CLREXCP)
1483      (ins),
1484      /* else */
1485    !if (!eq(NumSrcArgs, 1),
1486      !if (!eq(HasModifiers, 1),
1487        // VOP1 with modifiers
1488        (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1489             clampmod:$clamp, omod:$omod)
1490      /* else */,
1491        // VOP1 without modifiers
1492        !if (!eq(HasIntClamp, 1),
1493          (ins Src0RC:$src0, clampmod:$clamp),
1494          (ins Src0RC:$src0))
1495      /* endif */ ),
1496    !if (!eq(NumSrcArgs, 2),
1497      !if (!eq(HasModifiers, 1),
1498        // VOP 2 with modifiers
1499        !if( !eq(HasOMod, 1),
1500          (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1501               Src1Mod:$src1_modifiers, Src1RC:$src1,
1502               clampmod:$clamp, omod:$omod),
1503           (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1504               Src1Mod:$src1_modifiers, Src1RC:$src1,
1505               clampmod:$clamp))
1506      /* else */,
1507        // VOP2 without modifiers
1508        !if (!eq(HasIntClamp, 1),
1509          (ins Src0RC:$src0, Src1RC:$src1, clampmod:$clamp),
1510          (ins Src0RC:$src0, Src1RC:$src1))
1511
1512      /* endif */ )
1513    /* NumSrcArgs == 3 */,
1514      !if (!eq(HasModifiers, 1),
1515        !if (!eq(HasSrc2Mods, 1),
1516          // VOP3 with modifiers
1517          !if (!eq(HasOMod, 1),
1518            (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1519                 Src1Mod:$src1_modifiers, Src1RC:$src1,
1520                 Src2Mod:$src2_modifiers, Src2RC:$src2,
1521                 clampmod:$clamp, omod:$omod),
1522            !if (!eq(HasIntClamp, 1),
1523              (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1524                   Src1Mod:$src1_modifiers, Src1RC:$src1,
1525                   Src2Mod:$src2_modifiers, Src2RC:$src2,
1526                   clampmod:$clamp),
1527              (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1528                   Src1Mod:$src1_modifiers, Src1RC:$src1,
1529                   Src2Mod:$src2_modifiers, Src2RC:$src2))),
1530          // VOP3 with modifiers except src2
1531          !if (!eq(HasOMod, 1),
1532            (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1533                 Src1Mod:$src1_modifiers, Src1RC:$src1,
1534                 Src2RC:$src2, clampmod:$clamp, omod:$omod),
1535            !if (!eq(HasIntClamp, 1),
1536              (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1537                   Src1Mod:$src1_modifiers, Src1RC:$src1,
1538                   Src2RC:$src2, clampmod:$clamp),
1539              (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1540                   Src1Mod:$src1_modifiers, Src1RC:$src1,
1541                   Src2RC:$src2))))
1542      /* else */,
1543        // VOP3 without modifiers
1544        !if (!eq(HasIntClamp, 1),
1545          (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2, clampmod:$clamp),
1546          (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2))
1547      /* endif */ ))));
1548}
1549
1550/// XXX - src1 may only allow VGPRs?
1551
1552// The modifiers (except clamp) are dummy operands for the benefit of
1553// printing and parsing. They defer their values to looking at the
1554// srcN_modifiers for what to print.
1555class getInsVOP3P <RegisterOperand Src0RC, RegisterOperand Src1RC,
1556                   RegisterOperand Src2RC, int NumSrcArgs,
1557                   bit HasClamp,
1558                   Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1559  dag ret = !if (!eq(NumSrcArgs, 2),
1560    !if (HasClamp,
1561      (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1562           Src1Mod:$src1_modifiers, Src1RC:$src1,
1563           clampmod:$clamp,
1564           op_sel:$op_sel, op_sel_hi:$op_sel_hi,
1565           neg_lo:$neg_lo, neg_hi:$neg_hi),
1566      (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1567           Src1Mod:$src1_modifiers, Src1RC:$src1,
1568           op_sel:$op_sel, op_sel_hi:$op_sel_hi,
1569           neg_lo:$neg_lo, neg_hi:$neg_hi)),
1570    // else NumSrcArgs == 3
1571    !if (HasClamp,
1572      (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1573           Src1Mod:$src1_modifiers, Src1RC:$src1,
1574           Src2Mod:$src2_modifiers, Src2RC:$src2,
1575           clampmod:$clamp,
1576           op_sel:$op_sel, op_sel_hi:$op_sel_hi,
1577           neg_lo:$neg_lo, neg_hi:$neg_hi),
1578      (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1579           Src1Mod:$src1_modifiers, Src1RC:$src1,
1580           Src2Mod:$src2_modifiers, Src2RC:$src2,
1581           op_sel:$op_sel, op_sel_hi:$op_sel_hi,
1582           neg_lo:$neg_lo, neg_hi:$neg_hi))
1583  );
1584}
1585
1586class getInsVOP3OpSel <RegisterOperand Src0RC,
1587                       RegisterOperand Src1RC,
1588                       RegisterOperand Src2RC,
1589                       int NumSrcArgs,
1590                       bit HasClamp,
1591                       Operand Src0Mod,
1592                       Operand Src1Mod,
1593                       Operand Src2Mod> {
1594  dag ret = !if (!eq(NumSrcArgs, 2),
1595    !if (HasClamp,
1596      (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1597           Src1Mod:$src1_modifiers, Src1RC:$src1,
1598           clampmod:$clamp,
1599           op_sel:$op_sel),
1600      (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1601           Src1Mod:$src1_modifiers, Src1RC:$src1,
1602           op_sel:$op_sel)),
1603    // else NumSrcArgs == 3
1604    !if (HasClamp,
1605      (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1606           Src1Mod:$src1_modifiers, Src1RC:$src1,
1607           Src2Mod:$src2_modifiers, Src2RC:$src2,
1608           clampmod:$clamp,
1609           op_sel:$op_sel),
1610      (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1611           Src1Mod:$src1_modifiers, Src1RC:$src1,
1612           Src2Mod:$src2_modifiers, Src2RC:$src2,
1613           op_sel:$op_sel))
1614  );
1615}
1616
1617class getInsDPP <RegisterOperand DstRC, RegisterClass Src0RC, RegisterClass Src1RC,
1618                 int NumSrcArgs, bit HasModifiers,
1619                 Operand Src0Mod, Operand Src1Mod> {
1620
1621  dag ret = !if (!eq(NumSrcArgs, 0),
1622                // VOP1 without input operands (V_NOP)
1623                (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1624                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl),
1625            !if (!eq(NumSrcArgs, 1),
1626              !if (!eq(HasModifiers, 1),
1627                // VOP1_DPP with modifiers
1628                (ins DstRC:$old, Src0Mod:$src0_modifiers,
1629                     Src0RC:$src0, dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1630                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1631              /* else */,
1632                // VOP1_DPP without modifiers
1633                (ins DstRC:$old, Src0RC:$src0,
1634                     dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1635                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1636              /* endif */)
1637              /* NumSrcArgs == 2 */,
1638              !if (!eq(HasModifiers, 1),
1639                // VOP2_DPP with modifiers
1640                (ins DstRC:$old,
1641                     Src0Mod:$src0_modifiers, Src0RC:$src0,
1642                     Src1Mod:$src1_modifiers, Src1RC:$src1,
1643                     dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1644                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1645              /* else */,
1646                // VOP2_DPP without modifiers
1647                (ins DstRC:$old,
1648                     Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl,
1649                     row_mask:$row_mask, bank_mask:$bank_mask,
1650                     bound_ctrl:$bound_ctrl)
1651             /* endif */)));
1652}
1653
1654class getInsDPP16 <RegisterOperand DstRC, RegisterClass Src0RC, RegisterClass Src1RC,
1655                   int NumSrcArgs, bit HasModifiers,
1656                   Operand Src0Mod, Operand Src1Mod> {
1657  dag ret = !con(getInsDPP<DstRC, Src0RC, Src1RC, NumSrcArgs,
1658                           HasModifiers, Src0Mod, Src1Mod>.ret,
1659                 (ins FI:$fi));
1660}
1661
1662class getInsDPP8 <RegisterOperand DstRC, RegisterClass Src0RC, RegisterClass Src1RC,
1663                 int NumSrcArgs, bit HasModifiers,
1664                 Operand Src0Mod, Operand Src1Mod> {
1665  dag ret = !if (!eq(NumSrcArgs, 0),
1666                // VOP1 without input operands (V_NOP)
1667                (ins dpp8:$dpp8, FI:$fi),
1668            !if (!eq(NumSrcArgs, 1),
1669              !if (!eq(HasModifiers, 1),
1670                // VOP1_DPP with modifiers
1671                (ins DstRC:$old, Src0Mod:$src0_modifiers,
1672                     Src0RC:$src0, dpp8:$dpp8, FI:$fi)
1673              /* else */,
1674                // VOP1_DPP without modifiers
1675                (ins DstRC:$old, Src0RC:$src0, dpp8:$dpp8, FI:$fi)
1676              /* endif */)
1677              /* NumSrcArgs == 2 */,
1678              !if (!eq(HasModifiers, 1),
1679                // VOP2_DPP with modifiers
1680                (ins DstRC:$old,
1681                     Src0Mod:$src0_modifiers, Src0RC:$src0,
1682                     Src1Mod:$src1_modifiers, Src1RC:$src1,
1683                     dpp8:$dpp8, FI:$fi)
1684              /* else */,
1685                // VOP2_DPP without modifiers
1686                (ins DstRC:$old,
1687                     Src0RC:$src0, Src1RC:$src1, dpp8:$dpp8, FI:$fi)
1688             /* endif */)));
1689}
1690
1691
1692// Ins for SDWA
1693class getInsSDWA <RegisterOperand Src0RC, RegisterOperand Src1RC, int NumSrcArgs,
1694                  bit HasSDWAOMod, Operand Src0Mod, Operand Src1Mod,
1695                  ValueType DstVT> {
1696
1697  dag ret = !if(!eq(NumSrcArgs, 0),
1698               // VOP1 without input operands (V_NOP)
1699               (ins),
1700            !if(!eq(NumSrcArgs, 1),
1701               // VOP1
1702               !if(!eq(HasSDWAOMod, 0),
1703                  // VOP1_SDWA without omod
1704                  (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1705                       clampmod:$clamp,
1706                       dst_sel:$dst_sel, dst_unused:$dst_unused,
1707                       src0_sel:$src0_sel),
1708                  // VOP1_SDWA with omod
1709                  (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1710                       clampmod:$clamp, omod:$omod,
1711                       dst_sel:$dst_sel, dst_unused:$dst_unused,
1712                       src0_sel:$src0_sel)),
1713            !if(!eq(NumSrcArgs, 2),
1714               !if(!eq(DstVT.Size, 1),
1715                  // VOPC_SDWA
1716                  (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1717                       Src1Mod:$src1_modifiers, Src1RC:$src1,
1718                       clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel),
1719                  // VOP2_SDWA
1720                  !if(!eq(HasSDWAOMod, 0),
1721                     // VOP2_SDWA without omod
1722                     (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1723                          Src1Mod:$src1_modifiers, Src1RC:$src1,
1724                          clampmod:$clamp,
1725                          dst_sel:$dst_sel, dst_unused:$dst_unused,
1726                          src0_sel:$src0_sel, src1_sel:$src1_sel),
1727                     // VOP2_SDWA with omod
1728                     (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1729                          Src1Mod:$src1_modifiers, Src1RC:$src1,
1730                          clampmod:$clamp, omod:$omod,
1731                          dst_sel:$dst_sel, dst_unused:$dst_unused,
1732                          src0_sel:$src0_sel, src1_sel:$src1_sel))),
1733            (ins)/* endif */)));
1734}
1735
1736// Outs for DPP and SDWA
1737class getOutsExt <bit HasDst, ValueType DstVT, RegisterOperand DstRCExt> {
1738  dag ret = !if(HasDst,
1739                !if(!eq(DstVT.Size, 1),
1740                    (outs), // no dst for VOPC, we use "vcc"-token as dst in SDWA VOPC instructions
1741                    (outs DstRCExt:$vdst)),
1742                (outs)); // V_NOP
1743}
1744
1745// Outs for SDWA
1746class getOutsSDWA <bit HasDst, ValueType DstVT, RegisterOperand DstRCSDWA> {
1747  dag ret = !if(HasDst,
1748                !if(!eq(DstVT.Size, 1),
1749                    (outs DstRCSDWA:$sdst),
1750                    (outs DstRCSDWA:$vdst)),
1751                (outs)); // V_NOP
1752}
1753
1754// Returns the assembly string for the inputs and outputs of a VOP[12C]
1755// instruction.  This does not add the _e32 suffix, so it can be reused
1756// by getAsm64.
1757class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
1758  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1759  string src0 = ", $src0";
1760  string src1 = ", $src1";
1761  string src2 = ", $src2";
1762  string ret = !if(HasDst, dst, "") #
1763               !if(!eq(NumSrcArgs, 1), src0, "") #
1764               !if(!eq(NumSrcArgs, 2), src0#src1, "") #
1765               !if(!eq(NumSrcArgs, 3), src0#src1#src2, "");
1766}
1767
1768// Returns the assembly string for the inputs and outputs of a VOP3
1769// instruction.
1770class getAsm64 <bit HasDst, int NumSrcArgs, bit HasIntClamp, bit HasModifiers,
1771                bit HasOMod, ValueType DstVT = i32> {
1772  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1773  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1774  string src1 = !if(!eq(NumSrcArgs, 1), "",
1775                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1776                                           " $src1_modifiers,"));
1777  string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1778  string iclamp = !if(HasIntClamp, "$clamp", "");
1779  string ret =
1780  !if(!eq(HasModifiers, 0),
1781      getAsm32<HasDst, NumSrcArgs, DstVT>.ret # iclamp,
1782      dst#", "#src0#src1#src2#"$clamp"#!if(HasOMod, "$omod", ""));
1783}
1784
1785// Returns the assembly string for the inputs and outputs of a VOP3P
1786// instruction.
1787class getAsmVOP3P <bit HasDst, int NumSrcArgs, bit HasModifiers,
1788                   bit HasClamp, ValueType DstVT = i32> {
1789  string dst = " $vdst";
1790  string src0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,");
1791  string src1 = !if(!eq(NumSrcArgs, 1), "",
1792                   !if(!eq(NumSrcArgs, 2), " $src1",
1793                                           " $src1,"));
1794  string src2 = !if(!eq(NumSrcArgs, 3), " $src2", "");
1795
1796  string mods = !if(HasModifiers, "$neg_lo$neg_hi", "");
1797  string clamp = !if(HasClamp, "$clamp", "");
1798
1799  // Each modifier is printed as an array of bits for each operand, so
1800  // all operands are printed as part of src0_modifiers.
1801  string ret = dst#", "#src0#src1#src2#"$op_sel$op_sel_hi"#mods#clamp;
1802}
1803
1804class getAsmVOP3OpSel <int NumSrcArgs,
1805                       bit HasClamp,
1806                       bit Src0HasMods,
1807                       bit Src1HasMods,
1808                       bit Src2HasMods> {
1809  string dst = " $vdst";
1810
1811  string isrc0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,");
1812  string isrc1 = !if(!eq(NumSrcArgs, 1), "",
1813                     !if(!eq(NumSrcArgs, 2), " $src1",
1814                                             " $src1,"));
1815  string isrc2 = !if(!eq(NumSrcArgs, 3), " $src2", "");
1816
1817  string fsrc0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1818  string fsrc1 = !if(!eq(NumSrcArgs, 1), "",
1819                     !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1820                                             " $src1_modifiers,"));
1821  string fsrc2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1822
1823  string src0 = !if(Src0HasMods, fsrc0, isrc0);
1824  string src1 = !if(Src1HasMods, fsrc1, isrc1);
1825  string src2 = !if(Src2HasMods, fsrc2, isrc2);
1826
1827  string clamp = !if(HasClamp, "$clamp", "");
1828
1829  string ret = dst#", "#src0#src1#src2#"$op_sel"#clamp;
1830}
1831
1832class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1833  string dst = !if(HasDst,
1834                   !if(!eq(DstVT.Size, 1),
1835                       "$sdst",
1836                       "$vdst"),
1837                    ""); // use $sdst for VOPC
1838  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1839  string src1 = !if(!eq(NumSrcArgs, 1), "",
1840                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1841                                           " $src1_modifiers,"));
1842  string args = !if(!eq(HasModifiers, 0),
1843                     getAsm32<0, NumSrcArgs, DstVT>.ret,
1844                     ", "#src0#src1);
1845  string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
1846}
1847
1848class getAsmDPP16 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1849  string ret = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret#"$fi";
1850}
1851
1852class getAsmDPP8 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1853  string dst = !if(HasDst,
1854                   !if(!eq(DstVT.Size, 1),
1855                       "$sdst",
1856                       "$vdst"),
1857                    ""); // use $sdst for VOPC
1858  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1859  string src1 = !if(!eq(NumSrcArgs, 1), "",
1860                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1861                                           " $src1_modifiers,"));
1862  string args = !if(!eq(HasModifiers, 0),
1863                     getAsm32<0, NumSrcArgs, DstVT>.ret,
1864                     ", "#src0#src1);
1865  string ret = dst#args#"$dpp8$fi";
1866}
1867
1868class getAsmSDWA <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
1869  string dst = !if(HasDst,
1870                   !if(!eq(DstVT.Size, 1),
1871                       " vcc", // use vcc token as dst for VOPC instructioins
1872                       "$vdst"),
1873                    "");
1874  string src0 = "$src0_modifiers";
1875  string src1 = "$src1_modifiers";
1876  string args = !if(!eq(NumSrcArgs, 0),
1877                    "",
1878                    !if(!eq(NumSrcArgs, 1),
1879                        ", "#src0#"$clamp",
1880                        ", "#src0#", "#src1#"$clamp"
1881                     )
1882                );
1883  string sdwa = !if(!eq(NumSrcArgs, 0),
1884                    "",
1885                    !if(!eq(NumSrcArgs, 1),
1886                        " $dst_sel $dst_unused $src0_sel",
1887                        !if(!eq(DstVT.Size, 1),
1888                            " $src0_sel $src1_sel", // No dst_sel and dst_unused for VOPC
1889                            " $dst_sel $dst_unused $src0_sel $src1_sel"
1890                        )
1891                    )
1892                );
1893  string ret = dst#args#sdwa;
1894}
1895
1896class getAsmSDWA9 <bit HasDst, bit HasOMod, int NumSrcArgs,
1897                   ValueType DstVT = i32> {
1898  string dst = !if(HasDst,
1899                   !if(!eq(DstVT.Size, 1),
1900                       "$sdst", // VOPC
1901                       "$vdst"), // VOP1/2
1902                    "");
1903  string src0 = "$src0_modifiers";
1904  string src1 = "$src1_modifiers";
1905  string out_mods = !if(!eq(HasOMod, 0), "$clamp", "$clamp$omod");
1906  string args = !if(!eq(NumSrcArgs, 0), "",
1907                    !if(!eq(NumSrcArgs, 1),
1908                        ", "#src0,
1909                        ", "#src0#", "#src1
1910                     )
1911                );
1912  string sdwa = !if(!eq(NumSrcArgs, 0), "",
1913                    !if(!eq(NumSrcArgs, 1),
1914                        out_mods#" $dst_sel $dst_unused $src0_sel",
1915                        !if(!eq(DstVT.Size, 1),
1916                            " $src0_sel $src1_sel", // No dst_sel, dst_unused and output modifiers for VOPC
1917                            out_mods#" $dst_sel $dst_unused $src0_sel $src1_sel"
1918                        )
1919                    )
1920                );
1921  string ret = dst#args#sdwa;
1922}
1923
1924
1925// Function that checks if instruction supports DPP and SDWA
1926class getHasExt <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
1927                 ValueType Src1VT = i32> {
1928  bit ret = !if(!eq(NumSrcArgs, 3),
1929                0, // NumSrcArgs == 3 - No DPP or SDWA for VOP3
1930                !if(!eq(DstVT.Size, 64),
1931                    0, // 64-bit dst - No DPP or SDWA for 64-bit operands
1932                    !if(!eq(Src0VT.Size, 64),
1933                        0, // 64-bit src0
1934                        !if(!eq(Src1VT.Size, 64),
1935                            0, // 64-bit src2
1936                            1
1937                        )
1938                    )
1939                )
1940            );
1941}
1942
1943class getHasDPP <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
1944                 ValueType Src1VT = i32> {
1945  bit ret = !if(!eq(NumSrcArgs, 0), 0,
1946                getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret);
1947}
1948
1949class BitOr<bit a, bit b> {
1950  bit ret = !if(a, 1, !if(b, 1, 0));
1951}
1952
1953class BitAnd<bit a, bit b> {
1954  bit ret = !if(a, !if(b, 1, 0), 0);
1955}
1956
1957def PatGenMode {
1958  int NoPattern = 0;
1959  int Pattern   = 1;
1960}
1961
1962class VOPProfile <list<ValueType> _ArgVT, bit _EnableF32SrcMods = 0,
1963                  bit _EnableClamp = 0> {
1964
1965  field list<ValueType> ArgVT = _ArgVT;
1966  field bit EnableF32SrcMods = _EnableF32SrcMods;
1967  field bit EnableClamp = _EnableClamp;
1968
1969  field ValueType DstVT = ArgVT[0];
1970  field ValueType Src0VT = ArgVT[1];
1971  field ValueType Src1VT = ArgVT[2];
1972  field ValueType Src2VT = ArgVT[3];
1973  field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
1974  field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret;
1975  field RegisterOperand DstRCSDWA = getSDWADstForVT<DstVT>.ret;
1976  field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
1977  field RegisterClass Src1RC32 = getVregSrcForVT<Src1VT>.ret;
1978  field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
1979  field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
1980  field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
1981  field RegisterClass Src0DPP = getVregSrcForVT<Src0VT>.ret;
1982  field RegisterClass Src1DPP = getVregSrcForVT<Src1VT>.ret;
1983  field RegisterOperand Src0SDWA = getSDWASrcForVT<Src0VT>.ret;
1984  field RegisterOperand Src1SDWA = getSDWASrcForVT<Src0VT>.ret;
1985  field Operand Src0Mod = getSrcMod<Src0VT, EnableF32SrcMods>.ret;
1986  field Operand Src1Mod = getSrcMod<Src1VT, EnableF32SrcMods>.ret;
1987  field Operand Src2Mod = getSrcMod<Src2VT, EnableF32SrcMods>.ret;
1988  field Operand Src0ModDPP = getSrcModExt<Src0VT>.ret;
1989  field Operand Src1ModDPP = getSrcModExt<Src1VT>.ret;
1990  field Operand Src0ModSDWA = getSrcModSDWA<Src0VT>.ret;
1991  field Operand Src1ModSDWA = getSrcModSDWA<Src1VT>.ret;
1992
1993
1994  field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1);
1995  field bit HasDst32 = HasDst;
1996  field bit EmitDst = HasDst; // force dst encoding, see v_movreld_b32 special case
1997  field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
1998  field bit HasSrc0 = !if(!eq(Src0VT.Value, untyped.Value), 0, 1);
1999  field bit HasSrc1 = !if(!eq(Src1VT.Value, untyped.Value), 0, 1);
2000  field bit HasSrc2 = !if(!eq(Src2VT.Value, untyped.Value), 0, 1);
2001
2002  // TODO: Modifiers logic is somewhat adhoc here, to be refined later
2003  // HasModifiers affects the normal and DPP encodings. We take note of EnableF32SrcMods, which
2004  // enables modifiers for i32 type.
2005  field bit HasModifiers = BitOr<isModifierType<Src0VT>.ret, EnableF32SrcMods>.ret;
2006
2007  // HasSrc*FloatMods affects the SDWA encoding. We ignore EnableF32SrcMods.
2008  field bit HasSrc0FloatMods = isFloatType<Src0VT>.ret;
2009  field bit HasSrc1FloatMods = isFloatType<Src1VT>.ret;
2010  field bit HasSrc2FloatMods = isFloatType<Src2VT>.ret;
2011
2012  // HasSrc*IntMods affects the SDWA encoding. We ignore EnableF32SrcMods.
2013  field bit HasSrc0IntMods = isIntType<Src0VT>.ret;
2014  field bit HasSrc1IntMods = isIntType<Src1VT>.ret;
2015  field bit HasSrc2IntMods = isIntType<Src2VT>.ret;
2016
2017  field bit HasSrc0Mods = HasModifiers;
2018  field bit HasSrc1Mods = !if(HasModifiers, BitOr<HasSrc1FloatMods, HasSrc1IntMods>.ret, 0);
2019  field bit HasSrc2Mods = !if(HasModifiers, BitOr<HasSrc2FloatMods, HasSrc2IntMods>.ret, 0);
2020
2021  field bit HasClamp = BitOr<isModifierType<Src0VT>.ret, EnableClamp>.ret;
2022  field bit HasSDWAClamp = EmitDst;
2023  field bit HasFPClamp = BitAnd<isFloatType<DstVT>.ret, HasClamp>.ret;
2024  field bit HasIntClamp = !if(isFloatType<DstVT>.ret, 0, HasClamp);
2025  field bit HasClampLo = HasClamp;
2026  field bit HasClampHi = BitAnd<isPackedType<DstVT>.ret, HasClamp>.ret;
2027  field bit HasHigh = 0;
2028
2029  field bit IsPacked = isPackedType<Src0VT>.ret;
2030  field bit HasOpSel = IsPacked;
2031  field bit HasOMod = !if(HasOpSel, 0, isFloatType<DstVT>.ret);
2032  field bit HasSDWAOMod = isFloatType<DstVT>.ret;
2033
2034  field bit HasExt = getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
2035  field bit HasExtDPP = getHasDPP<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
2036  field bit HasExtSDWA = HasExt;
2037  field bit HasExtSDWA9 = HasExt;
2038  field int NeedPatGen = PatGenMode.NoPattern;
2039
2040  field bit IsMAI = 0;
2041
2042  field Operand Src0PackedMod = !if(HasSrc0FloatMods, PackedF16InputMods, PackedI16InputMods);
2043  field Operand Src1PackedMod = !if(HasSrc1FloatMods, PackedF16InputMods, PackedI16InputMods);
2044  field Operand Src2PackedMod = !if(HasSrc2FloatMods, PackedF16InputMods, PackedI16InputMods);
2045
2046  field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs));
2047
2048  // VOP3b instructions are a special case with a second explicit
2049  // output. This is manually overridden for them.
2050  field dag Outs32 = Outs;
2051  field dag Outs64 = Outs;
2052  field dag OutsDPP = getOutsExt<HasDst, DstVT, DstRCDPP>.ret;
2053  field dag OutsDPP8 = getOutsExt<HasDst, DstVT, DstRCDPP>.ret;
2054  field dag OutsSDWA = getOutsSDWA<HasDst, DstVT, DstRCSDWA>.ret;
2055
2056  field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
2057  field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
2058                             HasIntClamp, HasModifiers, HasSrc2Mods,
2059                             HasOMod, Src0Mod, Src1Mod, Src2Mod>.ret;
2060  field dag InsVOP3P = getInsVOP3P<Src0RC64, Src1RC64, Src2RC64,
2061                                   NumSrcArgs, HasClamp,
2062                                   Src0PackedMod, Src1PackedMod, Src2PackedMod>.ret;
2063  field dag InsVOP3OpSel = getInsVOP3OpSel<Src0RC64, Src1RC64, Src2RC64,
2064                                           NumSrcArgs,
2065                                           HasClamp,
2066                                           getOpSelMod<Src0VT>.ret,
2067                                           getOpSelMod<Src1VT>.ret,
2068                                           getOpSelMod<Src2VT>.ret>.ret;
2069  field dag InsDPP = !if(HasExtDPP,
2070                         getInsDPP<DstRCDPP, Src0DPP, Src1DPP, NumSrcArgs,
2071                                   HasModifiers, Src0ModDPP, Src1ModDPP>.ret,
2072                         (ins));
2073  field dag InsDPP16 = getInsDPP16<DstRCDPP, Src0DPP, Src1DPP, NumSrcArgs,
2074                                   HasModifiers, Src0ModDPP, Src1ModDPP>.ret;
2075  field dag InsDPP8 = getInsDPP8<DstRCDPP, Src0DPP, Src1DPP, NumSrcArgs, 0,
2076                                 Src0ModDPP, Src1ModDPP>.ret;
2077  field dag InsSDWA = getInsSDWA<Src0SDWA, Src1SDWA, NumSrcArgs,
2078                                 HasSDWAOMod, Src0ModSDWA, Src1ModSDWA,
2079                                 DstVT>.ret;
2080
2081
2082  field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret;
2083  field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasIntClamp, HasModifiers, HasOMod, DstVT>.ret;
2084  field string AsmVOP3P = getAsmVOP3P<HasDst, NumSrcArgs, HasModifiers, HasClamp, DstVT>.ret;
2085  field string AsmVOP3OpSel = getAsmVOP3OpSel<NumSrcArgs,
2086                                              HasClamp,
2087                                              HasSrc0FloatMods,
2088                                              HasSrc1FloatMods,
2089                                              HasSrc2FloatMods>.ret;
2090  field string AsmDPP = !if(HasExtDPP,
2091                            getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret, "");
2092  field string AsmDPP16 = getAsmDPP16<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
2093  field string AsmDPP8 = getAsmDPP8<HasDst, NumSrcArgs, 0, DstVT>.ret;
2094  field string AsmSDWA = getAsmSDWA<HasDst, NumSrcArgs, DstVT>.ret;
2095  field string AsmSDWA9 = getAsmSDWA9<HasDst, HasSDWAOMod, NumSrcArgs, DstVT>.ret;
2096
2097  field string TieRegDPP = "$old";
2098}
2099
2100class VOP_NO_EXT <VOPProfile p> : VOPProfile <p.ArgVT> {
2101  let HasExt = 0;
2102  let HasExtDPP = 0;
2103  let HasExtSDWA = 0;
2104  let HasExtSDWA9 = 0;
2105}
2106
2107class VOP_PAT_GEN <VOPProfile p, int mode=PatGenMode.Pattern> : VOPProfile <p.ArgVT> {
2108  let NeedPatGen = mode;
2109}
2110
2111def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
2112def VOP_F16_I16 : VOPProfile <[f16, i16, untyped, untyped]>;
2113def VOP_I16_F16 : VOPProfile <[i16, f16, untyped, untyped]>;
2114
2115def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
2116def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i16, untyped]>;
2117def VOP_F16_F16_I32 : VOPProfile <[f16, f16, i32, untyped]>;
2118def VOP_I16_I16_I16 : VOPProfile <[i16, i16, i16, untyped]>;
2119
2120def VOP_I16_I16_I16_I16 : VOPProfile <[i16, i16, i16, i16, untyped]>;
2121def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>;
2122
2123def VOP_I32_I16_I16_I32 : VOPProfile <[i32, i16, i16, i32, untyped]>;
2124
2125def VOP_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, untyped]>;
2126def VOP_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, untyped]>;
2127def VOP_B32_F16_F16 : VOPProfile <[i32, f16, f16, untyped]>;
2128
2129def VOP_V2F16_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, v2f16]>;
2130def VOP_V2I16_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, v2i16]>;
2131def VOP_V2I16_F32_F32 : VOPProfile <[v2i16, f32, f32, untyped]>;
2132def VOP_V2I16_I32_I32 : VOPProfile <[v2i16, i32, i32, untyped]>;
2133
2134def VOP_F32_V2F16_V2F16_V2F16 : VOPProfile <[f32, v2f16, v2f16, v2f16]>;
2135
2136def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
2137
2138def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
2139def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
2140def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
2141def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
2142def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
2143def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
2144def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
2145def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
2146def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
2147def VOP_F16_F32 : VOPProfile <[f16, f32, untyped, untyped]>;
2148def VOP_F32_F16 : VOPProfile <[f32, f16, untyped, untyped]>;
2149
2150def VOP_F32_F32_F16 : VOPProfile <[f32, f32, f16, untyped]>;
2151def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
2152def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
2153def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
2154def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
2155def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
2156def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
2157def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
2158def VOP_I32_I32_I32_ARITH : VOPProfile <[i32, i32, i32, untyped], 0, /*EnableClamp=*/1>;
2159def VOP_V2F16_F32_F32 : VOPProfile <[v2f16, f32, f32, untyped]>;
2160def VOP_F32_F16_F16_F16 : VOPProfile <[f32, f16, f16, f16]>;
2161
2162def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
2163def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
2164def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
2165
2166def VOP_F16_F32_F16_F32 : VOPProfile <[f16, f32, f16, f32]>;
2167def VOP_F32_F32_F16_F16 : VOPProfile <[f32, f32, f16, f16]>;
2168def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
2169def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
2170def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
2171def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
2172def VOP_I32_F32_I32_I32 : VOPProfile <[i32, f32, i32, i32]>;
2173def VOP_I64_I64_I32_I64 : VOPProfile <[i64, i64, i32, i64]>;
2174def VOP_V4I32_I64_I32_V4I32 : VOPProfile <[v4i32, i64, i32, v4i32]>;
2175
2176def VOP_F32_V2F16_V2F16_F32 : VOPProfile <[f32, v2f16, v2f16, f32]>;
2177def VOP_I32_V2I16_V2I16_I32 : VOPProfile <[i32, v2i16, v2i16, i32]>;
2178
2179def VOP_V4F32_F32_F32_V4F32       : VOPProfile <[v4f32,  f32,   f32,   v4f32]>;
2180def VOP_V16F32_F32_F32_V16F32     : VOPProfile <[v16f32, f32,   f32,   v16f32]>;
2181def VOP_V32F32_F32_F32_V32F32     : VOPProfile <[v32f32, f32,   f32,   v32f32]>;
2182def VOP_V4F32_V4F16_V4F16_V4F32   : VOPProfile <[v4f32,  v4f16, v4f16, v4f32]>;
2183def VOP_V16F32_V4F16_V4F16_V16F32 : VOPProfile <[v16f32, v4f16, v4f16, v16f32]>;
2184def VOP_V32F32_V4F16_V4F16_V32F32 : VOPProfile <[v32f32, v4f16, v4f16, v32f32]>;
2185def VOP_V4F32_V2I16_V2I16_V4F32   : VOPProfile <[v4f32,  v2i16, v2i16, v4f32]>;
2186def VOP_V16F32_V2I16_V2I16_V16F32 : VOPProfile <[v16f32, v2i16, v2i16, v16f32]>;
2187def VOP_V32F32_V2I16_V2I16_V32F32 : VOPProfile <[v32f32, v2i16, v2i16, v32f32]>;
2188def VOP_V4I32_I32_I32_V4I32       : VOPProfile <[v4i32,  i32,   i32,   v4i32]>;
2189def VOP_V16I32_I32_I32_V16I32     : VOPProfile <[v16i32, i32,   i32,   v16i32]>;
2190def VOP_V32I32_I32_I32_V32I32     : VOPProfile <[v32i32, i32,   i32,   v32i32]>;
2191
2192class Commutable_REV <string revOp, bit isOrig> {
2193  string RevOp = revOp;
2194  bit IsOrig = isOrig;
2195}
2196
2197class AtomicNoRet <string noRetOp, bit isRet> {
2198  string NoRetOp = noRetOp;
2199  bit IsRet = isRet;
2200}
2201
2202//===----------------------------------------------------------------------===//
2203// Interpolation opcodes
2204//===----------------------------------------------------------------------===//
2205
2206class VINTRPDstOperand <RegisterClass rc> : RegisterOperand <rc, "printVINTRPDst">;
2207
2208class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2209  VINTRPCommon <outs, ins, "", pattern>,
2210  SIMCInstr<opName, SIEncodingFamily.NONE> {
2211  let isPseudo = 1;
2212  let isCodeGenOnly = 1;
2213}
2214
2215// FIXME-GFX10: WIP.
2216class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
2217                      string asm, int encodingFamily> :
2218  VINTRPCommon <outs, ins, asm, []>,
2219  VINTRPe <op>,
2220  SIMCInstr<opName, encodingFamily> {
2221  let DisableDecoder = DisableSIDecoder;
2222}
2223
2224class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
2225                      string asm> :
2226  VINTRPCommon <outs, ins, asm, []>,
2227  VINTRPe_vi <op>,
2228  SIMCInstr<opName, SIEncodingFamily.VI> {
2229  let AssemblerPredicate = VIAssemblerPredicate;
2230  let DecoderNamespace = "GFX8";
2231  let DisableDecoder = DisableVIDecoder;
2232}
2233
2234// FIXME-GFX10: WIP.
2235multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
2236                     list<dag> pattern = []> {
2237  def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
2238
2239  let AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" in {
2240    def _si : VINTRP_Real_si <op, NAME, outs, ins, asm, SIEncodingFamily.SI>;
2241  } // End AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7"
2242
2243  def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
2244
2245  let AssemblerPredicate = isGFX10Plus, DecoderNamespace = "GFX10" in {
2246    def _gfx10 : VINTRP_Real_si<op, NAME, outs, ins, asm, SIEncodingFamily.GFX10>;
2247  } // End AssemblerPredicate = isGFX10Plus, DecoderNamespace = "GFX10"
2248}
2249//===----------------------------------------------------------------------===//
2250// Vector instruction mappings
2251//===----------------------------------------------------------------------===//
2252
2253// Maps an opcode in e32 form to its e64 equivalent
2254def getVOPe64 : InstrMapping {
2255  let FilterClass = "VOP";
2256  let RowFields = ["OpName"];
2257  let ColFields = ["Size", "VOP3"];
2258  let KeyCol = ["4", "0"];
2259  let ValueCols = [["8", "1"]];
2260}
2261
2262// Maps an opcode in e64 form to its e32 equivalent
2263def getVOPe32 : InstrMapping {
2264  let FilterClass = "VOP";
2265  let RowFields = ["OpName"];
2266  let ColFields = ["Size", "VOP3"];
2267  let KeyCol = ["8", "1"];
2268  let ValueCols = [["4", "0"]];
2269}
2270
2271// Maps ordinary instructions to their SDWA counterparts
2272def getSDWAOp : InstrMapping {
2273  let FilterClass = "VOP";
2274  let RowFields = ["OpName"];
2275  let ColFields = ["AsmVariantName"];
2276  let KeyCol = ["Default"];
2277  let ValueCols = [["SDWA"]];
2278}
2279
2280// Maps SDWA instructions to their ordinary counterparts
2281def getBasicFromSDWAOp : InstrMapping {
2282  let FilterClass = "VOP";
2283  let RowFields = ["OpName"];
2284  let ColFields = ["AsmVariantName"];
2285  let KeyCol = ["SDWA"];
2286  let ValueCols = [["Default"]];
2287}
2288
2289// Maps ordinary instructions to their DPP counterparts
2290def getDPPOp32 : InstrMapping {
2291  let FilterClass = "VOP";
2292  let RowFields = ["OpName"];
2293  let ColFields = ["AsmVariantName"];
2294  let KeyCol = ["Default"];
2295  let ValueCols = [["DPP"]];
2296}
2297
2298// Maps an commuted opcode to its original version
2299def getCommuteOrig : InstrMapping {
2300  let FilterClass = "Commutable_REV";
2301  let RowFields = ["RevOp"];
2302  let ColFields = ["IsOrig"];
2303  let KeyCol = ["0"];
2304  let ValueCols = [["1"]];
2305}
2306
2307// Maps an original opcode to its commuted version
2308def getCommuteRev : InstrMapping {
2309  let FilterClass = "Commutable_REV";
2310  let RowFields = ["RevOp"];
2311  let ColFields = ["IsOrig"];
2312  let KeyCol = ["1"];
2313  let ValueCols = [["0"]];
2314}
2315
2316def getMCOpcodeGen : InstrMapping {
2317  let FilterClass = "SIMCInstr";
2318  let RowFields = ["PseudoInstr"];
2319  let ColFields = ["Subtarget"];
2320  let KeyCol = [!cast<string>(SIEncodingFamily.NONE)];
2321  let ValueCols = [[!cast<string>(SIEncodingFamily.SI)],
2322                   [!cast<string>(SIEncodingFamily.VI)],
2323                   [!cast<string>(SIEncodingFamily.SDWA)],
2324                   [!cast<string>(SIEncodingFamily.SDWA9)],
2325                   // GFX80 encoding is added to work around a multiple matching
2326                   // issue for buffer instructions with unpacked d16 data. This
2327                   // does not actually change the encoding, and thus may be
2328                   // removed later.
2329                   [!cast<string>(SIEncodingFamily.GFX80)],
2330                   [!cast<string>(SIEncodingFamily.GFX9)],
2331                   [!cast<string>(SIEncodingFamily.GFX10)],
2332                   [!cast<string>(SIEncodingFamily.SDWA10)]];
2333}
2334
2335// Get equivalent SOPK instruction.
2336def getSOPKOp : InstrMapping {
2337  let FilterClass = "SOPKInstTable";
2338  let RowFields = ["BaseCmpOp"];
2339  let ColFields = ["IsSOPK"];
2340  let KeyCol = ["0"];
2341  let ValueCols = [["1"]];
2342}
2343
2344def getAddr64Inst : InstrMapping {
2345  let FilterClass = "MUBUFAddr64Table";
2346  let RowFields = ["OpName"];
2347  let ColFields = ["IsAddr64"];
2348  let KeyCol = ["0"];
2349  let ValueCols = [["1"]];
2350}
2351
2352def getIfAddr64Inst : InstrMapping {
2353  let FilterClass = "MUBUFAddr64Table";
2354  let RowFields = ["OpName"];
2355  let ColFields = ["IsAddr64"];
2356  let KeyCol = ["1"];
2357  let ValueCols = [["1"]];
2358}
2359
2360def getMUBUFNoLdsInst : InstrMapping {
2361  let FilterClass = "MUBUFLdsTable";
2362  let RowFields = ["OpName"];
2363  let ColFields = ["IsLds"];
2364  let KeyCol = ["1"];
2365  let ValueCols = [["0"]];
2366}
2367
2368// Maps an atomic opcode to its version with a return value.
2369def getAtomicRetOp : InstrMapping {
2370  let FilterClass = "AtomicNoRet";
2371  let RowFields = ["NoRetOp"];
2372  let ColFields = ["IsRet"];
2373  let KeyCol = ["0"];
2374  let ValueCols = [["1"]];
2375}
2376
2377// Maps an atomic opcode to its returnless version.
2378def getAtomicNoRetOp : InstrMapping {
2379  let FilterClass = "AtomicNoRet";
2380  let RowFields = ["NoRetOp"];
2381  let ColFields = ["IsRet"];
2382  let KeyCol = ["1"];
2383  let ValueCols = [["0"]];
2384}
2385
2386// Maps a GLOBAL to its SADDR form.
2387def getGlobalSaddrOp : InstrMapping {
2388  let FilterClass = "GlobalSaddrTable";
2389  let RowFields = ["SaddrOp"];
2390  let ColFields = ["IsSaddr"];
2391  let KeyCol = ["0"];
2392  let ValueCols = [["1"]];
2393}
2394
2395// Maps a v_cmpx opcode with sdst to opcode without sdst.
2396def getVCMPXNoSDstOp : InstrMapping {
2397  let FilterClass = "VCMPXNoSDstTable";
2398  let RowFields = ["NoSDstOp"];
2399  let ColFields = ["HasSDst"];
2400  let KeyCol = ["1"];
2401  let ValueCols = [["0"]];
2402}
2403
2404// Maps a SOPP to a SOPP with S_NOP
2405def getSOPPWithRelaxation : InstrMapping {
2406  let FilterClass = "Base_SOPP";
2407  let RowFields = ["AsmString"];
2408  let ColFields = ["Size"];
2409  let KeyCol = ["4"];
2410  let ValueCols = [["8"]];
2411}
2412
2413include "SIInstructions.td"
2414
2415include "DSInstructions.td"
2416include "MIMGInstructions.td"
2417