1//===-- SIInstrInfo.td -----------------------------------------------------===//
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 <(all_of FeatureWavefrontSize32)>;
11def isWave64 : Predicate<"Subtarget->getWavefrontSize() == 64">,
12  AssemblerPredicate <(all_of FeatureWavefrontSize64)>;
13
14class GCNPredicateControl : PredicateControl {
15  Predicate SIAssemblerPredicate = isGFX6GFX7;
16  Predicate VIAssemblerPredicate = isGFX8GFX9;
17}
18
19// Except for the NONE field, this must be kept in sync with the
20// SIEncodingFamily enum in SIInstrInfo.cpp and the columns of the
21// getMCOpcodeGen table.
22def SIEncodingFamily {
23  int NONE = -1;
24  int SI = 0;
25  int VI = 1;
26  int SDWA = 2;
27  int SDWA9 = 3;
28  int GFX80 = 4;
29  int GFX9 = 5;
30  int GFX10 = 6;
31  int SDWA10 = 7;
32  int GFX90A = 8;
33  int GFX940 = 9;
34  int GFX11 = 10;
35}
36
37//===----------------------------------------------------------------------===//
38// SI DAG Nodes
39//===----------------------------------------------------------------------===//
40
41def AMDGPUclamp : SDNode<"AMDGPUISD::CLAMP", SDTFPUnaryOp>;
42
43def SIsbuffer_load : SDNode<"AMDGPUISD::SBUFFER_LOAD",
44  SDTypeProfile<1, 3, [SDTCisVT<1, v4i32>, SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
45  [SDNPMayLoad, SDNPMemOperand]
46>;
47
48def SIds_ordered_count : SDNode<"AMDGPUISD::DS_ORDERED_COUNT",
49  SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i16>]>,
50  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain, SDNPInGlue]
51>;
52
53def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2,
54  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
55>;
56
57def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2,
58  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
59>;
60
61def SDTAtomic2_f32 : SDTypeProfile<1, 2, [
62  SDTCisSameAs<0,2>, SDTCisFP<0>, SDTCisPtrTy<1>
63]>;
64
65def SIatomic_fmin : SDNode<"AMDGPUISD::ATOMIC_LOAD_FMIN", SDTAtomic2_f32,
66  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
67>;
68
69def SIatomic_fmax : SDNode<"AMDGPUISD::ATOMIC_LOAD_FMAX", SDTAtomic2_f32,
70  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
71>;
72
73// load_d16_{lo|hi} ptr, tied_input
74def SIload_d16 : SDTypeProfile<1, 2, [
75  SDTCisPtrTy<1>,
76  SDTCisSameAs<0, 2>
77]>;
78
79
80def SDTtbuffer_load : SDTypeProfile<1, 8,
81  [                     // vdata
82   SDTCisVT<1, v4i32>,  // rsrc
83   SDTCisVT<2, i32>,    // vindex(VGPR)
84   SDTCisVT<3, i32>,    // voffset(VGPR)
85   SDTCisVT<4, i32>,    // soffset(SGPR)
86   SDTCisVT<5, i32>,    // offset(imm)
87   SDTCisVT<6, i32>,    // format(imm)
88   SDTCisVT<7, i32>,    // cachepolicy, swizzled buffer(imm)
89   SDTCisVT<8, i1>      // idxen(imm)
90  ]>;
91
92def SItbuffer_load :   SDNode<"AMDGPUISD::TBUFFER_LOAD_FORMAT", SDTtbuffer_load,
93                              [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]>;
94def SItbuffer_load_d16 : SDNode<"AMDGPUISD::TBUFFER_LOAD_FORMAT_D16",
95                                SDTtbuffer_load,
96                                [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]>;
97
98def SDTtbuffer_store : SDTypeProfile<0, 9,
99    [                     // vdata
100     SDTCisVT<1, v4i32>,  // rsrc
101     SDTCisVT<2, i32>,    // vindex(VGPR)
102     SDTCisVT<3, i32>,    // voffset(VGPR)
103     SDTCisVT<4, i32>,    // soffset(SGPR)
104     SDTCisVT<5, i32>,    // offset(imm)
105     SDTCisVT<6, i32>,    // format(imm)
106     SDTCisVT<7, i32>,    // cachepolicy, swizzled buffer(imm)
107     SDTCisVT<8, i1>      // idxen(imm)
108    ]>;
109
110def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT", SDTtbuffer_store,
111                             [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
112def SItbuffer_store_d16 : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT_D16",
113                                SDTtbuffer_store,
114                                [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
115
116def SDTBufferLoad : SDTypeProfile<1, 7,
117    [                    // vdata
118     SDTCisVT<1, v4i32>, // rsrc
119     SDTCisVT<2, i32>,   // vindex(VGPR)
120     SDTCisVT<3, i32>,   // voffset(VGPR)
121     SDTCisVT<4, i32>,   // soffset(SGPR)
122     SDTCisVT<5, i32>,   // offset(imm)
123     SDTCisVT<6, i32>,   // cachepolicy, swizzled buffer(imm)
124     SDTCisVT<7, i1>]>;  // idxen(imm)
125
126def SIbuffer_load : SDNode <"AMDGPUISD::BUFFER_LOAD", SDTBufferLoad,
127                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
128def SIbuffer_load_ubyte : SDNode <"AMDGPUISD::BUFFER_LOAD_UBYTE", SDTBufferLoad,
129                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
130def SIbuffer_load_ushort : SDNode <"AMDGPUISD::BUFFER_LOAD_USHORT", SDTBufferLoad,
131                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
132def SIbuffer_load_byte : SDNode <"AMDGPUISD::BUFFER_LOAD_BYTE", SDTBufferLoad,
133                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
134def SIbuffer_load_short: SDNode <"AMDGPUISD::BUFFER_LOAD_SHORT", SDTBufferLoad,
135                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
136def SIbuffer_load_format : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT", SDTBufferLoad,
137                            [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
138def SIbuffer_load_format_d16 : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT_D16",
139                                SDTBufferLoad,
140                                [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
141
142def SDTBufferStore : SDTypeProfile<0, 8,
143    [                    // vdata
144     SDTCisVT<1, v4i32>, // rsrc
145     SDTCisVT<2, i32>,   // vindex(VGPR)
146     SDTCisVT<3, i32>,   // voffset(VGPR)
147     SDTCisVT<4, i32>,   // soffset(SGPR)
148     SDTCisVT<5, i32>,   // offset(imm)
149     SDTCisVT<6, i32>,   // cachepolicy, swizzled buffer(imm)
150     SDTCisVT<7, i1>]>;  // idxen(imm)
151
152def SIbuffer_store : SDNode <"AMDGPUISD::BUFFER_STORE", SDTBufferStore,
153                             [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
154def SIbuffer_store_byte: SDNode <"AMDGPUISD::BUFFER_STORE_BYTE",
155                         SDTBufferStore,
156                         [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
157def SIbuffer_store_short : SDNode <"AMDGPUISD::BUFFER_STORE_SHORT",
158                           SDTBufferStore,
159                           [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
160def SIbuffer_store_format : SDNode <"AMDGPUISD::BUFFER_STORE_FORMAT",
161                            SDTBufferStore,
162                            [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
163def SIbuffer_store_format_d16 : SDNode <"AMDGPUISD::BUFFER_STORE_FORMAT_D16",
164                            SDTBufferStore,
165                            [SDNPMayStore, SDNPMemOperand, SDNPHasChain]>;
166
167class SDBufferAtomic<string opcode> : SDNode <opcode,
168  SDTypeProfile<1, 8,
169       [SDTCisVT<2, v4i32>, // rsrc
170       SDTCisVT<3, i32>,   // vindex(VGPR)
171       SDTCisVT<4, i32>,   // voffset(VGPR)
172       SDTCisVT<5, i32>,   // soffset(SGPR)
173       SDTCisVT<6, i32>,   // offset(imm)
174       SDTCisVT<7, i32>,   // cachepolicy(imm)
175       SDTCisVT<8, i1>]>,  // idxen(imm)
176  [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore]
177>;
178
179def SIbuffer_atomic_swap : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SWAP">;
180def SIbuffer_atomic_add : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_ADD">;
181def SIbuffer_atomic_sub : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SUB">;
182def SIbuffer_atomic_smin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SMIN">;
183def SIbuffer_atomic_umin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_UMIN">;
184def SIbuffer_atomic_smax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_SMAX">;
185def SIbuffer_atomic_umax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_UMAX">;
186def SIbuffer_atomic_and : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_AND">;
187def SIbuffer_atomic_or : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_OR">;
188def SIbuffer_atomic_xor : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_XOR">;
189def SIbuffer_atomic_inc : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_INC">;
190def SIbuffer_atomic_dec : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_DEC">;
191def SIbuffer_atomic_csub : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_CSUB">;
192def SIbuffer_atomic_fadd : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_FADD">;
193def SIbuffer_atomic_fmin : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_FMIN">;
194def SIbuffer_atomic_fmax : SDBufferAtomic <"AMDGPUISD::BUFFER_ATOMIC_FMAX">;
195
196multiclass SDBufferAtomicRetNoRet {
197  def "_ret" : PatFrag<
198    (ops node:$vdata_in, node:$rsrc, node:$vindex, node:$voffset, node:$soffset,
199      node:$offset, node:$cachepolicy, node:$idxen),
200    (!cast<SDNode>(NAME) node:$vdata_in, node:$rsrc, node:$vindex,
201      node:$voffset, node:$soffset, node:$offset, node:$cachepolicy,
202      node:$idxen)> {
203    let PredicateCode = [{ return !(SDValue(N, 0).use_empty()); }];
204    let GISelPredicateCode = [{ return true; }];
205  }
206
207  def "_noret" : PatFrag<
208    (ops node:$vdata_in, node:$rsrc, node:$vindex, node:$voffset, node:$soffset,
209      node:$offset, node:$cachepolicy, node:$idxen),
210    (!cast<SDNode>(NAME) node:$vdata_in, node:$rsrc, node:$vindex,
211      node:$voffset, node:$soffset, node:$offset, node:$cachepolicy,
212      node:$idxen)> {
213    let PredicateCode = [{ return SDValue(N, 0).use_empty(); }];
214    let GISelPredicateCode = [{ return false; }];
215  }
216}
217
218defm SIbuffer_atomic_swap : SDBufferAtomicRetNoRet;
219defm SIbuffer_atomic_add : SDBufferAtomicRetNoRet;
220defm SIbuffer_atomic_sub : SDBufferAtomicRetNoRet;
221defm SIbuffer_atomic_smin : SDBufferAtomicRetNoRet;
222defm SIbuffer_atomic_umin : SDBufferAtomicRetNoRet;
223defm SIbuffer_atomic_smax : SDBufferAtomicRetNoRet;
224defm SIbuffer_atomic_umax : SDBufferAtomicRetNoRet;
225defm SIbuffer_atomic_and : SDBufferAtomicRetNoRet;
226defm SIbuffer_atomic_or : SDBufferAtomicRetNoRet;
227defm SIbuffer_atomic_xor : SDBufferAtomicRetNoRet;
228defm SIbuffer_atomic_inc : SDBufferAtomicRetNoRet;
229defm SIbuffer_atomic_dec : SDBufferAtomicRetNoRet;
230defm SIbuffer_atomic_fadd : SDBufferAtomicRetNoRet;
231defm SIbuffer_atomic_fmin : SDBufferAtomicRetNoRet;
232defm SIbuffer_atomic_fmax : SDBufferAtomicRetNoRet;
233
234def SIbuffer_atomic_cmpswap : SDNode <"AMDGPUISD::BUFFER_ATOMIC_CMPSWAP",
235  SDTypeProfile<1, 9,
236    [SDTCisVT<0, i32>,   // dst
237     SDTCisVT<1, i32>,   // src
238     SDTCisVT<2, i32>,   // cmp
239     SDTCisVT<3, v4i32>, // rsrc
240     SDTCisVT<4, i32>,   // vindex(VGPR)
241     SDTCisVT<5, i32>,   // voffset(VGPR)
242     SDTCisVT<6, i32>,   // soffset(SGPR)
243     SDTCisVT<7, i32>,   // offset(imm)
244     SDTCisVT<8, i32>,   // cachepolicy(imm)
245     SDTCisVT<9, i1>]>,  // idxen(imm)
246  [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore]
247>;
248
249def SIbuffer_atomic_cmpswap_ret : PatFrag<
250  (ops node:$src, node:$cmp, node:$rsrc, node:$vindex, node:$voffset,
251    node:$soffset, node:$offset, node:$cachepolicy, node:$idxen),
252  (SIbuffer_atomic_cmpswap node:$src, node:$cmp, node:$rsrc, node:$vindex,
253    node:$voffset, node:$soffset, node:$offset, node:$cachepolicy,
254    node:$idxen)> {
255  let PredicateCode = [{ return !(SDValue(N, 0).use_empty()); }];
256  let GISelPredicateCode = [{ return true; }];
257}
258
259def SIbuffer_atomic_cmpswap_noret : PatFrag<
260  (ops node:$src, node:$cmp, node:$rsrc, node:$vindex, node:$voffset,
261    node:$soffset, node:$offset, node:$cachepolicy, node:$idxen),
262  (SIbuffer_atomic_cmpswap node:$src, node:$cmp, node:$rsrc, node:$vindex,
263    node:$voffset, node:$soffset, node:$offset, node:$cachepolicy,
264    node:$idxen)> {
265  let PredicateCode = [{ return SDValue(N, 0).use_empty(); }];
266  let GISelPredicateCode = [{ return false; }];
267}
268
269class SDGlobalAtomicNoRtn<string opcode, ValueType ty> : SDNode <opcode,
270  SDTypeProfile<0, 2,
271      [SDTCisPtrTy<0>,     // vaddr
272       SDTCisVT<1, ty>]>,  // vdata
273  [SDNPMemOperand, SDNPHasChain, SDNPMayLoad, SDNPMayStore]
274>;
275
276def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET",
277  SDTypeProfile<1, 2, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]>
278>;
279
280def SIlds : SDNode<"AMDGPUISD::LDS",
281  SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>]>
282>;
283
284def SIload_d16_lo : SDNode<"AMDGPUISD::LOAD_D16_LO",
285  SIload_d16,
286  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
287>;
288
289def SIload_d16_lo_u8 : SDNode<"AMDGPUISD::LOAD_D16_LO_U8",
290  SIload_d16,
291  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
292>;
293
294def SIload_d16_lo_i8 : SDNode<"AMDGPUISD::LOAD_D16_LO_I8",
295  SIload_d16,
296  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
297>;
298
299def SIload_d16_hi : SDNode<"AMDGPUISD::LOAD_D16_HI",
300  SIload_d16,
301  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
302>;
303
304def SIload_d16_hi_u8 : SDNode<"AMDGPUISD::LOAD_D16_HI_U8",
305  SIload_d16,
306  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
307>;
308
309def SIload_d16_hi_i8 : SDNode<"AMDGPUISD::LOAD_D16_HI_I8",
310  SIload_d16,
311  [SDNPMayLoad, SDNPMemOperand, SDNPHasChain]
312>;
313
314def SIdenorm_mode : SDNode<"AMDGPUISD::DENORM_MODE",
315  SDTypeProfile<0 ,1, [SDTCisInt<0>]>,
316  [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]
317>;
318
319def SIfptrunc_round_upward : SDNode<"AMDGPUISD::FPTRUNC_ROUND_UPWARD",
320  SDTFPRoundOp
321>;
322
323def SIfptrunc_round_downward : SDNode<"AMDGPUISD::FPTRUNC_ROUND_DOWNWARD",
324  SDTFPRoundOp
325>;
326
327//===----------------------------------------------------------------------===//
328// ValueType helpers
329//===----------------------------------------------------------------------===//
330
331// Returns 1 if the source arguments have modifiers, 0 if they do not.
332// XXX - do f16 instructions?
333class isFloatType<ValueType SrcVT> {
334  bit ret = !or(!eq(SrcVT.Value, f16.Value),
335                !eq(SrcVT.Value, f32.Value),
336                !eq(SrcVT.Value, f64.Value),
337                !eq(SrcVT.Value, v2f16.Value),
338                !eq(SrcVT.Value, v4f16.Value),
339                !eq(SrcVT.Value, v2f32.Value),
340                !eq(SrcVT.Value, v4f32.Value),
341                !eq(SrcVT.Value, v8f32.Value),
342                !eq(SrcVT.Value, v2f64.Value),
343                !eq(SrcVT.Value, v4f64.Value));
344}
345
346class isIntType<ValueType SrcVT> {
347  bit ret = !or(!eq(SrcVT.Value, i16.Value),
348                !eq(SrcVT.Value, i32.Value),
349                !eq(SrcVT.Value, i64.Value),
350                !eq(SrcVT.Value, v2i32.Value),
351                !eq(SrcVT.Value, v4i32.Value),
352                !eq(SrcVT.Value, v8i32.Value));
353}
354
355class isPackedType<ValueType SrcVT> {
356  bit ret = !or(!eq(SrcVT.Value, v2i16.Value),
357                !eq(SrcVT.Value, v2f16.Value),
358                !eq(SrcVT.Value, v4f16.Value),
359                !eq(SrcVT.Value, v2i32.Value),
360                !eq(SrcVT.Value, v2f32.Value),
361                !eq(SrcVT.Value, v4i32.Value),
362                !eq(SrcVT.Value, v4f32.Value),
363                !eq(SrcVT.Value, v8i32.Value),
364                !eq(SrcVT.Value, v8f32.Value));
365}
366
367
368//===----------------------------------------------------------------------===//
369// PatFrags for global memory operations
370//===----------------------------------------------------------------------===//
371
372defm atomic_inc : binary_atomic_op_all_as<SIatomic_inc>;
373defm atomic_dec : binary_atomic_op_all_as<SIatomic_dec>;
374defm atomic_load_fmin : binary_atomic_op_all_as<SIatomic_fmin, 0>;
375defm atomic_load_fmax : binary_atomic_op_all_as<SIatomic_fmax, 0>;
376
377//===----------------------------------------------------------------------===//
378// SDNodes PatFrags for loads/stores with a glue input.
379// This is for SDNodes and PatFrag for local loads and stores to
380// enable s_mov_b32 m0, -1 to be glued to the memory instructions.
381//
382// These mirror the regular load/store PatFrags and rely on special
383// processing during Select() to add the glued copy.
384//
385//===----------------------------------------------------------------------===//
386
387def AMDGPUld_glue : SDNode <"ISD::LOAD", SDTLoad,
388  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
389>;
390
391def AMDGPUatomic_ld_glue : SDNode <"ISD::ATOMIC_LOAD", SDTAtomicLoad,
392  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
393>;
394
395def unindexedload_glue : PatFrag <(ops node:$ptr), (AMDGPUld_glue node:$ptr)> {
396  let IsLoad = 1;
397  let IsUnindexed = 1;
398}
399
400def load_glue : PatFrag <(ops node:$ptr), (unindexedload_glue node:$ptr)> {
401  let IsLoad = 1;
402  let IsNonExtLoad = 1;
403}
404
405def atomic_load_8_glue : PatFrag<(ops node:$ptr),
406  (AMDGPUatomic_ld_glue node:$ptr)> {
407  let IsAtomic = 1;
408  let MemoryVT = i8;
409}
410
411def atomic_load_16_glue : PatFrag<(ops node:$ptr),
412  (AMDGPUatomic_ld_glue node:$ptr)> {
413  let IsAtomic = 1;
414  let MemoryVT = i16;
415}
416
417def atomic_load_32_glue : PatFrag<(ops node:$ptr),
418  (AMDGPUatomic_ld_glue node:$ptr)> {
419  let IsAtomic = 1;
420  let MemoryVT = i32;
421}
422
423def atomic_load_64_glue : PatFrag<(ops node:$ptr),
424  (AMDGPUatomic_ld_glue node:$ptr)> {
425  let IsAtomic = 1;
426  let MemoryVT = i64;
427}
428
429def extload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr)> {
430  let IsLoad = 1;
431  let IsAnyExtLoad = 1;
432}
433
434def sextload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr)> {
435  let IsLoad = 1;
436  let IsSignExtLoad = 1;
437}
438
439def zextload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr)> {
440  let IsLoad = 1;
441  let IsZeroExtLoad = 1;
442}
443
444def extloadi8_glue : PatFrag<(ops node:$ptr), (extload_glue node:$ptr)> {
445  let IsLoad = 1;
446  let MemoryVT = i8;
447}
448
449def zextloadi8_glue : PatFrag<(ops node:$ptr), (zextload_glue node:$ptr)> {
450  let IsLoad = 1;
451  let MemoryVT = i8;
452}
453
454def extloadi16_glue : PatFrag<(ops node:$ptr), (extload_glue node:$ptr)> {
455  let IsLoad = 1;
456  let MemoryVT = i16;
457}
458
459def zextloadi16_glue : PatFrag<(ops node:$ptr), (zextload_glue node:$ptr)> {
460  let IsLoad = 1;
461  let MemoryVT = i16;
462}
463
464def sextloadi8_glue : PatFrag<(ops node:$ptr), (sextload_glue node:$ptr)> {
465  let IsLoad = 1;
466  let MemoryVT = i8;
467}
468
469def sextloadi16_glue : PatFrag<(ops node:$ptr), (sextload_glue node:$ptr)> {
470  let IsLoad = 1;
471  let MemoryVT = i16;
472}
473
474
475let IsLoad = 1, AddressSpaces = LoadAddress_local.AddrSpaces in {
476def load_local_m0 : PatFrag<(ops node:$ptr), (load_glue node:$ptr)> {
477  let IsNonExtLoad = 1;
478}
479
480def extloadi8_local_m0 : PatFrag<(ops node:$ptr), (extloadi8_glue node:$ptr)>;
481def sextloadi8_local_m0 : PatFrag<(ops node:$ptr), (sextloadi8_glue node:$ptr)>;
482def zextloadi8_local_m0 : PatFrag<(ops node:$ptr), (zextloadi8_glue node:$ptr)>;
483
484def extloadi16_local_m0 : PatFrag<(ops node:$ptr), (extloadi16_glue node:$ptr)>;
485def sextloadi16_local_m0 : PatFrag<(ops node:$ptr), (sextloadi16_glue node:$ptr)>;
486def zextloadi16_local_m0 : PatFrag<(ops node:$ptr), (zextloadi16_glue node:$ptr)>;
487} // End IsLoad = 1, , AddressSpaces = LoadAddress_local.AddrSpaces
488
489def load_align8_local_m0 : PatFrag<(ops node:$ptr),
490                                   (load_local_m0 node:$ptr)> {
491  let IsLoad = 1;
492  int MinAlignment = 8;
493}
494
495def load_align16_local_m0 : PatFrag<(ops node:$ptr),
496                                   (load_local_m0 node:$ptr)> {
497  let IsLoad = 1;
498  int MinAlignment = 16;
499}
500
501let IsAtomic = 1, AddressSpaces = LoadAddress_local.AddrSpaces in {
502def atomic_load_8_local_m0 : PatFrag<(ops node:$ptr),
503                                      (atomic_load_8_glue node:$ptr)>;
504def atomic_load_16_local_m0 : PatFrag<(ops node:$ptr),
505                                      (atomic_load_16_glue node:$ptr)>;
506def atomic_load_32_local_m0 : PatFrag<(ops node:$ptr),
507                                      (atomic_load_32_glue node:$ptr)>;
508def atomic_load_64_local_m0 : PatFrag<(ops node:$ptr),
509                                       (atomic_load_64_glue node:$ptr)>;
510} // End let AddressSpaces = LoadAddress_local.AddrSpaces
511
512
513def AMDGPUst_glue : SDNode <"ISD::STORE", SDTStore,
514  [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
515>;
516
517def AMDGPUatomic_st_glue : SDNode <"ISD::ATOMIC_STORE", SDTAtomicStore,
518  [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
519>;
520
521def unindexedstore_glue : PatFrag<(ops node:$val, node:$ptr),
522                                   (AMDGPUst_glue node:$val, node:$ptr)> {
523  let IsStore = 1;
524  let IsUnindexed = 1;
525}
526
527def store_glue : PatFrag<(ops node:$val, node:$ptr),
528                         (unindexedstore_glue node:$val, node:$ptr)> {
529  let IsStore = 1;
530  let IsTruncStore = 0;
531}
532
533def truncstore_glue : PatFrag<(ops node:$val, node:$ptr),
534  (unindexedstore_glue node:$val, node:$ptr)> {
535  let IsStore = 1;
536  let IsTruncStore = 1;
537}
538
539def truncstorei8_glue : PatFrag<(ops node:$val, node:$ptr),
540                           (truncstore_glue node:$val, node:$ptr)> {
541  let IsStore = 1;
542  let MemoryVT = i8;
543  let IsTruncStore = 1;
544}
545
546def truncstorei16_glue : PatFrag<(ops node:$val, node:$ptr),
547                           (truncstore_glue node:$val, node:$ptr)> {
548  let IsStore = 1;
549  let MemoryVT = i16;
550  let IsTruncStore = 1;
551}
552
553let IsStore = 1, AddressSpaces = StoreAddress_local.AddrSpaces in {
554def store_local_m0 : PatFrag<(ops node:$val, node:$ptr),
555                             (store_glue node:$val, node:$ptr)>;
556def truncstorei8_local_m0 : PatFrag<(ops node:$val, node:$ptr),
557                                    (truncstorei8_glue node:$val, node:$ptr)>;
558def truncstorei16_local_m0 : PatFrag<(ops node:$val, node:$ptr),
559                                    (truncstorei16_glue node:$val, node:$ptr)>;
560}
561
562def store_align8_local_m0 : PatFrag <(ops node:$value, node:$ptr),
563                                     (store_local_m0 node:$value, node:$ptr)>,
564                            Aligned<8> {
565  let IsStore = 1;
566}
567
568def store_align16_local_m0 : PatFrag <(ops node:$value, node:$ptr),
569                                     (store_local_m0 node:$value, node:$ptr)>,
570                            Aligned<16> {
571  let IsStore = 1;
572}
573
574let PredicateCode = [{return cast<MemSDNode>(N)->getAlignment() < 4;}],
575    GISelPredicateCode = [{return (*MI.memoperands_begin())->getAlign() < 4;}],
576    AddressSpaces = [ AddrSpaces.Local ] in {
577def load_align_less_than_4_local : PatFrag<(ops node:$ptr),
578                                           (load_local node:$ptr)> {
579  let IsLoad = 1;
580  let IsNonExtLoad = 1;
581}
582
583def load_align_less_than_4_local_m0 : PatFrag<(ops node:$ptr),
584                                              (load_local_m0 node:$ptr)> {
585  let IsLoad = 1;
586  let IsNonExtLoad = 1;
587}
588
589def store_align_less_than_4_local : PatFrag <(ops node:$value, node:$ptr),
590                                             (store_local node:$value, node:$ptr)> {
591  let IsStore = 1;
592  let IsTruncStore = 0;
593}
594
595def store_align_less_than_4_local_m0 : PatFrag <(ops node:$value, node:$ptr),
596                                                (store_local_m0 node:$value, node:$ptr)> {
597  let IsStore = 1;
598  let IsTruncStore = 0;
599}
600}
601
602def atomic_store_8_glue : PatFrag <
603  (ops node:$ptr, node:$value),
604  (AMDGPUatomic_st_glue node:$ptr, node:$value)> {
605  let IsAtomic = 1;
606  let MemoryVT = i8;
607}
608
609def atomic_store_16_glue : PatFrag <
610  (ops node:$ptr, node:$value),
611  (AMDGPUatomic_st_glue node:$ptr, node:$value)> {
612  let IsAtomic = 1;
613  let MemoryVT = i16;
614}
615
616def atomic_store_32_glue : PatFrag <
617  (ops node:$ptr, node:$value),
618  (AMDGPUatomic_st_glue node:$ptr, node:$value)> {
619  let IsAtomic = 1;
620  let MemoryVT = i32;
621}
622
623def atomic_store_64_glue : PatFrag <
624  (ops node:$ptr, node:$value),
625  (AMDGPUatomic_st_glue node:$ptr, node:$value)> {
626  let IsAtomic = 1;
627  let MemoryVT = i64;
628}
629
630let IsAtomic = 1, AddressSpaces = StoreAddress_local.AddrSpaces in {
631def atomic_store_8_local_m0 : PatFrag<(ops node:$ptr, node:$val),
632                                       (atomic_store_8_glue node:$ptr, node:$val)>;
633def atomic_store_16_local_m0 : PatFrag<(ops node:$ptr, node:$val),
634                                       (atomic_store_16_glue node:$ptr, node:$val)>;
635def atomic_store_32_local_m0 : PatFrag<(ops node:$ptr, node:$val),
636                                       (atomic_store_32_glue node:$ptr, node:$val)>;
637def atomic_store_64_local_m0 : PatFrag<(ops node:$ptr, node:$val),
638                                       (atomic_store_64_glue node:$ptr, node:$val)>;
639} // End let IsAtomic = 1, AddressSpaces = StoreAddress_local.AddrSpaces
640
641
642def si_setcc_uniform : PatFrag <
643  (ops node:$lhs, node:$rhs, node:$cond),
644  (setcc node:$lhs, node:$rhs, node:$cond), [{
645  return !N->isDivergent();
646}]>;
647
648//===----------------------------------------------------------------------===//
649// SDNodes PatFrags for a16 loads and stores with 3 components.
650// v3f16/v3i16 is widened to v4f16/v4i16, so we need to match on the memory
651// load/store size.
652//===----------------------------------------------------------------------===//
653
654class mubuf_intrinsic_load<SDPatternOperator name, ValueType vt> : PatFrag <
655  (ops node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset,
656            node:$auxiliary, node:$idxen),
657  (name node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset,
658            node:$auxiliary, node:$idxen)> {
659  let IsLoad = 1;
660  let MemoryVT = vt;
661}
662
663class mubuf_intrinsic_store<SDPatternOperator name, ValueType vt> : PatFrag <
664  (ops node:$vdata, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset,
665            node:$auxiliary, node:$idxen),
666  (name node:$vdata, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset,
667            node:$auxiliary, node:$idxen)> {
668  let IsStore = 1;
669  let MemoryVT = vt;
670}
671
672class mtbuf_intrinsic_load<SDPatternOperator name, ValueType vt> : PatFrag <
673  (ops node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset,
674            node:$format, node:$auxiliary, node:$idxen),
675  (name node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset,
676            node:$format, node:$auxiliary, node:$idxen)> {
677  let IsLoad = 1;
678  let MemoryVT = vt;
679}
680
681class mtbuf_intrinsic_store<SDPatternOperator name, ValueType vt> : PatFrag <
682  (ops node:$vdata, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset,
683            node:$format, node:$auxiliary, node:$idxen),
684  (name node:$vdata, node:$rsrc, node:$vindex, node:$voffset, node:$soffset, node:$offset,
685            node:$format, node:$auxiliary, node:$idxen)> {
686  let IsStore = 1;
687  let MemoryVT = vt;
688}
689
690//===----------------------------------------------------------------------===//
691// SDNodes PatFrags for d16 loads
692//===----------------------------------------------------------------------===//
693
694class LoadD16Frag <SDPatternOperator op> : PatFrag<
695  (ops node:$ptr, node:$tied_in),
696  (op node:$ptr, node:$tied_in)> {
697  let IsLoad = 1;
698}
699
700foreach as = [ "global", "flat", "constant", "local", "private", "region" ] in {
701let AddressSpaces = !cast<AddressSpaceList>("LoadAddress_"#as).AddrSpaces in {
702
703def load_d16_hi_#as : LoadD16Frag <SIload_d16_hi>;
704
705def az_extloadi8_d16_hi_#as : LoadD16Frag <SIload_d16_hi_u8> {
706  let MemoryVT = i8;
707}
708
709def sextloadi8_d16_hi_#as : LoadD16Frag <SIload_d16_hi_i8> {
710  let MemoryVT = i8;
711}
712
713def load_d16_lo_#as : LoadD16Frag <SIload_d16_lo>;
714
715def az_extloadi8_d16_lo_#as : LoadD16Frag <SIload_d16_lo_u8> {
716  let MemoryVT = i8;
717}
718
719def sextloadi8_d16_lo_#as : LoadD16Frag <SIload_d16_lo_i8> {
720  let MemoryVT = i8;
721}
722
723} // End let AddressSpaces = ...
724} // End foreach AddrSpace
725
726def lshr_rev : PatFrag <
727  (ops node:$src1, node:$src0),
728  (srl $src0, $src1)
729>;
730
731def ashr_rev : PatFrag <
732  (ops node:$src1, node:$src0),
733  (sra $src0, $src1)
734>;
735
736def lshl_rev : PatFrag <
737  (ops node:$src1, node:$src0),
738  (shl $src0, $src1)
739>;
740
741def add_ctpop : PatFrag <
742  (ops node:$src0, node:$src1),
743  (add (ctpop $src0), $src1)
744>;
745
746def xnor : PatFrag <
747  (ops node:$src0, node:$src1),
748  (not (xor $src0, $src1))
749>;
750
751foreach I = 1-4 in {
752def shl#I#_add : PatFrag <
753  (ops node:$src0, node:$src1),
754  (add (shl_oneuse $src0, (i32 I)), $src1)> {
755  // FIXME: Poor substitute for disabling pattern in SelectionDAG
756  let PredicateCode = [{return false;}];
757  let GISelPredicateCode = [{return true;}];
758}
759}
760
761multiclass SIAtomicM0Glue2 <string op_name, bit is_amdgpu = 0,
762                            SDTypeProfile tc = SDTAtomic2,
763                            bit IsInt = 1> {
764
765  def _glue : SDNode <
766    !if(is_amdgpu, "AMDGPUISD", "ISD")#"::ATOMIC_"#op_name, tc,
767    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
768  >;
769
770  let AddressSpaces = StoreAddress_local.AddrSpaces in {
771    defm _local_m0 : binary_atomic_op <!cast<SDNode>(NAME#"_glue"), IsInt>;
772    defm _local_m0 : ret_noret_binary_atomic_op <!cast<SDNode>(NAME#"_glue"),
773                                                 IsInt>;
774  }
775
776  let AddressSpaces = StoreAddress_region.AddrSpaces in {
777    defm _region_m0 : binary_atomic_op <!cast<SDNode>(NAME#"_glue"), IsInt>;
778    defm _region_m0 : ret_noret_binary_atomic_op <!cast<SDNode>(NAME#"_glue"),
779                                                  IsInt>;
780  }
781}
782
783defm atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
784defm atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
785defm atomic_inc : SIAtomicM0Glue2 <"INC", 1>;
786defm atomic_dec : SIAtomicM0Glue2 <"DEC", 1>;
787defm atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
788defm atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
789defm atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
790defm atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
791defm atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
792defm atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
793defm atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
794defm atomic_swap : SIAtomicM0Glue2 <"SWAP">;
795defm atomic_load_fadd : SIAtomicM0Glue2 <"LOAD_FADD", 0, SDTAtomic2_f32, 0>;
796defm atomic_load_fmin : SIAtomicM0Glue2 <"LOAD_FMIN", 1, SDTAtomic2_f32, 0>;
797defm atomic_load_fmax : SIAtomicM0Glue2 <"LOAD_FMAX", 1, SDTAtomic2_f32, 0>;
798
799def as_i1timm : SDNodeXForm<timm, [{
800  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
801}]>;
802
803def as_i8imm : SDNodeXForm<imm, [{
804  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
805}]>;
806
807def as_i8timm : SDNodeXForm<timm, [{
808  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
809}]>;
810
811def as_i16imm : SDNodeXForm<imm, [{
812  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
813}]>;
814
815def as_i16timm : SDNodeXForm<timm, [{
816  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
817}]>;
818
819def as_i32imm: SDNodeXForm<imm, [{
820  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
821}]>;
822
823def as_i32timm: SDNodeXForm<timm, [{
824  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
825}]>;
826
827def as_i64imm: SDNodeXForm<imm, [{
828  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
829}]>;
830
831def cond_as_i32imm: SDNodeXForm<cond, [{
832  return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32);
833}]>;
834
835// Copied from the AArch64 backend:
836def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
837return CurDAG->getTargetConstant(
838  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
839}]>;
840
841def frameindex_to_targetframeindex : SDNodeXForm<frameindex, [{
842  auto FI = cast<FrameIndexSDNode>(N);
843  return CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32);
844}]>;
845
846// Copied from the AArch64 backend:
847def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
848return CurDAG->getTargetConstant(
849  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
850}]>;
851
852class bitextract_imm<int bitnum> : SDNodeXForm<imm, [{
853  uint64_t Imm = N->getZExtValue();
854  unsigned Bit = (Imm >> }] # bitnum # [{ ) & 1;
855  return CurDAG->getTargetConstant(Bit, SDLoc(N), MVT::i1);
856}]>;
857
858def SIMM16bit : ImmLeaf <i32,
859  [{return isInt<16>(Imm);}]
860>;
861
862def UIMM16bit : ImmLeaf <i32,
863  [{return isUInt<16>(Imm);}]
864>;
865
866def i64imm_32bit : ImmLeaf<i64, [{
867  return (Imm & 0xffffffffULL) == static_cast<uint64_t>(Imm);
868}]>;
869
870def InlineImm16 : ImmLeaf<i16, [{
871  return isInlineImmediate16(Imm);
872}]>;
873
874def InlineImm32 : ImmLeaf<i32, [{
875  return isInlineImmediate32(Imm);
876}]>;
877
878def InlineImm64 : ImmLeaf<i64, [{
879  return isInlineImmediate64(Imm);
880}]>;
881
882def InlineImmFP32 : FPImmLeaf<f32, [{
883  return isInlineImmediate(Imm);
884}]>;
885
886def InlineImmFP64 : FPImmLeaf<f64, [{
887  return isInlineImmediate(Imm);
888}]>;
889
890
891class VGPRImm <dag frag> : PatLeaf<frag, [{
892  return isVGPRImm(N);
893}]>;
894
895def NegateImm : SDNodeXForm<imm, [{
896  return CurDAG->getConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
897}]>;
898
899// TODO: When FP inline imm values work?
900def NegSubInlineConst32 : ImmLeaf<i32, [{
901  return Imm < -16 && Imm >= -64;
902}], NegateImm>;
903
904def NegSubInlineIntConst16 : ImmLeaf<i16, [{
905  return Imm < -16 && Imm >= -64;
906}], NegateImm>;
907
908def ShiftAmt32Imm : ImmLeaf <i32, [{
909  return Imm < 32;
910}]>;
911
912def getNegV2I16Imm : SDNodeXForm<build_vector, [{
913  return SDValue(packNegConstantV2I16(N, *CurDAG), 0);
914}]>;
915
916def NegSubInlineConstV216 : PatLeaf<(build_vector), [{
917  assert(N->getNumOperands() == 2);
918  assert(N->getOperand(0).getValueType().getSizeInBits() == 16);
919  SDValue Src0 = N->getOperand(0);
920  SDValue Src1 = N->getOperand(1);
921  if (Src0 == Src1)
922    return isNegInlineImmediate(Src0.getNode());
923
924  return (isNullConstantOrUndef(Src0) && isNegInlineImmediate(Src1.getNode())) ||
925         (isNullConstantOrUndef(Src1) && isNegInlineImmediate(Src0.getNode()));
926}], getNegV2I16Imm>;
927
928
929def fp16_zeros_high_16bits : PatLeaf<(f16 VGPR_32:$src), [{
930  return fp16SrcZerosHighBits(N->getOpcode());
931}]>;
932
933
934//===----------------------------------------------------------------------===//
935// MUBUF/SMEM Patterns
936//===----------------------------------------------------------------------===//
937
938def extract_cpol : SDNodeXForm<timm, [{
939  return CurDAG->getTargetConstant(N->getZExtValue() & AMDGPU::CPol::ALL, SDLoc(N), MVT::i8);
940}]>;
941
942def extract_swz : SDNodeXForm<timm, [{
943  return CurDAG->getTargetConstant((N->getZExtValue() >> 3) & 1, SDLoc(N), MVT::i8);
944}]>;
945
946def set_glc : SDNodeXForm<timm, [{
947  return CurDAG->getTargetConstant(N->getZExtValue() | AMDGPU::CPol::GLC, SDLoc(N), MVT::i8);
948}]>;
949
950//===----------------------------------------------------------------------===//
951// Custom Operands
952//===----------------------------------------------------------------------===//
953
954def SoppBrTarget : AsmOperandClass {
955  let Name = "SoppBrTarget";
956  let ParserMethod = "parseSOppBrTarget";
957}
958
959def sopp_brtarget : Operand<OtherVT> {
960  let EncoderMethod = "getSOPPBrEncoding";
961  let DecoderMethod = "decodeSoppBrTarget";
962  let OperandType = "OPERAND_PCREL";
963  let ParserMatchClass = SoppBrTarget;
964}
965
966def si_ga : Operand<iPTR>;
967
968def InterpSlotMatchClass : AsmOperandClass {
969  let Name = "InterpSlot";
970  let PredicateMethod = "isInterpSlot";
971  let ParserMethod = "parseInterpSlot";
972  let RenderMethod = "addImmOperands";
973}
974
975def InterpSlot : Operand<i32> {
976  let PrintMethod = "printInterpSlot";
977  let ParserMatchClass = InterpSlotMatchClass;
978  let OperandType = "OPERAND_IMMEDIATE";
979}
980
981def AttrMatchClass : AsmOperandClass {
982  let Name = "Attr";
983  let PredicateMethod = "isInterpAttr";
984  let ParserMethod = "parseInterpAttr";
985  let RenderMethod = "addImmOperands";
986}
987
988// It appears to be necessary to create a separate operand for this to
989// be able to parse attr<num> with no space.
990def Attr : Operand<i32> {
991  let PrintMethod = "printInterpAttr";
992  let ParserMatchClass = AttrMatchClass;
993  let OperandType = "OPERAND_IMMEDIATE";
994}
995
996def AttrChanMatchClass : AsmOperandClass {
997  let Name = "AttrChan";
998  let PredicateMethod = "isAttrChan";
999  let RenderMethod = "addImmOperands";
1000}
1001
1002def AttrChan : Operand<i32> {
1003  let PrintMethod = "printInterpAttrChan";
1004  let ParserMatchClass = AttrChanMatchClass;
1005  let OperandType = "OPERAND_IMMEDIATE";
1006}
1007
1008def SendMsgMatchClass : AsmOperandClass {
1009  let Name = "SendMsg";
1010  let PredicateMethod = "isSendMsg";
1011  let ParserMethod = "parseSendMsgOp";
1012  let RenderMethod = "addImmOperands";
1013}
1014
1015def SwizzleMatchClass : AsmOperandClass {
1016  let Name = "Swizzle";
1017  let PredicateMethod = "isSwizzle";
1018  let ParserMethod = "parseSwizzleOp";
1019  let RenderMethod = "addImmOperands";
1020  let IsOptional = 1;
1021}
1022
1023def EndpgmMatchClass : AsmOperandClass {
1024  let Name = "EndpgmImm";
1025  let PredicateMethod = "isEndpgm";
1026  let ParserMethod = "parseEndpgmOp";
1027  let RenderMethod = "addImmOperands";
1028  let IsOptional = 1;
1029}
1030
1031def ExpTgtMatchClass : AsmOperandClass {
1032  let Name = "ExpTgt";
1033  let PredicateMethod = "isExpTgt";
1034  let ParserMethod = "parseExpTgt";
1035  let RenderMethod = "printExpTgt";
1036}
1037
1038def SWaitMatchClass : AsmOperandClass {
1039  let Name = "SWaitCnt";
1040  let RenderMethod = "addImmOperands";
1041  let ParserMethod = "parseSWaitCntOps";
1042}
1043
1044def DepCtrMatchClass : AsmOperandClass {
1045  let Name = "DepCtr";
1046  let RenderMethod = "addImmOperands";
1047  let ParserMethod = "parseDepCtrOps";
1048}
1049
1050def SDelayMatchClass : AsmOperandClass {
1051  let Name = "SDelayAlu";
1052  let RenderMethod = "addImmOperands";
1053  let ParserMethod = "parseSDelayAluOps";
1054}
1055
1056def VReg32OrOffClass : AsmOperandClass {
1057  let Name = "VReg32OrOff";
1058  let ParserMethod = "parseVReg32OrOff";
1059}
1060
1061let OperandType = "OPERAND_IMMEDIATE" in {
1062def SendMsgImm : Operand<i32> {
1063  let PrintMethod = "printSendMsg";
1064  let ParserMatchClass = SendMsgMatchClass;
1065}
1066
1067def SwizzleImm : Operand<i16> {
1068  let PrintMethod = "printSwizzle";
1069  let ParserMatchClass = SwizzleMatchClass;
1070}
1071
1072def EndpgmImm : Operand<i16> {
1073  let PrintMethod = "printEndpgm";
1074  let ParserMatchClass = EndpgmMatchClass;
1075}
1076
1077def WAIT_FLAG : Operand <i32> {
1078  let ParserMatchClass = SWaitMatchClass;
1079  let PrintMethod = "printWaitFlag";
1080}
1081
1082def DepCtrImm : Operand <i32> {
1083  let ParserMatchClass = DepCtrMatchClass;
1084  let PrintMethod = "printDepCtr";
1085}
1086
1087def DELAY_FLAG : Operand <i32> {
1088  let ParserMatchClass = SDelayMatchClass;
1089  let PrintMethod = "printDelayFlag";
1090}
1091} // End OperandType = "OPERAND_IMMEDIATE"
1092
1093include "SIInstrFormats.td"
1094include "VIInstrFormats.td"
1095
1096def BoolReg : AsmOperandClass {
1097  let Name = "BoolReg";
1098  let ParserMethod = "parseBoolReg";
1099  let RenderMethod = "addRegOperands";
1100}
1101
1102class BoolRC : RegisterOperand<SReg_1> {
1103  let ParserMatchClass = BoolReg;
1104  let DecoderMethod = "decodeBoolReg";
1105}
1106
1107def SSrc_i1 : RegisterOperand<SReg_1_XEXEC> {
1108  let ParserMatchClass = BoolReg;
1109  let DecoderMethod = "decodeBoolReg";
1110}
1111
1112def VOPDstS64orS32 : BoolRC {
1113  let PrintMethod = "printVOPDst";
1114}
1115
1116// SCSrc_i1 is the operand for pseudo instructions only.
1117// Boolean immediates shall not be exposed to codegen instructions.
1118def SCSrc_i1 : RegisterOperand<SReg_1_XEXEC> {
1119  let OperandNamespace = "AMDGPU";
1120  let OperandType = "OPERAND_REG_IMM_INT32";
1121  let ParserMatchClass = BoolReg;
1122  let DecoderMethod = "decodeBoolReg";
1123}
1124
1125// ===----------------------------------------------------------------------===//
1126// ExpSrc* Special cases for exp src operands which are printed as
1127// "off" depending on en operand.
1128// ===----------------------------------------------------------------------===//
1129
1130def ExpSrc0 : RegisterOperand<VGPR_32> {
1131  let PrintMethod = "printExpSrc0";
1132  let ParserMatchClass = VReg32OrOffClass;
1133}
1134
1135def ExpSrc1 : RegisterOperand<VGPR_32> {
1136  let PrintMethod = "printExpSrc1";
1137  let ParserMatchClass = VReg32OrOffClass;
1138}
1139
1140def ExpSrc2 : RegisterOperand<VGPR_32> {
1141  let PrintMethod = "printExpSrc2";
1142  let ParserMatchClass = VReg32OrOffClass;
1143}
1144
1145def ExpSrc3 : RegisterOperand<VGPR_32> {
1146  let PrintMethod = "printExpSrc3";
1147  let ParserMatchClass = VReg32OrOffClass;
1148}
1149
1150class SDWASrc<ValueType vt> : RegisterOperand<VS_32> {
1151  let OperandNamespace = "AMDGPU";
1152  string Type = !if(isFloatType<vt>.ret, "FP", "INT");
1153  let OperandType = "OPERAND_REG_INLINE_C_"#Type#vt.Size;
1154  let DecoderMethod = "decodeSDWASrc"#vt.Size;
1155  let EncoderMethod = "getSDWASrcEncoding";
1156}
1157
1158def SDWASrc_i32 : SDWASrc<i32>;
1159def SDWASrc_i16 : SDWASrc<i16>;
1160def SDWASrc_f32 : SDWASrc<f32>;
1161def SDWASrc_f16 : SDWASrc<f16>;
1162
1163def SDWAVopcDst : BoolRC {
1164  let OperandNamespace = "AMDGPU";
1165  let OperandType = "OPERAND_SDWA_VOPC_DST";
1166  let EncoderMethod = "getSDWAVopcDstEncoding";
1167  let DecoderMethod = "decodeSDWAVopcDst";
1168  let PrintMethod = "printVOPDst";
1169}
1170
1171class NamedMatchClass<string CName, bit Optional = 1> : AsmOperandClass {
1172  let Name = "Imm"#CName;
1173  let PredicateMethod = "is"#CName;
1174  let ParserMethod = !if(Optional, "parseOptionalOperand", "parse"#CName);
1175  let RenderMethod = "addImmOperands";
1176  let IsOptional = Optional;
1177  let DefaultMethod = !if(Optional, "default"#CName, ?);
1178}
1179
1180class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> {
1181  let PrintMethod = "print"#Name;
1182  let ParserMatchClass = MatchClass;
1183}
1184
1185class NamedOperandBit_0<string Name, AsmOperandClass MatchClass> :
1186  OperandWithDefaultOps<i1, (ops (i1 0))> {
1187  let PrintMethod = "print"#Name;
1188  let ParserMatchClass = MatchClass;
1189}
1190
1191class NamedOperandBit_1<string Name, AsmOperandClass MatchClass> :
1192  OperandWithDefaultOps<i1, (ops (i1 1))> {
1193  let PrintMethod = "print"#Name;
1194  let ParserMatchClass = MatchClass;
1195}
1196
1197class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> {
1198  let PrintMethod = "print"#Name;
1199  let ParserMatchClass = MatchClass;
1200}
1201
1202class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> {
1203  let PrintMethod = "print"#Name;
1204  let ParserMatchClass = MatchClass;
1205}
1206
1207class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> {
1208  let PrintMethod = "print"#Name;
1209  let ParserMatchClass = MatchClass;
1210}
1211
1212class NamedOperandU32_0<string Name, AsmOperandClass MatchClass> :
1213  OperandWithDefaultOps<i32, (ops (i32 0))> {
1214  let PrintMethod = "print"#Name;
1215  let ParserMatchClass = MatchClass;
1216}
1217
1218class NamedOperandU32Default0<string Name, AsmOperandClass MatchClass> :
1219  OperandWithDefaultOps<i32, (ops (i32 0))> {
1220  let PrintMethod = "print"#Name;
1221  let ParserMatchClass = MatchClass;
1222}
1223
1224class NamedOperandU32Default1<string Name, AsmOperandClass MatchClass> :
1225  OperandWithDefaultOps<i32, (ops (i32 1))> {
1226  let PrintMethod = "print"#Name;
1227  let ParserMatchClass = MatchClass;
1228}
1229
1230let OperandType = "OPERAND_IMMEDIATE" in {
1231
1232def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>;
1233def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>;
1234def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>;
1235
1236def flat_offset : NamedOperandU16<"FlatOffset", NamedMatchClass<"FlatOffset">>;
1237def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>;
1238def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>;
1239def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>;
1240
1241def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>;
1242
1243def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>;
1244def omod0 : NamedOperandU32_0<"OModSI", NamedMatchClass<"OModSI">>;
1245
1246// We need to make the cases with a default of 0 distinct from no
1247// default to help deal with some cases where the operand appears
1248// before a mandatory operand.
1249def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>;
1250def clampmod0 : NamedOperandBit_0<"ClampSI", NamedMatchClass<"ClampSI">>;
1251def highmod : NamedOperandBit<"High", NamedMatchClass<"High">>;
1252
1253def CPol : NamedOperandU32<"CPol", NamedMatchClass<"CPol">>;
1254def CPol_0 : NamedOperandU32Default0<"CPol", NamedMatchClass<"CPol">>;
1255def CPol_GLC1 : NamedOperandU32Default1<"CPol", NamedMatchClass<"CPol">>;
1256
1257def TFE : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>;
1258def TFE_0 : NamedOperandBit_0<"TFE", NamedMatchClass<"TFE">>;
1259def SWZ : NamedOperandBit<"SWZ", NamedMatchClass<"SWZ">>;
1260def SWZ_0 : NamedOperandBit_0<"SWZ", NamedMatchClass<"SWZ">>;
1261def UNorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>;
1262def DA : NamedOperandBit<"DA", NamedMatchClass<"DA">>;
1263def R128A16 : NamedOperandBit<"R128A16", NamedMatchClass<"R128A16">>;
1264def GFX10A16 : NamedOperandBit<"GFX10A16", NamedMatchClass<"GFX10A16">>;
1265def D16 : NamedOperandBit<"D16", NamedMatchClass<"D16">>;
1266def LWE : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>;
1267def exp_compr : NamedOperandBit<"ExpCompr", NamedMatchClass<"ExpCompr">>;
1268def exp_vm : NamedOperandBit<"ExpVM", NamedMatchClass<"ExpVM">>;
1269
1270def FORMAT : NamedOperandU8<"FORMAT", NamedMatchClass<"FORMAT", 0>>;
1271
1272def DMask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>;
1273def Dim : NamedOperandU8<"Dim", NamedMatchClass<"Dim", 0>>;
1274
1275def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>;
1276def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>;
1277def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>;
1278def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>;
1279
1280def op_sel0 : NamedOperandU32Default0<"OpSel", NamedMatchClass<"OpSel">>;
1281def op_sel_hi0 : NamedOperandU32Default0<"OpSelHi", NamedMatchClass<"OpSelHi">>;
1282def neg_lo0 : NamedOperandU32Default0<"NegLo", NamedMatchClass<"NegLo">>;
1283def neg_hi0 : NamedOperandU32Default0<"NegHi", NamedMatchClass<"NegHi">>;
1284
1285def dpp8 : NamedOperandU32<"DPP8", NamedMatchClass<"DPP8", 0>>;
1286def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>;
1287
1288def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>;
1289def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>;
1290def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>;
1291def FI : NamedOperandU32<"FI", NamedMatchClass<"FI">>;
1292
1293def blgp : NamedOperandU32<"BLGP", NamedMatchClass<"BLGP">>;
1294def cbsz : NamedOperandU32<"CBSZ", NamedMatchClass<"CBSZ">>;
1295def abid : NamedOperandU32<"ABID", NamedMatchClass<"ABID">>;
1296
1297def hwreg : NamedOperandU32<"Hwreg", NamedMatchClass<"Hwreg", 0>>;
1298
1299def exp_tgt : NamedOperandU32<"ExpTgt", NamedMatchClass<"ExpTgt", 0>> {
1300
1301}
1302
1303def wait_vdst : NamedOperandU8<"WaitVDST", NamedMatchClass<"WaitVDST">>;
1304def wait_exp : NamedOperandU8<"WaitEXP", NamedMatchClass<"WaitEXP">>;
1305
1306} // End OperandType = "OPERAND_IMMEDIATE"
1307
1308class KImmMatchClass<int size> : AsmOperandClass {
1309  let Name = "KImmFP"#size;
1310  let PredicateMethod = "isKImmFP"#size;
1311  let ParserMethod = "parseImm";
1312  let RenderMethod = "addKImmFP"#size#"Operands";
1313}
1314
1315class kimmOperand<ValueType vt> : Operand<vt> {
1316  let OperandNamespace = "AMDGPU";
1317  let OperandType = "OPERAND_KIMM"#vt.Size;
1318  let PrintMethod = "printU"#vt.Size#"ImmOperand";
1319  let ParserMatchClass = !cast<AsmOperandClass>("KImmFP"#vt.Size#"MatchClass");
1320  let DecoderMethod = "decodeOperand_f"#vt.Size#"kimm";
1321}
1322
1323// 32-bit VALU immediate operand that uses the constant bus.
1324def KImmFP32MatchClass : KImmMatchClass<32>;
1325def f32kimm : kimmOperand<i32>;
1326
1327// 32-bit VALU immediate operand with a 16-bit value that uses the
1328// constant bus.
1329def KImmFP16MatchClass : KImmMatchClass<16>;
1330def f16kimm : kimmOperand<i16>;
1331
1332class FPInputModsMatchClass <int opSize> : AsmOperandClass {
1333  let Name = "RegOrImmWithFP"#opSize#"InputMods";
1334  let ParserMethod = "parseRegOrImmWithFPInputMods";
1335  let PredicateMethod = "isRegOrImmWithFP"#opSize#"InputMods";
1336}
1337
1338class FPVCSrcInputModsMatchClass <int opSize> : FPInputModsMatchClass <opSize> {
1339  let Name = "RegOrInlineImmWithFP"#opSize#"InputMods";
1340  let PredicateMethod = "isRegOrInlineImmWithFP"#opSize#"InputMods";
1341}
1342
1343def FP16InputModsMatchClass : FPInputModsMatchClass<16>;
1344def FP32InputModsMatchClass : FPInputModsMatchClass<32>;
1345def FP64InputModsMatchClass : FPInputModsMatchClass<64>;
1346
1347def FP16VCSrcInputModsMatchClass : FPVCSrcInputModsMatchClass<16>;
1348def FP32VCSrcInputModsMatchClass : FPVCSrcInputModsMatchClass<32>;
1349
1350class InputMods <AsmOperandClass matchClass> : Operand <i32> {
1351  let OperandNamespace = "AMDGPU";
1352  let OperandType = "OPERAND_INPUT_MODS";
1353  let ParserMatchClass = matchClass;
1354}
1355
1356class FPInputMods <FPInputModsMatchClass matchClass> : InputMods <matchClass> {
1357  let PrintMethod = "printOperandAndFPInputMods";
1358}
1359
1360def FP16InputMods : FPInputMods<FP16InputModsMatchClass>;
1361def FP32InputMods : FPInputMods<FP32InputModsMatchClass>;
1362def FP64InputMods : FPInputMods<FP64InputModsMatchClass>;
1363
1364def FP16VCSrcInputMods : FPInputMods<FP16VCSrcInputModsMatchClass>;
1365def FP32VCSrcInputMods : FPInputMods<FP32VCSrcInputModsMatchClass>;
1366
1367class IntInputModsMatchClass <int opSize> : AsmOperandClass {
1368  let Name = "RegOrImmWithInt"#opSize#"InputMods";
1369  let ParserMethod = "parseRegOrImmWithIntInputMods";
1370  let PredicateMethod = "isRegOrImmWithInt"#opSize#"InputMods";
1371}
1372class IntVCSrcInputModsMatchClass <int opSize> : IntInputModsMatchClass <opSize> {
1373  let Name = "RegOrInlineImmWithInt"#opSize#"InputMods";
1374  let PredicateMethod = "isRegOrInlineImmWithInt"#opSize#"InputMods";
1375}
1376def Int32InputModsMatchClass : IntInputModsMatchClass<32>;
1377def Int64InputModsMatchClass : IntInputModsMatchClass<64>;
1378def Int32VCSrcInputModsMatchClass : IntVCSrcInputModsMatchClass<32>;
1379
1380class IntInputMods <IntInputModsMatchClass matchClass> : InputMods <matchClass> {
1381  let PrintMethod = "printOperandAndIntInputMods";
1382}
1383def Int32InputMods : IntInputMods<Int32InputModsMatchClass>;
1384def Int64InputMods : IntInputMods<Int64InputModsMatchClass>;
1385def Int32VCSrcInputMods : IntInputMods<Int32VCSrcInputModsMatchClass>;
1386
1387class OpSelModsMatchClass : AsmOperandClass {
1388  let Name = "OpSelMods";
1389  let ParserMethod = "parseRegOrImm";
1390  let PredicateMethod = "isRegOrImm";
1391}
1392
1393def IntOpSelModsMatchClass : OpSelModsMatchClass;
1394def IntOpSelMods : InputMods<IntOpSelModsMatchClass>;
1395
1396class FPSDWAInputModsMatchClass <int opSize> : AsmOperandClass {
1397  let Name = "SDWAWithFP"#opSize#"InputMods";
1398  let ParserMethod = "parseRegOrImmWithFPInputMods";
1399  let PredicateMethod = "isSDWAFP"#opSize#"Operand";
1400}
1401
1402def FP16SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<16>;
1403def FP32SDWAInputModsMatchClass : FPSDWAInputModsMatchClass<32>;
1404
1405class FPSDWAInputMods <FPSDWAInputModsMatchClass matchClass> :
1406  InputMods <matchClass> {
1407  let PrintMethod = "printOperandAndFPInputMods";
1408}
1409
1410def FP16SDWAInputMods : FPSDWAInputMods<FP16SDWAInputModsMatchClass>;
1411def FP32SDWAInputMods : FPSDWAInputMods<FP32SDWAInputModsMatchClass>;
1412
1413def FPVRegInputModsMatchClass : AsmOperandClass {
1414  let Name = "VRegWithFPInputMods";
1415  let ParserMethod = "parseRegWithFPInputMods";
1416  let PredicateMethod = "isVRegWithInputMods";
1417}
1418
1419def FPVRegInputMods : InputMods <FPVRegInputModsMatchClass> {
1420  let PrintMethod = "printOperandAndFPInputMods";
1421}
1422
1423class IntSDWAInputModsMatchClass <int opSize> : AsmOperandClass {
1424  let Name = "SDWAWithInt"#opSize#"InputMods";
1425  let ParserMethod = "parseRegOrImmWithIntInputMods";
1426  let PredicateMethod = "isSDWAInt"#opSize#"Operand";
1427}
1428
1429def Int16SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<16>;
1430def Int32SDWAInputModsMatchClass : IntSDWAInputModsMatchClass<32>;
1431
1432class IntSDWAInputMods <IntSDWAInputModsMatchClass matchClass> :
1433  InputMods <matchClass> {
1434  let PrintMethod = "printOperandAndIntInputMods";
1435}
1436
1437def Int16SDWAInputMods : IntSDWAInputMods<Int16SDWAInputModsMatchClass>;
1438def Int32SDWAInputMods : IntSDWAInputMods<Int32SDWAInputModsMatchClass>;
1439
1440def IntVRegInputModsMatchClass : AsmOperandClass {
1441  let Name = "VRegWithIntInputMods";
1442  let ParserMethod = "parseRegWithIntInputMods";
1443  let PredicateMethod = "isVRegWithInputMods";
1444}
1445
1446def IntVRegInputMods : InputMods <IntVRegInputModsMatchClass> {
1447  let PrintMethod = "printOperandAndIntInputMods";
1448}
1449
1450class PackedFPInputModsMatchClass <int opSize> : AsmOperandClass {
1451  let Name = "PackedFP"#opSize#"InputMods";
1452  let ParserMethod = "parseRegOrImm";
1453  let PredicateMethod = "isRegOrImm";
1454//  let PredicateMethod = "isPackedFP"#opSize#"InputMods";
1455}
1456
1457class PackedIntInputModsMatchClass <int opSize> : AsmOperandClass {
1458  let Name = "PackedInt"#opSize#"InputMods";
1459  let ParserMethod = "parseRegOrImm";
1460  let PredicateMethod = "isRegOrImm";
1461//  let PredicateMethod = "isPackedInt"#opSize#"InputMods";
1462}
1463
1464def PackedF16InputModsMatchClass : PackedFPInputModsMatchClass<16>;
1465def PackedI16InputModsMatchClass : PackedIntInputModsMatchClass<16>;
1466
1467class PackedFPInputMods <PackedFPInputModsMatchClass matchClass> : InputMods <matchClass> {
1468//  let PrintMethod = "printPackedFPInputMods";
1469}
1470
1471class PackedIntInputMods <PackedIntInputModsMatchClass matchClass> : InputMods <matchClass> {
1472  //let PrintMethod = "printPackedIntInputMods";
1473}
1474
1475def PackedF16InputMods : PackedFPInputMods<PackedF16InputModsMatchClass>;
1476def PackedI16InputMods : PackedIntInputMods<PackedI16InputModsMatchClass>;
1477
1478//===----------------------------------------------------------------------===//
1479// Complex patterns
1480//===----------------------------------------------------------------------===//
1481
1482def DS1Addr1Offset : ComplexPattern<iPTR, 2, "SelectDS1Addr1Offset">;
1483def DS64Bit4ByteAligned : ComplexPattern<iPTR, 3, "SelectDS64Bit4ByteAligned">;
1484def DS128Bit8ByteAligned : ComplexPattern<iPTR, 3, "SelectDS128Bit8ByteAligned">;
1485
1486def MOVRELOffset : ComplexPattern<iPTR, 2, "SelectMOVRELOffset">;
1487
1488def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
1489def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
1490def VOP3NoMods : ComplexPattern<untyped, 1, "SelectVOP3NoMods">;
1491// VOP3Mods, but the input source is known to never be NaN.
1492def VOP3Mods_nnan : ComplexPattern<fAny, 2, "SelectVOP3Mods_NNaN">;
1493
1494def VOP3OMods : ComplexPattern<untyped, 3, "SelectVOP3OMods">;
1495
1496def VOP3PMods  : ComplexPattern<untyped, 2, "SelectVOP3PMods">;
1497
1498def VOP3PModsDOT  : ComplexPattern<untyped, 2, "SelectVOP3PModsDOT">;
1499def DotIUVOP3PMods  : ComplexPattern<untyped, 1, "SelectDotIUVOP3PMods">;
1500
1501def VOP3OpSel  : ComplexPattern<untyped, 2, "SelectVOP3OpSel">;
1502
1503def VOP3OpSelMods  : ComplexPattern<untyped, 2, "SelectVOP3OpSelMods">;
1504
1505def VOP3PMadMixMods  : ComplexPattern<untyped, 2, "SelectVOP3PMadMixMods">;
1506
1507def VINTERPMods  : ComplexPattern<untyped, 2, "SelectVINTERPMods">;
1508def VINTERPModsHi  : ComplexPattern<untyped, 2, "SelectVINTERPModsHi">;
1509
1510//===----------------------------------------------------------------------===//
1511// SI assembler operands
1512//===----------------------------------------------------------------------===//
1513
1514def SIOperand {
1515  int ZERO = 0x80;
1516  int VCC = 0x6A;
1517  int FLAT_SCR = 0x68;
1518}
1519
1520// This should be kept in sync with SISrcMods enum
1521def SRCMODS {
1522  int NONE = 0;
1523  int NEG = 1;
1524  int ABS = 2;
1525  int NEG_ABS = 3;
1526
1527  int NEG_HI = ABS;
1528  int OP_SEL_0 = 4;
1529  int OP_SEL_1 = 8;
1530  int DST_OP_SEL = 8;
1531}
1532
1533def DSTCLAMP {
1534  int NONE = 0;
1535  int ENABLE = 1;
1536}
1537
1538def DSTOMOD {
1539  int NONE = 0;
1540}
1541
1542def HWREG {
1543  int MODE = 1;
1544  int STATUS = 2;
1545  int TRAPSTS = 3;
1546  int HW_ID = 4;
1547  int GPR_ALLOC = 5;
1548  int LDS_ALLOC = 6;
1549  int IB_STS = 7;
1550  int MEM_BASES = 15;
1551  int TBA_LO = 16;
1552  int TBA_HI = 17;
1553  int TMA_LO = 18;
1554  int TMA_HI = 19;
1555  int FLAT_SCR_LO = 20;
1556  int FLAT_SCR_HI = 21;
1557  int XNACK_MASK = 22;
1558  int POPS_PACKER = 25;
1559  int SHADER_CYCLES = 29;
1560}
1561
1562class getHwRegImm<int Reg, int Offset = 0, int Size = 32> {
1563  int ret = !and(!or(Reg,
1564                     !shl(Offset, 6),
1565                     !shl(!add(Size, -1), 11)), 65535);
1566}
1567
1568//===----------------------------------------------------------------------===//
1569//
1570// SI Instruction multiclass helpers.
1571//
1572// Instructions with _32 take 32-bit operands.
1573// Instructions with _64 take 64-bit operands.
1574//
1575// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
1576// encoding is the standard encoding, but instruction that make use of
1577// any of the instruction modifiers must use the 64-bit encoding.
1578//
1579// Instructions with _e32 use the 32-bit encoding.
1580// Instructions with _e64 use the 64-bit encoding.
1581//
1582//===----------------------------------------------------------------------===//
1583
1584class SIMCInstr <string pseudo, int subtarget> {
1585  string PseudoInstr = pseudo;
1586  int Subtarget = subtarget;
1587}
1588
1589//===----------------------------------------------------------------------===//
1590// Vector ALU classes
1591//===----------------------------------------------------------------------===//
1592
1593class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
1594  int ret =
1595    !if (!eq(Src0.Value, untyped.Value),      0,
1596      !if (!eq(Src1.Value, untyped.Value),    1,   // VOP1
1597         !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
1598                                              3))); // VOP3
1599}
1600
1601// Returns the register class to use for the destination of VOP[123C]
1602// instructions for the given VT.
1603class getVALUDstForVT<ValueType VT> {
1604  RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
1605                          !if(!eq(VT.Size, 128), VOPDstOperand<VReg_128>,
1606                            !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
1607                              !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>,
1608                              VOPDstS64orS32)))); // else VT == i1
1609}
1610
1611// Returns the register class to use for the destination of VOP[12C]
1612// instructions with SDWA extension
1613class getSDWADstForVT<ValueType VT> {
1614  RegisterOperand ret = !if(!eq(VT.Size, 1),
1615                            SDWAVopcDst, // VOPC
1616                            VOPDstOperand<VGPR_32>); // VOP1/2 32-bit dst
1617}
1618
1619// Returns the register class to use for source 0 of VOP[12C]
1620// instructions for the given VT.
1621class getVOPSrc0ForVT<ValueType VT> {
1622  bit isFP = isFloatType<VT>.ret;
1623
1624  RegisterOperand ret =
1625    !if(isFP,
1626      !if(!eq(VT.Size, 64),
1627         VSrc_f64,
1628         !if(!eq(VT.Value, f16.Value),
1629            VSrc_f16,
1630            !if(!eq(VT.Value, v2f16.Value),
1631               VSrc_v2f16,
1632               !if(!eq(VT.Value, v4f16.Value),
1633                 AVSrc_64,
1634                 VSrc_f32
1635               )
1636            )
1637         )
1638       ),
1639       !if(!eq(VT.Size, 64),
1640          VSrc_b64,
1641          !if(!eq(VT.Value, i16.Value),
1642             VSrc_b16,
1643             !if(!eq(VT.Value, v2i16.Value),
1644                VSrc_v2b16,
1645                VSrc_b32
1646             )
1647          )
1648       )
1649    );
1650}
1651
1652class getSOPSrcForVT<ValueType VT> {
1653  RegisterOperand ret = !if(!eq(VT.Size, 64), SSrc_b64, SSrc_b32);
1654}
1655
1656// Returns the vreg register class to use for source operand given VT
1657class getVregSrcForVT<ValueType VT> {
1658  RegisterClass ret = !if(!eq(VT.Size, 128), VReg_128,
1659                        !if(!eq(VT.Size, 96), VReg_96,
1660                          !if(!eq(VT.Size, 64), VReg_64,
1661                            !if(!eq(VT.Size, 48), VReg_64,
1662                              VGPR_32))));
1663}
1664
1665class getSDWASrcForVT <ValueType VT> {
1666  bit isFP = isFloatType<VT>.ret;
1667  RegisterOperand retFlt = !if(!eq(VT.Size, 16), SDWASrc_f16, SDWASrc_f32);
1668  RegisterOperand retInt = !if(!eq(VT.Size, 16), SDWASrc_i16, SDWASrc_i32);
1669  RegisterOperand ret = !if(isFP, retFlt, retInt);
1670}
1671
1672// Returns the register class to use for sources of VOP3 instructions for the
1673// given VT.
1674class getVOP3SrcForVT<ValueType VT> {
1675  bit isFP = isFloatType<VT>.ret;
1676  RegisterOperand ret =
1677  !if(!eq(VT.Size, 128),
1678     VSrc_128,
1679     !if(!eq(VT.Size, 64),
1680        !if(isFP,
1681           !if(!eq(VT.Value, v2f32.Value),
1682               VSrc_v2f32,
1683               VSrc_f64),
1684           !if(!eq(VT.Value, v2i32.Value),
1685               VSrc_v2b32,
1686           VSrc_b64)),
1687        !if(!eq(VT.Value, i1.Value),
1688           SSrc_i1,
1689           !if(isFP,
1690              !if(!eq(VT.Value, f16.Value),
1691                 VSrc_f16,
1692                 !if(!eq(VT.Value, v2f16.Value),
1693                    VSrc_v2f16,
1694                    !if(!eq(VT.Value, v4f16.Value),
1695                      AVSrc_64,
1696                      VSrc_f32
1697                    )
1698                 )
1699              ),
1700              !if(!eq(VT.Value, i16.Value),
1701                 VSrc_b16,
1702                 !if(!eq(VT.Value, v2i16.Value),
1703                    VSrc_v2b16,
1704                    VSrc_b32
1705                 )
1706              )
1707           )
1708        )
1709     )
1710  );
1711}
1712
1713// Src2 of VOP3 DPP instructions cannot be a literal
1714class getVOP3DPPSrcForVT<ValueType VT> {
1715  bit isFP = isFloatType<VT>.ret;
1716  RegisterOperand ret =
1717      !if (!eq(VT.Value, i1.Value), SSrc_i1,
1718           !if (isFP,
1719                !if (!eq(VT.Value, f16.Value), VCSrc_f16,
1720                     !if (!eq(VT.Value, v2f16.Value), VCSrc_v2f16, VCSrc_f32)),
1721                !if (!eq(VT.Value, i16.Value), VCSrc_b16,
1722                     !if (!eq(VT.Value, v2i16.Value), VCSrc_v2b16,
1723                          VCSrc_b32))));
1724}
1725
1726// Float or packed int
1727class isModifierType<ValueType SrcVT> {
1728  bit ret = !or(!eq(SrcVT.Value, f16.Value),
1729                !eq(SrcVT.Value, f32.Value),
1730                !eq(SrcVT.Value, f64.Value),
1731                !eq(SrcVT.Value, v2f16.Value),
1732                !eq(SrcVT.Value, v2i16.Value),
1733                !eq(SrcVT.Value, v2f32.Value),
1734                !eq(SrcVT.Value, v2i32.Value),
1735                !eq(SrcVT.Value, v4f32.Value),
1736                !eq(SrcVT.Value, v4i32.Value),
1737                !eq(SrcVT.Value, v8f32.Value),
1738                !eq(SrcVT.Value, v8i32.Value));
1739}
1740
1741// Return type of input modifiers operand for specified input operand
1742class getSrcMod <ValueType VT, bit EnableF32SrcMods> {
1743  bit isFP = isFloatType<VT>.ret;
1744  bit isPacked = isPackedType<VT>.ret;
1745  Operand ret =  !if(!eq(VT.Size, 64),
1746                     !if(isFP, FP64InputMods, Int64InputMods),
1747                       !if(isFP,
1748                         !if(!eq(VT.Value, f16.Value),
1749                            FP16InputMods,
1750                            FP32InputMods
1751                          ),
1752                         !if(EnableF32SrcMods, FP32InputMods, Int32InputMods))
1753                     );
1754}
1755
1756class getOpSelMod <ValueType VT> {
1757  Operand ret = !if(!eq(VT.Value, f16.Value), FP16InputMods, IntOpSelMods);
1758}
1759
1760// Return type of input modifiers operand specified input operand for DPP
1761class getSrcModDPP <ValueType VT> {
1762  bit isFP = isFloatType<VT>.ret;
1763  Operand ret = !if(isFP, FPVRegInputMods, IntVRegInputMods);
1764}
1765
1766// Return type of input modifiers operand for specified input operand for DPP
1767class getSrcModVOP3DPP <ValueType VT, bit EnableF32SrcMods> {
1768  bit isFP = isFloatType<VT>.ret;
1769  bit isPacked = isPackedType<VT>.ret;
1770  Operand ret =
1771      !if (isFP,
1772           !if (!eq(VT.Value, f16.Value), FP16VCSrcInputMods,
1773                FP32VCSrcInputMods),
1774           !if (EnableF32SrcMods, FP32VCSrcInputMods, Int32VCSrcInputMods));
1775}
1776
1777// Return type of input modifiers operand specified input operand for SDWA
1778class getSrcModSDWA <ValueType VT> {
1779  Operand ret = !if(!eq(VT.Value, f16.Value), FP16SDWAInputMods,
1780                !if(!eq(VT.Value, f32.Value), FP32SDWAInputMods,
1781                !if(!eq(VT.Value, i16.Value), Int16SDWAInputMods,
1782                Int32SDWAInputMods)));
1783}
1784
1785// Returns the input arguments for VOP[12C] instructions for the given SrcVT.
1786class getIns32 <RegisterOperand Src0RC, RegisterOperand Src1RC, int NumSrcArgs> {
1787  dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
1788            !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
1789                                    (ins)));
1790}
1791
1792// Returns the input arguments for VOP3 instructions for the given SrcVT.
1793class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
1794                RegisterOperand Src2RC, int NumSrcArgs,
1795                bit HasClamp, bit HasModifiers, bit HasSrc2Mods, bit HasOMod,
1796                Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1797
1798  dag ret =
1799    !if (!eq(NumSrcArgs, 0),
1800      // VOP1 without input operands (V_NOP, V_CLREXCP)
1801      (ins),
1802      /* else */
1803    !if (!eq(NumSrcArgs, 1),
1804      !if (HasModifiers,
1805        // VOP1 with modifiers
1806        !if(HasOMod,
1807          (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1808               clampmod0:$clamp, omod0:$omod),
1809          (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1810               clampmod0:$clamp))
1811      /* else */,
1812        // VOP1 without modifiers
1813        !if (HasClamp,
1814          (ins Src0RC:$src0, clampmod0:$clamp),
1815          (ins Src0RC:$src0))
1816      /* endif */ ),
1817    !if (!eq(NumSrcArgs, 2),
1818      !if (HasModifiers,
1819        // VOP 2 with modifiers
1820        !if(HasOMod,
1821          (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1822               Src1Mod:$src1_modifiers, Src1RC:$src1,
1823               clampmod0:$clamp, omod0:$omod),
1824           (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1825               Src1Mod:$src1_modifiers, Src1RC:$src1,
1826               clampmod0:$clamp))
1827      /* else */,
1828        // VOP2 without modifiers
1829        !if (HasClamp,
1830          (ins Src0RC:$src0, Src1RC:$src1, clampmod0:$clamp),
1831          (ins Src0RC:$src0, Src1RC:$src1))
1832
1833      /* endif */ )
1834    /* NumSrcArgs == 3 */,
1835      !if (HasModifiers,
1836        !if (HasSrc2Mods,
1837          // VOP3 with modifiers
1838          !if (HasOMod,
1839            (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1840                 Src1Mod:$src1_modifiers, Src1RC:$src1,
1841                 Src2Mod:$src2_modifiers, Src2RC:$src2,
1842                 clampmod0:$clamp, omod0:$omod),
1843            !if (HasClamp,
1844              (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1845                   Src1Mod:$src1_modifiers, Src1RC:$src1,
1846                   Src2Mod:$src2_modifiers, Src2RC:$src2,
1847                   clampmod0:$clamp),
1848              (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1849                   Src1Mod:$src1_modifiers, Src1RC:$src1,
1850                   Src2Mod:$src2_modifiers, Src2RC:$src2))),
1851          // VOP3 with modifiers except src2
1852          !if (HasOMod,
1853            (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1854                 Src1Mod:$src1_modifiers, Src1RC:$src1,
1855                 Src2RC:$src2, clampmod0:$clamp, omod0:$omod),
1856            !if (HasClamp,
1857              (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1858                   Src1Mod:$src1_modifiers, Src1RC:$src1,
1859                   Src2RC:$src2, clampmod0:$clamp),
1860              (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1861                   Src1Mod:$src1_modifiers, Src1RC:$src1,
1862                   Src2RC:$src2))))
1863      /* else */,
1864        // VOP3 without modifiers
1865        !if (HasClamp,
1866          (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2, clampmod0:$clamp),
1867          (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2))
1868      /* endif */ ))));
1869}
1870
1871class getInsVOP3Base<RegisterOperand Src0RC, RegisterOperand Src1RC,
1872                RegisterOperand Src2RC, int NumSrcArgs,
1873                bit HasClamp, bit HasModifiers, bit HasSrc2Mods, bit HasOMod,
1874                Operand Src0Mod, Operand Src1Mod, Operand Src2Mod, bit HasOpSel,
1875                bit IsVOP3P> {
1876  // getInst64 handles clamp and omod. implicit mutex between vop3p and omod
1877  dag base = getIns64 <Src0RC, Src1RC, Src2RC, NumSrcArgs,
1878                HasClamp, HasModifiers, HasSrc2Mods, HasOMod,
1879                Src0Mod, Src1Mod, Src2Mod>.ret;
1880  dag opsel = (ins op_sel0:$op_sel);
1881  dag vop3pOpsel = (ins op_sel_hi0:$op_sel_hi);
1882  dag vop3pFields = !con(!if(HasOpSel, vop3pOpsel, (ins)), (ins neg_lo0:$neg_lo, neg_hi0:$neg_hi));
1883
1884  dag ret = !con(base,
1885                 !if(HasOpSel, opsel,(ins)),
1886                 !if(IsVOP3P, vop3pFields,(ins)));
1887}
1888
1889class getInsVOP3P <RegisterOperand Src0RC, RegisterOperand Src1RC,
1890                   RegisterOperand Src2RC, int NumSrcArgs, bit HasClamp, bit HasOpSel,
1891                   Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1892  dag ret = getInsVOP3Base<Src0RC, Src1RC, Src2RC, NumSrcArgs,
1893                    HasClamp, 1/*HasModifiers*/, 1/*HasSrc2Mods*/,
1894                    0/*HasOMod*/, Src0Mod, Src1Mod, Src2Mod,
1895                    HasOpSel, 1/*IsVOP3P*/>.ret;
1896}
1897
1898class getInsVOP3OpSel <RegisterOperand Src0RC, RegisterOperand Src1RC,
1899                       RegisterOperand Src2RC, int NumSrcArgs,
1900                       bit HasClamp, bit HasOMod,
1901                       Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1902  dag ret = getInsVOP3Base<Src0RC, Src1RC,
1903                    Src2RC, NumSrcArgs,
1904                    HasClamp, 1/*HasModifiers*/, 1/*HasSrc2Mods*/, HasOMod,
1905                    Src0Mod, Src1Mod, Src2Mod, 1/*HasOpSel*/, 0>.ret;
1906}
1907
1908class getInsDPPBase <RegisterOperand OldRC, RegisterClass Src0RC, RegisterClass Src1RC,
1909                 RegisterClass Src2RC, int NumSrcArgs, bit HasModifiers,
1910                 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1911
1912  dag ret = !if (!eq(NumSrcArgs, 0),
1913                // VOP1 without input operands (V_NOP)
1914                (ins ),
1915            !if (!eq(NumSrcArgs, 1),
1916              !if (HasModifiers,
1917                // VOP1_DPP with modifiers
1918                (ins OldRC:$old, Src0Mod:$src0_modifiers,
1919                     Src0RC:$src0)
1920              /* else */,
1921                // VOP1_DPP without modifiers
1922                (ins OldRC:$old, Src0RC:$src0)
1923              /* endif */),
1924            !if (!eq(NumSrcArgs, 2),
1925              !if (HasModifiers,
1926                // VOP2_DPP with modifiers
1927                (ins OldRC:$old,
1928                     Src0Mod:$src0_modifiers, Src0RC:$src0,
1929                     Src1Mod:$src1_modifiers, Src1RC:$src1)
1930              /* else */,
1931                // VOP2_DPP without modifiers
1932                (ins OldRC:$old,
1933                     Src0RC:$src0, Src1RC:$src1)
1934                )
1935              /* NumSrcArgs == 3, VOP3 */,
1936              !if (HasModifiers,
1937                // VOP3_DPP with modifiers
1938                (ins OldRC:$old,
1939                     Src0Mod:$src0_modifiers, Src0RC:$src0,
1940                     Src1Mod:$src1_modifiers, Src1RC:$src1,
1941                     Src2Mod:$src2_modifiers, Src2RC:$src2)
1942              /* else */,
1943                // VOP3_DPP without modifiers
1944                (ins OldRC:$old,
1945                     Src0RC:$src0, Src1RC:$src1,
1946                     Src2RC:$src2)
1947                )
1948             /* endif */)));
1949}
1950
1951class getInsDPP <RegisterOperand OldRC, RegisterClass Src0RC, RegisterClass Src1RC,
1952                 RegisterClass Src2RC, int NumSrcArgs, bit HasModifiers,
1953                 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1954  dag ret = !con(getInsDPPBase<OldRC, Src0RC, Src1RC, Src2RC, NumSrcArgs,
1955                           HasModifiers, Src0Mod, Src1Mod, Src2Mod>.ret,
1956                 (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1957                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl));
1958}
1959
1960class getInsDPP16 <RegisterOperand OldRC, RegisterClass Src0RC, RegisterClass Src1RC,
1961                 RegisterClass Src2RC, int NumSrcArgs, bit HasModifiers,
1962                 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1963  dag ret = !con(getInsDPP<OldRC, Src0RC, Src1RC, Src2RC, NumSrcArgs,
1964                           HasModifiers, Src0Mod, Src1Mod, Src2Mod>.ret,
1965                 (ins FI:$fi));
1966}
1967
1968class getInsDPP8 <RegisterOperand OldRC, RegisterClass Src0RC, RegisterClass Src1RC,
1969                 RegisterClass Src2RC, int NumSrcArgs, bit HasModifiers,
1970                 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1971  dag ret = !con(getInsDPPBase<OldRC, Src0RC, Src1RC, Src2RC, NumSrcArgs,
1972                           HasModifiers, Src0Mod, Src1Mod, Src2Mod>.ret,
1973                 (ins dpp8:$dpp8, FI:$fi));
1974}
1975
1976class getInsVOP3DPPBase<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs> {
1977  dag old = ( ins OldRC:$old );
1978  dag base = VOP3Base;
1979  dag ret =  !con(
1980                !if(!ne(NumSrcArgs, 0), old, (ins)),
1981                base
1982              );
1983}
1984
1985class getInsVOP3DPP<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs> {
1986  dag ret = !con(getInsVOP3DPPBase<VOP3Base,OldRC,NumSrcArgs>.ret,
1987                 (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1988                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl));
1989}
1990
1991class getInsVOP3DPP16<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs> {
1992  dag ret = !con(getInsVOP3DPP<VOP3Base,OldRC,NumSrcArgs>.ret,
1993                 (ins FI:$fi));
1994}
1995
1996class getInsVOP3DPP8<dag VOP3Base, RegisterOperand OldRC, int NumSrcArgs> {
1997  dag ret = !con(getInsVOP3DPPBase<VOP3Base,OldRC,NumSrcArgs>.ret,
1998                 (ins dpp8:$dpp8, FI:$fi));
1999}
2000
2001// Ins for SDWA
2002class getInsSDWA <RegisterOperand Src0RC, RegisterOperand Src1RC, int NumSrcArgs,
2003                  bit HasSDWAOMod, Operand Src0Mod, Operand Src1Mod,
2004                  ValueType DstVT> {
2005
2006  dag ret = !if(!eq(NumSrcArgs, 0),
2007               // VOP1 without input operands (V_NOP)
2008               (ins),
2009            !if(!eq(NumSrcArgs, 1),
2010               // VOP1
2011               !if(!not(HasSDWAOMod),
2012                  // VOP1_SDWA without omod
2013                  (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
2014                       clampmod:$clamp,
2015                       dst_sel:$dst_sel, dst_unused:$dst_unused,
2016                       src0_sel:$src0_sel),
2017                  // VOP1_SDWA with omod
2018                  (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
2019                       clampmod:$clamp, omod:$omod,
2020                       dst_sel:$dst_sel, dst_unused:$dst_unused,
2021                       src0_sel:$src0_sel)),
2022            !if(!eq(NumSrcArgs, 2),
2023               !if(!eq(DstVT.Size, 1),
2024                  // VOPC_SDWA
2025                  (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
2026                       Src1Mod:$src1_modifiers, Src1RC:$src1,
2027                       clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel),
2028                  // VOP2_SDWA
2029                  !if(!not(HasSDWAOMod),
2030                     // VOP2_SDWA without omod
2031                     (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
2032                          Src1Mod:$src1_modifiers, Src1RC:$src1,
2033                          clampmod:$clamp,
2034                          dst_sel:$dst_sel, dst_unused:$dst_unused,
2035                          src0_sel:$src0_sel, src1_sel:$src1_sel),
2036                     // VOP2_SDWA with omod
2037                     (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
2038                          Src1Mod:$src1_modifiers, Src1RC:$src1,
2039                          clampmod:$clamp, omod:$omod,
2040                          dst_sel:$dst_sel, dst_unused:$dst_unused,
2041                          src0_sel:$src0_sel, src1_sel:$src1_sel))),
2042            (ins)/* endif */)));
2043}
2044
2045// Outs for DPP
2046class getOutsDPP <bit HasDst, ValueType DstVT, RegisterOperand DstRCDPP> {
2047  dag ret = !if(HasDst,
2048                !if(!eq(DstVT.Size, 1),
2049                    (outs), // no dst for VOPC, we use "vcc"-token as dst in SDWA VOPC instructions
2050                    (outs DstRCDPP:$vdst)),
2051                (outs)); // V_NOP
2052}
2053
2054// Outs for SDWA
2055class getOutsSDWA <bit HasDst, ValueType DstVT, RegisterOperand DstRCSDWA> {
2056  dag ret = !if(HasDst,
2057                !if(!eq(DstVT.Size, 1),
2058                    (outs DstRCSDWA:$sdst),
2059                    (outs DstRCSDWA:$vdst)),
2060                (outs)); // V_NOP
2061}
2062
2063// Returns the assembly string for the inputs and outputs of a VOP[12C]
2064// instruction.  This does not add the _e32 suffix, so it can be reused
2065// by getAsm64.
2066class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
2067  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
2068  string src0 = ", $src0";
2069  string src1 = ", $src1";
2070  string src2 = ", $src2";
2071  string ret = !if(HasDst, dst, "") #
2072               !if(!eq(NumSrcArgs, 1), src0, "") #
2073               !if(!eq(NumSrcArgs, 2), src0#src1, "") #
2074               !if(!eq(NumSrcArgs, 3), src0#src1#src2, "");
2075}
2076
2077class getAsmVOPDPart <int NumSrcArgs, string XorY> {
2078  string dst = "$vdst" # XorY;
2079  string src0 = ", $src0" # XorY;
2080  string src1 = ", $vsrc1" # XorY;
2081  string ret = dst #
2082               !if(!ge(NumSrcArgs, 1), src0, "") #
2083               !if(!ge(NumSrcArgs, 2), src1, "");
2084}
2085
2086// Returns the assembly string for the inputs and outputs of a VOP3
2087// instruction.
2088class getAsm64 <bit HasDst, int NumSrcArgs, bit HasIntClamp, bit HasModifiers,
2089                bit HasOMod, ValueType DstVT = i32> {
2090  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
2091  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
2092  string src1 = !if(!eq(NumSrcArgs, 1), "",
2093                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
2094                                           " $src1_modifiers,"));
2095  string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
2096  string iclamp = !if(HasIntClamp, "$clamp", "");
2097  string ret =
2098  !if(!not(HasModifiers),
2099      getAsm32<HasDst, NumSrcArgs, DstVT>.ret # iclamp,
2100      dst#", "#src0#src1#src2#"$clamp"#!if(HasOMod, "$omod", ""));
2101}
2102
2103// Returns the assembly string for the inputs and outputs of a VOP3P
2104// instruction.
2105class getAsmVOP3P <int NumSrcArgs, bit HasModifiers,
2106                   bit HasClamp, bit HasOpSel> {
2107  string dst = "$vdst";
2108  string src0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,");
2109  string src1 = !if(!eq(NumSrcArgs, 1), "",
2110                   !if(!eq(NumSrcArgs, 2), " $src1",
2111                                           " $src1,"));
2112  string src2 = !if(!eq(NumSrcArgs, 3), " $src2", "");
2113
2114  string mods = !if(HasModifiers, "$neg_lo$neg_hi", "");
2115  string clamp = !if(HasClamp, "$clamp", "");
2116  string opsel = !if(HasOpSel, "$op_sel$op_sel_hi", "");
2117
2118  // Each modifier is printed as an array of bits for each operand, so
2119  // all operands are printed as part of src0_modifiers.
2120  string ret = dst#", "#src0#src1#src2#opsel#mods#clamp;
2121}
2122
2123class getAsmVOP3OpSel <int NumSrcArgs,
2124                       bit HasClamp,
2125                       bit Src0HasMods,
2126                       bit Src1HasMods,
2127                       bit Src2HasMods> {
2128  string dst = "$vdst";
2129
2130  string isrc0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,");
2131  string isrc1 = !if(!eq(NumSrcArgs, 1), "",
2132                     !if(!eq(NumSrcArgs, 2), " $src1",
2133                                             " $src1,"));
2134  string isrc2 = !if(!eq(NumSrcArgs, 3), " $src2", "");
2135
2136  string fsrc0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
2137  string fsrc1 = !if(!eq(NumSrcArgs, 1), "",
2138                     !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
2139                                             " $src1_modifiers,"));
2140  string fsrc2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
2141
2142  string src0 = !if(Src0HasMods, fsrc0, isrc0);
2143  string src1 = !if(Src1HasMods, fsrc1, isrc1);
2144  string src2 = !if(Src2HasMods, fsrc2, isrc2);
2145
2146  string clamp = !if(HasClamp, "$clamp", "");
2147  string omod = "";
2148  string ret = dst#", "#src0#src1#src2#"$op_sel"#clamp#omod;
2149}
2150
2151class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
2152  string dst = !if(HasDst,
2153                   !if(!eq(DstVT.Size, 1),
2154                       "$sdst",
2155                       "$vdst"),
2156                    ""); // use $sdst for VOPC
2157  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
2158  string src1 = !if(!eq(NumSrcArgs, 1), "",
2159                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
2160                                           " $src1_modifiers,"));
2161  string args = !if(!not(HasModifiers),
2162                     getAsm32<0, NumSrcArgs, DstVT>.ret,
2163                     ", "#src0#src1);
2164  string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
2165}
2166
2167class getAsmDPP16 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
2168  string ret = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret#"$fi";
2169}
2170
2171class getAsmDPP8 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32>
2172  : getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>{
2173  let ret = dst#args#" $dpp8$fi";
2174}
2175
2176class getAsmVOP3DPPBase <int NumSrcArgs, bit HasDst, bit HasClamp,
2177                       bit HasOpSel, bit HasOMod, bit IsVOP3P,
2178                       bit HasModifiers, bit Src0HasMods,
2179                       bit Src1HasMods, bit Src2HasMods, ValueType DstVT = i32> {
2180  string dst = !if(HasDst,
2181                   !if(!eq(DstVT.Size, 1),
2182                       "$sdst",
2183                       "$vdst"),
2184                    ""); // use $sdst for VOPC
2185  string isrc0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,");
2186  string isrc1 = !if(!eq(NumSrcArgs, 1), "",
2187                     !if(!eq(NumSrcArgs, 2), " $src1",
2188                                             " $src1,"));
2189  string isrc2 = !if(!eq(NumSrcArgs, 3), " $src2", "");
2190
2191  string fsrc0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
2192  string fsrc1 = !if(!eq(NumSrcArgs, 1), "",
2193                     !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
2194                                             " $src1_modifiers,"));
2195  string fsrc2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
2196
2197  string src0 = !if(Src0HasMods, fsrc0, isrc0);
2198  string src1 = !if(Src1HasMods, fsrc1, isrc1);
2199  string src2 = !if(Src2HasMods, fsrc2, isrc2);
2200  string opsel = !if(HasOpSel, "$op_sel", "");
2201  string 3PMods = !if(IsVOP3P,
2202                      !if(HasOpSel, "$op_sel_hi", "")
2203                        #!if(HasModifiers, "$neg_lo$neg_hi", ""),
2204                      "");
2205  string clamp = !if(HasClamp, "$clamp", "");
2206  string omod = !if(HasOMod, "$omod", "");
2207
2208  string ret = dst#", "#src0#src1#src2#opsel#3PMods#clamp#omod;
2209
2210}
2211
2212class getAsmVOP3DPP<string base> {
2213  string ret = base # " $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
2214}
2215
2216class getAsmVOP3DPP16<string base> {
2217  string ret = getAsmVOP3DPP<base>.ret # "$fi";
2218}
2219
2220class getAsmVOP3DPP8<string base> {
2221  string ret = base # " $dpp8$fi";
2222}
2223
2224
2225class getAsmSDWA <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
2226  string dst = !if(HasDst,
2227                   !if(!eq(DstVT.Size, 1),
2228                       " vcc", // use vcc token as dst for VOPC instructions
2229                       "$vdst"),
2230                    "");
2231  string src0 = "$src0_modifiers";
2232  string src1 = "$src1_modifiers";
2233  string args = !if(!eq(NumSrcArgs, 0),
2234                    "",
2235                    !if(!eq(NumSrcArgs, 1),
2236                        ", "#src0#"$clamp",
2237                        ", "#src0#", "#src1#"$clamp"
2238                     )
2239                );
2240  string sdwa = !if(!eq(NumSrcArgs, 0),
2241                    "",
2242                    !if(!eq(NumSrcArgs, 1),
2243                        " $dst_sel $dst_unused $src0_sel",
2244                        !if(!eq(DstVT.Size, 1),
2245                            " $src0_sel $src1_sel", // No dst_sel and dst_unused for VOPC
2246                            " $dst_sel $dst_unused $src0_sel $src1_sel"
2247                        )
2248                    )
2249                );
2250  string ret = dst#args#sdwa;
2251}
2252
2253class getAsmSDWA9 <bit HasDst, bit HasOMod, int NumSrcArgs,
2254                   ValueType DstVT = i32> {
2255  string dst = !if(HasDst,
2256                   !if(!eq(DstVT.Size, 1),
2257                       "$sdst", // VOPC
2258                       "$vdst"), // VOP1/2
2259                    "");
2260  string src0 = "$src0_modifiers";
2261  string src1 = "$src1_modifiers";
2262  string out_mods = !if(!not(HasOMod), "$clamp", "$clamp$omod");
2263  string args = !if(!eq(NumSrcArgs, 0), "",
2264                    !if(!eq(NumSrcArgs, 1),
2265                        ", "#src0,
2266                        ", "#src0#", "#src1
2267                     )
2268                );
2269  string sdwa = !if(!eq(NumSrcArgs, 0), "",
2270                    !if(!eq(NumSrcArgs, 1),
2271                        out_mods#" $dst_sel $dst_unused $src0_sel",
2272                        !if(!eq(DstVT.Size, 1),
2273                            " $src0_sel $src1_sel", // No dst_sel, dst_unused and output modifiers for VOPC
2274                            out_mods#" $dst_sel $dst_unused $src0_sel $src1_sel"
2275                        )
2276                    )
2277                );
2278  string ret = dst#args#sdwa;
2279}
2280
2281class getHas64BitOps <int NumSrcArgs, ValueType DstVT, ValueType Src0VT,
2282                      ValueType Src1VT> {
2283  bit ret = !if(!eq(NumSrcArgs, 3),
2284                0,
2285                !if(!eq(DstVT.Size, 64),
2286                    1,
2287                    !if(!eq(Src0VT.Size, 64),
2288                        1,
2289                        !if(!eq(Src1VT.Size, 64),
2290                            1,
2291                            0
2292                        )
2293                    )
2294                )
2295            );
2296}
2297
2298class getHasSDWA <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
2299                  ValueType Src1VT = i32> {
2300  bit ret = !if(!eq(NumSrcArgs, 3),
2301                0, // NumSrcArgs == 3 - No SDWA for VOP3
2302                !if(!eq(DstVT.Size, 64),
2303                    0, // 64-bit dst - No SDWA for 64-bit operands
2304                    !if(!eq(Src0VT.Size, 64),
2305                        0, // 64-bit src0
2306                        !if(!eq(Src1VT.Size, 64),
2307                            0, // 64-bit src2
2308                            1
2309                        )
2310                    )
2311                )
2312            );
2313}
2314
2315class getHasDPP <int NumSrcArgs> {
2316  bit ret = !if(!eq(NumSrcArgs, 3),
2317                0, // NumSrcArgs == 3 - No DPP for VOP3
2318                1);
2319}
2320
2321class getHasExt32BitDPP <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
2322                 ValueType Src1VT = i32> {
2323  bit ret = !and(getHasDPP<NumSrcArgs>.ret,
2324                 !not(getHas64BitOps<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret));
2325}
2326
2327class getHasExt64BitDPP <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
2328                 ValueType Src1VT = i32> {
2329  bit ret = !and(getHasDPP<NumSrcArgs>.ret,
2330                 getHas64BitOps<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret);
2331}
2332
2333// Function that checks if instruction supports DPP and SDWA
2334class getHasExt <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
2335                 ValueType Src1VT = i32> {
2336  bit ret = !or(getHasDPP<NumSrcArgs>.ret,
2337                getHasSDWA<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret);
2338}
2339
2340// Return an AGPR+VGPR operand class for the given VGPR register class.
2341class getLdStRegisterOperand<RegisterClass RC> {
2342  RegisterOperand ret =
2343    !if(!eq(RC.Size, 32), AVLdSt_32,
2344      !if(!eq(RC.Size, 64), AVLdSt_64,
2345        !if(!eq(RC.Size, 96), AVLdSt_96,
2346          !if(!eq(RC.Size, 128), AVLdSt_128,
2347            !if(!eq(RC.Size, 160), AVLdSt_160,
2348              RegisterOperand<VReg_1> // invalid register
2349    )))));
2350}
2351
2352class BitOr<bit a, bit b> {
2353  bit ret = !if(a, 1, !if(b, 1, 0));
2354}
2355
2356class BitAnd<bit a, bit b> {
2357  bit ret = !if(a, !if(b, 1, 0), 0);
2358}
2359
2360class getHasVOP3DPP <ValueType DstVT = i32, ValueType Src0VT = i32,
2361                 ValueType Src1VT = i32, ValueType Src2VT = i32> {
2362  bit ret =    !if(!eq(DstVT.Size, 64),
2363                    0, // 64-bit dst No DPP for 64-bit operands
2364                    !if(!eq(Src0VT.Size, 64),
2365                        0, // 64-bit src0
2366                        !if(!eq(Src1VT.Size, 64),
2367                            0, // 64-bit src1
2368                            !if(!eq(Src2VT.Size, 64),
2369                                0, // 64-bit src2
2370                                1
2371                            )
2372                        )
2373                    )
2374                );
2375}
2376
2377
2378def PatGenMode {
2379  int NoPattern = 0;
2380  int Pattern   = 1;
2381}
2382
2383class VOPProfile <list<ValueType> _ArgVT, bit _EnableF32SrcMods = 0,
2384                  bit _EnableClamp = 0> {
2385
2386  field list<ValueType> ArgVT = _ArgVT;
2387  field bit EnableF32SrcMods = _EnableF32SrcMods;
2388  field bit EnableClamp = _EnableClamp;
2389
2390  field ValueType DstVT = ArgVT[0];
2391  field ValueType Src0VT = ArgVT[1];
2392  field ValueType Src1VT = ArgVT[2];
2393  field ValueType Src2VT = ArgVT[3];
2394  field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
2395  field RegisterOperand DstRC64 = DstRC;
2396  field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret;
2397  field RegisterOperand DstRCSDWA = getSDWADstForVT<DstVT>.ret;
2398  field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
2399  field RegisterOperand Src1RC32 = RegisterOperand<getVregSrcForVT<Src1VT>.ret>;
2400  field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
2401  field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
2402  field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
2403  field RegisterClass Src0DPP = getVregSrcForVT<Src0VT>.ret;
2404  field RegisterClass Src1DPP = getVregSrcForVT<Src1VT>.ret;
2405  field RegisterClass Src2DPP = getVregSrcForVT<Src2VT>.ret;
2406  field RegisterOperand Src0VOP3DPP = VGPRSrc_32;
2407  field RegisterOperand Src1VOP3DPP = VGPRSrc_32;
2408  field RegisterOperand Src2VOP3DPP = getVOP3DPPSrcForVT<Src2VT>.ret;
2409  field RegisterOperand Src0SDWA = getSDWASrcForVT<Src0VT>.ret;
2410  field RegisterOperand Src1SDWA = getSDWASrcForVT<Src0VT>.ret;
2411  field Operand Src0Mod = getSrcMod<Src0VT, EnableF32SrcMods>.ret;
2412  field Operand Src1Mod = getSrcMod<Src1VT, EnableF32SrcMods>.ret;
2413  field Operand Src2Mod = getSrcMod<Src2VT, EnableF32SrcMods>.ret;
2414  field Operand Src0ModDPP = getSrcModDPP<Src0VT>.ret;
2415  field Operand Src1ModDPP = getSrcModDPP<Src1VT>.ret;
2416  field Operand Src2ModDPP = getSrcModDPP<Src2VT>.ret;
2417  field Operand Src2ModVOP3DPP = getSrcModVOP3DPP<Src2VT, EnableF32SrcMods>.ret;
2418  field Operand Src0ModSDWA = getSrcModSDWA<Src0VT>.ret;
2419  field Operand Src1ModSDWA = getSrcModSDWA<Src1VT>.ret;
2420
2421
2422  field bit HasDst = !ne(DstVT.Value, untyped.Value);
2423  field bit HasDst32 = HasDst;
2424  field bit EmitDst = HasDst; // force dst encoding, see v_movreld_b32 special case
2425  field bit EmitDstSel = EmitDst;
2426  field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
2427  field bit HasSrc0 = !ne(Src0VT.Value, untyped.Value);
2428  field bit HasSrc1 = !ne(Src1VT.Value, untyped.Value);
2429  field bit HasSrc2 = !ne(Src2VT.Value, untyped.Value);
2430
2431  // HasSrc*FloatMods affects the SDWA encoding. We ignore EnableF32SrcMods.
2432  field bit HasSrc0FloatMods = isFloatType<Src0VT>.ret;
2433  field bit HasSrc1FloatMods = isFloatType<Src1VT>.ret;
2434  field bit HasSrc2FloatMods = isFloatType<Src2VT>.ret;
2435
2436  // HasSrc*IntMods affects the SDWA encoding. We ignore EnableF32SrcMods.
2437  field bit HasSrc0IntMods = isIntType<Src0VT>.ret;
2438  field bit HasSrc1IntMods = isIntType<Src1VT>.ret;
2439  field bit HasSrc2IntMods = isIntType<Src2VT>.ret;
2440
2441  field bit HasClamp = !or(isModifierType<Src0VT>.ret, EnableClamp);
2442  field bit HasSDWAClamp = EmitDst;
2443  field bit HasFPClamp = !and(isFloatType<DstVT>.ret, HasClamp);
2444  field bit HasIntClamp = !if(isFloatType<DstVT>.ret, 0, HasClamp);
2445  field bit HasClampLo = HasClamp;
2446  field bit HasClampHi = !and(isPackedType<DstVT>.ret, HasClamp);
2447  field bit HasHigh = 0;
2448
2449  field bit IsPacked = isPackedType<Src0VT>.ret;
2450  field bit HasOpSel = IsPacked;
2451  field bit HasOMod = !if(HasOpSel, 0, isFloatType<DstVT>.ret);
2452  field bit HasSDWAOMod = isFloatType<DstVT>.ret;
2453
2454  field bit HasModifiers = !or(isModifierType<Src0VT>.ret,
2455                               isModifierType<Src1VT>.ret,
2456                               isModifierType<Src2VT>.ret,
2457                               HasOMod,
2458                               EnableF32SrcMods);
2459
2460  field bit HasSrc0Mods = HasModifiers;
2461  field bit HasSrc1Mods = !if(HasModifiers, !or(HasSrc1FloatMods, HasSrc1IntMods), 0);
2462  field bit HasSrc2Mods = !if(HasModifiers, !or(HasSrc2FloatMods, HasSrc2IntMods), 0);
2463
2464  field bit HasExt = getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
2465  field bit HasExtVOP3DPP = getHasVOP3DPP<DstVT, Src0VT, Src1VT, Src2VT>.ret;
2466  field bit HasExtDPP = !if(!or(getHasDPP<NumSrcArgs>.ret,
2467                HasExtVOP3DPP), 1, 0);
2468  field bit HasExt32BitDPP = getHasExt32BitDPP<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
2469  field bit HasExt64BitDPP = getHasExt64BitDPP<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
2470  field bit HasExtSDWA = getHasSDWA<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
2471  field bit HasExtSDWA9 = HasExtSDWA;
2472  field int NeedPatGen = PatGenMode.NoPattern;
2473
2474  field bit IsMAI = 0;
2475  field bit IsVOP3P = 0;
2476  field bit IsDOT = 0;
2477  field bit IsSingle = 0;
2478
2479  field Operand Src0PackedMod = !if(HasSrc0FloatMods, PackedF16InputMods, PackedI16InputMods);
2480  field Operand Src1PackedMod = !if(HasSrc1FloatMods, PackedF16InputMods, PackedI16InputMods);
2481  field Operand Src2PackedMod = !if(HasSrc2FloatMods, PackedF16InputMods, PackedI16InputMods);
2482
2483  field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs));
2484
2485  // VOP3b instructions are a special case with a second explicit
2486  // output. This is manually overridden for them.
2487  field dag Outs32 = Outs;
2488  field dag Outs64 = !if(HasDst,(outs DstRC64:$vdst),(outs));
2489  field dag OutsDPP = getOutsDPP<HasDst, DstVT, DstRCDPP>.ret;
2490  field dag OutsDPP8 = getOutsDPP<HasDst, DstVT, DstRCDPP>.ret;
2491  field dag OutsVOP3DPP = OutsDPP;
2492  field dag OutsVOP3DPP8 = OutsDPP8;
2493  field dag OutsSDWA = getOutsSDWA<HasDst, DstVT, DstRCSDWA>.ret;
2494
2495  field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
2496  field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
2497                             HasIntClamp, HasModifiers, HasSrc2Mods,
2498                             HasOMod, Src0Mod, Src1Mod, Src2Mod>.ret;
2499  field dag InsVOP3P = getInsVOP3P<Src0RC64, Src1RC64, Src2RC64,
2500                                   NumSrcArgs, HasClamp, HasOpSel,
2501                                   Src0PackedMod, Src1PackedMod, Src2PackedMod>.ret;
2502  field dag InsVOP3OpSel = getInsVOP3OpSel<Src0RC64, Src1RC64, Src2RC64,
2503                                NumSrcArgs, HasClamp, HasOMod,
2504                                getOpSelMod<Src0VT>.ret,
2505                                getOpSelMod<Src1VT>.ret,
2506                                getOpSelMod<Src2VT>.ret>.ret;
2507  field dag InsDPP = !if(HasExtDPP,
2508                         getInsDPP<DstRCDPP, Src0DPP, Src1DPP, Src2DPP, NumSrcArgs,
2509                                   HasModifiers, Src0ModDPP, Src1ModDPP, Src2ModDPP>.ret,
2510                         (ins));
2511  field dag InsDPP16 = getInsDPP16<DstRCDPP, Src0DPP, Src1DPP, Src2DPP, NumSrcArgs,
2512                                   HasModifiers, Src0ModDPP, Src1ModDPP, Src2ModDPP>.ret;
2513  field dag InsDPP8 = getInsDPP8<DstRCDPP, Src0DPP, Src1DPP, Src2DPP,
2514                                 NumSrcArgs, HasModifiers,
2515                                 Src0ModDPP, Src1ModDPP, Src2ModDPP>.ret;
2516  field dag InsVOP3Base = getInsVOP3Base<Src0VOP3DPP, Src1VOP3DPP,
2517                  Src2VOP3DPP, NumSrcArgs, HasClamp, HasModifiers, HasSrc2Mods, HasOMod,
2518                  Src0ModDPP, Src1ModDPP, Src2ModVOP3DPP, HasOpSel, IsVOP3P>.ret;
2519  field dag InsVOP3DPP = getInsVOP3DPP<InsVOP3Base, DstRCDPP, NumSrcArgs>.ret;
2520  field dag InsVOP3DPP16 = getInsVOP3DPP16<InsVOP3Base, DstRCDPP, NumSrcArgs>.ret;
2521  field dag InsVOP3DPP8 = getInsVOP3DPP8<InsVOP3Base, DstRCDPP, NumSrcArgs>.ret;
2522  field dag InsSDWA = getInsSDWA<Src0SDWA, Src1SDWA, NumSrcArgs,
2523                                 HasSDWAOMod, Src0ModSDWA, Src1ModSDWA,
2524                                 DstVT>.ret;
2525  field dag InsVOPDX = (ins Src0RC32:$src0X, Src1RC32:$vsrc1X);
2526  // It is a slight misnomer to use the deferred f32 operand type for non-float
2527  // operands, but this operand type will only be used if the other dual
2528  // component is FMAAK or FMAMK
2529  field dag InsVOPDXDeferred = (ins !if(!eq(Src0VT.Size, 32), VSrc_f32_Deferred, VSrc_f16_Deferred):$src0X, VGPR_32:$vsrc1X);
2530  field dag InsVOPDY = (ins Src0RC32:$src0Y, Src1RC32:$vsrc1Y);
2531  field dag InsVOPDYDeferred = (ins !if(!eq(Src1VT.Size, 32), VSrc_f32_Deferred, VSrc_f16_Deferred):$src0Y, VGPR_32:$vsrc1Y);
2532
2533
2534  field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret;
2535  field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasIntClamp, HasModifiers, HasOMod, DstVT>.ret;
2536  field string AsmVOP3P = getAsmVOP3P<NumSrcArgs, HasModifiers, HasClamp, HasOpSel>.ret;
2537  field string AsmVOP3OpSel = getAsmVOP3OpSel<NumSrcArgs,
2538                                              HasClamp,
2539                                              HasSrc0FloatMods,
2540                                              HasSrc1FloatMods,
2541                                              HasSrc2FloatMods>.ret;
2542  field string AsmDPP = !if(HasExtDPP,
2543                            getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret, "");
2544  field string AsmDPP16 = getAsmDPP16<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
2545  // DPP8 encoding has no fields for modifiers, and it is enforced by setting
2546  // the asm operand name via this HasModifiers flag
2547  field string AsmDPP8 = getAsmDPP8<HasDst, NumSrcArgs, 0 /*HasModifiers*/, DstVT>.ret;
2548  field string AsmVOP3DPPBase = getAsmVOP3DPPBase<NumSrcArgs, HasDst, HasClamp,
2549   HasOpSel, HasOMod, IsVOP3P, HasModifiers, HasSrc0FloatMods, HasSrc1FloatMods,
2550   HasSrc2FloatMods, DstVT >.ret;
2551  field string AsmVOP3DPP = getAsmVOP3DPP<AsmVOP3DPPBase>.ret;
2552  field string AsmVOP3DPP16 = getAsmVOP3DPP16<AsmVOP3DPPBase>.ret;
2553  field string AsmVOP3DPP8 = getAsmVOP3DPP8<AsmVOP3DPPBase>.ret;
2554  field string AsmSDWA = getAsmSDWA<HasDst, NumSrcArgs, DstVT>.ret;
2555  field string AsmSDWA9 = getAsmSDWA9<HasDst, HasSDWAOMod, NumSrcArgs, DstVT>.ret;
2556  field string AsmVOPDX = getAsmVOPDPart<NumSrcArgs, "X">.ret;
2557  field string AsmVOPDY = getAsmVOPDPart<NumSrcArgs, "Y">.ret;
2558  field string TieRegDPP = "$old";
2559}
2560
2561  class VOP_NO_EXT <VOPProfile p> : VOPProfile <p.ArgVT> {
2562  let HasExt = 0;
2563  let HasExtDPP = 0;
2564  let HasExtVOP3DPP = 0;
2565  let HasExt32BitDPP = 0;
2566  let HasExt64BitDPP = 0;
2567  let HasExtSDWA = 0;
2568  let HasExtSDWA9 = 0;
2569}
2570
2571class VOP_PAT_GEN <VOPProfile p, int mode=PatGenMode.NoPattern> : VOPProfile <p.ArgVT> {
2572  let NeedPatGen = mode;
2573}
2574def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
2575def VOP_F16_I16 : VOPProfile <[f16, i16, untyped, untyped]>;
2576def VOP_I16_F16 : VOPProfile <[i16, f16, untyped, untyped]>;
2577def VOP_I16_I16 : VOPProfile <[i16, i16, untyped, untyped]>;
2578
2579def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
2580def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i16, untyped]>;
2581def VOP_F16_F16_I32 : VOPProfile <[f16, f16, i32, untyped]>;
2582def VOP_I16_I16_I16 : VOPProfile <[i16, i16, i16, untyped]>;
2583def VOP_I16_I16_I16_ARITH : VOPProfile <[i16, i16, i16, untyped], 0, /*EnableClamp=*/1>;
2584
2585def VOP_I16_I16_I16_I16 : VOPProfile <[i16, i16, i16, i16, untyped]>;
2586def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>;
2587
2588def VOP_I32_I16_I16_I32 : VOPProfile <[i32, i16, i16, i32, untyped]>;
2589def VOP_I32_I16 : VOPProfile <[i32, i16, untyped, untyped]>;
2590
2591def VOP_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, untyped]>;
2592def VOP_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, untyped]>;
2593def VOP_B32_F16_F16 : VOPProfile <[i32, f16, f16, untyped]>;
2594
2595def VOP_V2F16_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, v2f16]>;
2596def VOP_V2I16_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, v2i16]>;
2597def VOP_V2I16_F32_F32 : VOPProfile <[v2i16, f32, f32, untyped]>;
2598def VOP_V2I16_I32_I32 : VOPProfile <[v2i16, i32, i32, untyped]>;
2599
2600def VOP_F16_V2F16_V2F16_F16 : VOPProfile <[f16, v2f16, v2f16, f16]>;
2601def VOP_I16_V2I16_V2I16_I16 : VOPProfile <[i16, v2i16, v2i16, i16]>;
2602def VOP_F32_V2I16_V2I16_F32 : VOPProfile <[f32, v2i16, v2i16, f32]>;
2603
2604def VOP_F32_V2F16_V2F16_V2F16 : VOPProfile <[f32, v2f16, v2f16, v2f16]>;
2605
2606def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
2607
2608def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
2609def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
2610def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
2611def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
2612def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
2613def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
2614def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
2615def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
2616def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
2617def VOP_F16_F32 : VOPProfile <[f16, f32, untyped, untyped]>;
2618def VOP_F32_F16 : VOPProfile <[f32, f16, untyped, untyped]>;
2619def VOP_I64_I64 : VOPProfile <[i64, i64, untyped, untyped]>;
2620
2621def VOP_F32_F32_F16 : VOPProfile <[f32, f32, f16, untyped]>;
2622def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
2623def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
2624def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
2625def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
2626def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
2627def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
2628def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
2629def VOP_I32_I32_I32_ARITH : VOPProfile <[i32, i32, i32, untyped], 0, /*EnableClamp=*/1>;
2630def VOP_V2F16_F32_F32 : VOPProfile <[v2f16, f32, f32, untyped]>;
2631def VOP_F32_F16_F16_F16 : VOPProfile <[f32, f16, f16, f16]>;
2632
2633def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
2634def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
2635def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
2636
2637def VOP_F16_F32_F16_F32 : VOPProfile <[f16, f32, f16, f32]>;
2638def VOP_F32_F32_F16_F16 : VOPProfile <[f32, f32, f16, f16]>;
2639def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
2640def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
2641def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
2642def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
2643def VOP_I32_F32_I32_I32 : VOPProfile <[i32, f32, i32, i32]>;
2644def VOP_I64_I64_I32_I64 : VOPProfile <[i64, i64, i32, i64]>;
2645def VOP_V4I32_I64_I32_V4I32 : VOPProfile <[v4i32, i64, i32, v4i32]>;
2646
2647def VOP_F32_V2F16_V2F16_F32 : VOPProfile <[f32, v2f16, v2f16, f32]>;
2648def VOP_I32_V2I16_V2I16_I32 : VOPProfile <[i32, v2i16, v2i16, i32]>;
2649
2650def VOP_V4F32_F32_F32_V4F32       : VOPProfile <[v4f32,  f32,   f32,   v4f32]>;
2651def VOP_V16F32_F32_F32_V16F32     : VOPProfile <[v16f32, f32,   f32,   v16f32]>;
2652def VOP_V32F32_F32_F32_V32F32     : VOPProfile <[v32f32, f32,   f32,   v32f32]>;
2653def VOP_V4F32_V4F16_V4F16_V4F32   : VOPProfile <[v4f32,  v4f16, v4f16, v4f32]>;
2654def VOP_V16F32_V4F16_V4F16_V16F32 : VOPProfile <[v16f32, v4f16, v4f16, v16f32]>;
2655def VOP_V32F32_V4F16_V4F16_V32F32 : VOPProfile <[v32f32, v4f16, v4f16, v32f32]>;
2656def VOP_V4F32_V2I16_V2I16_V4F32   : VOPProfile <[v4f32,  v2i16, v2i16, v4f32]>;
2657def VOP_V16F32_V2I16_V2I16_V16F32 : VOPProfile <[v16f32, v2i16, v2i16, v16f32]>;
2658def VOP_V32F32_V2I16_V2I16_V32F32 : VOPProfile <[v32f32, v2i16, v2i16, v32f32]>;
2659def VOP_V4I32_I32_I32_V4I32       : VOPProfile <[v4i32,  i32,   i32,   v4i32]>;
2660def VOP_V16I32_I32_I32_V16I32     : VOPProfile <[v16i32, i32,   i32,   v16i32]>;
2661def VOP_V32I32_I32_I32_V32I32     : VOPProfile <[v32i32, i32,   i32,   v32i32]>;
2662
2663def VOP_V4F64_F64_F64_V4F64 : VOPProfile <[v4f64, f64, f64, v4f64]>;
2664def VOP_V1F64_F64_F64_V1F64 : VOPProfile <[v1f64, f64, f64, v1f64]>;
2665
2666def VOP_V2F32_V2F32_V2F32_V2F32   : VOPProfile <[v2f32,  v2f32, v2f32, v2f32]>;
2667def VOP_V2F32_V2F32_V2F32         : VOPProfile <[v2f32,  v2f32, v2f32, untyped]>;
2668def VOP_V2I32_V2I32_V2I32         : VOPProfile <[v2i32,  v2i32, v2i32, untyped]>;
2669def VOP_V4F32_V4I16_V4I16_V4F32   : VOPProfile <[v4f32,  v4i16, v4i16, v4f32]>;
2670def VOP_V16F32_V4I16_V4I16_V16F32 : VOPProfile <[v16f32, v4i16, v4i16, v16f32]>;
2671def VOP_V32F32_V4I16_V4I16_V32F32 : VOPProfile <[v32f32, v4i16, v4i16, v32f32]>;
2672
2673def VOP_V4I32_I64_I64_V4I32       : VOPProfile <[v4i32,  i64,   i64,   v4i32]>;
2674def VOP_V16I32_I64_I64_V16I32     : VOPProfile <[v16i32, i64,   i64,   v16i32]>;
2675def VOP_V4F32_V2F32_V2F32_V4F32   : VOPProfile <[v4f32,  v2f32, v2f32, v4f32]>;
2676def VOP_V16F32_V2F32_V2F32_V16F32 : VOPProfile <[v16f32, v2f32, v2f32, v16f32]>;
2677
2678def VOP_V4F32_V4F16_V8F16_I32     : VOPProfile <[v4f32,  v4f16, v8f16, i32]>;
2679def VOP_V16F32_V4F16_V8F16_I32    : VOPProfile <[v16f32, v4f16, v8f16, i32]>;
2680def VOP_V4F32_V4I16_V8I16_I32     : VOPProfile <[v4f32,  v4i16, v8i16, i32]>;
2681def VOP_V16F32_V4I16_V8I16_I32    : VOPProfile <[v16f32, v4i16, v8i16, i32]>;
2682def VOP_V4I32_V2I32_V4I32_I32     : VOPProfile <[v4i32,  v2i32, v4i32, i32]>;
2683def VOP_V16I32_V2I32_V4I32_I32    : VOPProfile <[v16i32, v2i32, v4i32, i32]>;
2684
2685class Commutable_REV <string revOp, bit isOrig> {
2686  string RevOp = revOp;
2687  bit IsOrig = isOrig;
2688}
2689
2690class AtomicNoRet <string noRetOp, bit isRet> {
2691  string NoRetOp = noRetOp;
2692  bit IsRet = isRet;
2693}
2694
2695//===----------------------------------------------------------------------===//
2696// Interpolation opcodes
2697//===----------------------------------------------------------------------===//
2698
2699class VINTRPDstOperand <RegisterClass rc> : RegisterOperand <rc, "printVINTRPDst">;
2700
2701class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2702  VINTRPCommon <outs, ins, "", pattern>,
2703  SIMCInstr<opName, SIEncodingFamily.NONE> {
2704  let isPseudo = 1;
2705  let isCodeGenOnly = 1;
2706}
2707
2708// FIXME-GFX10: WIP.
2709class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
2710                      string asm, int encodingFamily> :
2711  VINTRPCommon <outs, ins, asm, []>,
2712  VINTRPe <op>,
2713  SIMCInstr<opName, encodingFamily> {
2714}
2715
2716class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
2717                      string asm> :
2718  VINTRPCommon <outs, ins, asm, []>,
2719  VINTRPe_vi <op>,
2720  SIMCInstr<opName, SIEncodingFamily.VI> {
2721  let AssemblerPredicate = VIAssemblerPredicate;
2722  let DecoderNamespace = "GFX8";
2723}
2724
2725// FIXME-GFX10: WIP.
2726multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
2727                     list<dag> pattern = []> {
2728  def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
2729
2730  let AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" in {
2731    def _si : VINTRP_Real_si <op, NAME, outs, ins, asm, SIEncodingFamily.SI>;
2732  } // End AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7"
2733
2734  def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
2735
2736  let AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10" in {
2737    def _gfx10 : VINTRP_Real_si<op, NAME, outs, ins, asm, SIEncodingFamily.GFX10>;
2738  } // End AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10"
2739}
2740
2741//===----------------------------------------------------------------------===//
2742// Vector instruction mappings
2743//===----------------------------------------------------------------------===//
2744
2745// Maps an opcode in e32 form to its e64 equivalent
2746def getVOPe64 : InstrMapping {
2747  let FilterClass = "VOP";
2748  let RowFields = ["OpName"];
2749  let ColFields = ["Size", "VOP3"];
2750  let KeyCol = ["4", "0"];
2751  let ValueCols = [["8", "1"]];
2752}
2753
2754// Maps an opcode in e64 form to its e32 equivalent
2755def getVOPe32 : InstrMapping {
2756  let FilterClass = "VOP";
2757  let RowFields = ["OpName"];
2758  let ColFields = ["Size", "VOP3"];
2759  let KeyCol = ["8", "1"];
2760  let ValueCols = [["4", "0"]];
2761}
2762
2763// Maps ordinary instructions to their SDWA counterparts
2764def getSDWAOp : InstrMapping {
2765  let FilterClass = "VOP";
2766  let RowFields = ["OpName"];
2767  let ColFields = ["AsmVariantName"];
2768  let KeyCol = ["Default"];
2769  let ValueCols = [["SDWA"]];
2770}
2771
2772// Maps SDWA instructions to their ordinary counterparts
2773def getBasicFromSDWAOp : InstrMapping {
2774  let FilterClass = "VOP";
2775  let RowFields = ["OpName"];
2776  let ColFields = ["AsmVariantName"];
2777  let KeyCol = ["SDWA"];
2778  let ValueCols = [["Default"]];
2779}
2780
2781// Maps ordinary instructions to their DPP counterparts
2782def getDPPOp32 : InstrMapping {
2783  let FilterClass = "VOP";
2784  let RowFields = ["OpName"];
2785  let ColFields = ["AsmVariantName"];
2786  let KeyCol = ["Default"];
2787  let ValueCols = [["DPP"]];
2788}
2789
2790// Maps an commuted opcode to its original version
2791def getCommuteOrig : InstrMapping {
2792  let FilterClass = "Commutable_REV";
2793  let RowFields = ["RevOp"];
2794  let ColFields = ["IsOrig"];
2795  let KeyCol = ["0"];
2796  let ValueCols = [["1"]];
2797}
2798
2799// Maps an original opcode to its commuted version
2800def getCommuteRev : InstrMapping {
2801  let FilterClass = "Commutable_REV";
2802  let RowFields = ["RevOp"];
2803  let ColFields = ["IsOrig"];
2804  let KeyCol = ["1"];
2805  let ValueCols = [["0"]];
2806}
2807
2808def getMCOpcodeGen : InstrMapping {
2809  let FilterClass = "SIMCInstr";
2810  let RowFields = ["PseudoInstr"];
2811  let ColFields = ["Subtarget"];
2812  let KeyCol = [!cast<string>(SIEncodingFamily.NONE)];
2813  // These columns must be kept in sync with the SIEncodingFamily enumeration.
2814  let ValueCols = [[!cast<string>(SIEncodingFamily.SI)],
2815                   [!cast<string>(SIEncodingFamily.VI)],
2816                   [!cast<string>(SIEncodingFamily.SDWA)],
2817                   [!cast<string>(SIEncodingFamily.SDWA9)],
2818                   // GFX80 encoding is added to work around a multiple matching
2819                   // issue for buffer instructions with unpacked d16 data. This
2820                   // does not actually change the encoding, and thus may be
2821                   // removed later.
2822                   [!cast<string>(SIEncodingFamily.GFX80)],
2823                   [!cast<string>(SIEncodingFamily.GFX9)],
2824                   [!cast<string>(SIEncodingFamily.GFX10)],
2825                   [!cast<string>(SIEncodingFamily.SDWA10)],
2826                   [!cast<string>(SIEncodingFamily.GFX90A)],
2827                   [!cast<string>(SIEncodingFamily.GFX940)],
2828                   [!cast<string>(SIEncodingFamily.GFX11)]];
2829}
2830
2831// Get equivalent SOPK instruction.
2832def getSOPKOp : InstrMapping {
2833  let FilterClass = "SOPKInstTable";
2834  let RowFields = ["BaseCmpOp"];
2835  let ColFields = ["IsSOPK"];
2836  let KeyCol = ["0"];
2837  let ValueCols = [["1"]];
2838}
2839
2840def getAddr64Inst : InstrMapping {
2841  let FilterClass = "MUBUFAddr64Table";
2842  let RowFields = ["OpName"];
2843  let ColFields = ["IsAddr64"];
2844  let KeyCol = ["0"];
2845  let ValueCols = [["1"]];
2846}
2847
2848def getIfAddr64Inst : InstrMapping {
2849  let FilterClass = "MUBUFAddr64Table";
2850  let RowFields = ["OpName"];
2851  let ColFields = ["IsAddr64"];
2852  let KeyCol = ["1"];
2853  let ValueCols = [["1"]];
2854}
2855
2856// Maps an atomic opcode to its returnless version.
2857def getAtomicNoRetOp : InstrMapping {
2858  let FilterClass = "AtomicNoRet";
2859  let RowFields = ["NoRetOp"];
2860  let ColFields = ["IsRet"];
2861  let KeyCol = ["1"];
2862  let ValueCols = [["0"]];
2863}
2864
2865// Maps a GLOBAL to its SADDR form.
2866def getGlobalSaddrOp : InstrMapping {
2867  let FilterClass = "GlobalSaddrTable";
2868  let RowFields = ["SaddrOp"];
2869  let ColFields = ["IsSaddr"];
2870  let KeyCol = ["0"];
2871  let ValueCols = [["1"]];
2872}
2873
2874// Maps a GLOBAL SADDR to its VADDR form.
2875def getGlobalVaddrOp : InstrMapping {
2876  let FilterClass = "GlobalSaddrTable";
2877  let RowFields = ["SaddrOp"];
2878  let ColFields = ["IsSaddr"];
2879  let KeyCol = ["1"];
2880  let ValueCols = [["0"]];
2881}
2882
2883// Maps a v_cmpx opcode with sdst to opcode without sdst.
2884def getVCMPXNoSDstOp : InstrMapping {
2885  let FilterClass = "VCMPXNoSDstTable";
2886  let RowFields = ["NoSDstOp"];
2887  let ColFields = ["HasSDst"];
2888  let KeyCol = ["1"];
2889  let ValueCols = [["0"]];
2890}
2891
2892// Maps a SOPP to a SOPP with S_NOP
2893def getSOPPWithRelaxation : InstrMapping {
2894  let FilterClass = "SOPPRelaxTable";
2895  let RowFields = ["KeyName"];
2896  let ColFields = ["IsRelaxed"];
2897  let KeyCol = ["0"];
2898  let ValueCols = [["1"]];
2899}
2900
2901// Maps flat scratch opcodes by addressing modes
2902def getFlatScratchInstSTfromSS : InstrMapping {
2903  let FilterClass = "FlatScratchInst";
2904  let RowFields = ["SVOp"];
2905  let ColFields = ["Mode"];
2906  let KeyCol = ["SS"];
2907  let ValueCols = [["ST"]];
2908}
2909
2910def getFlatScratchInstSSfromSV : InstrMapping {
2911  let FilterClass = "FlatScratchInst";
2912  let RowFields = ["SVOp"];
2913  let ColFields = ["Mode"];
2914  let KeyCol = ["SV"];
2915  let ValueCols = [["SS"]];
2916}
2917
2918def getFlatScratchInstSVfromSVS : InstrMapping {
2919  let FilterClass = "FlatScratchInst";
2920  let RowFields = ["SVOp"];
2921  let ColFields = ["Mode"];
2922  let KeyCol = ["SVS"];
2923  let ValueCols = [["SV"]];
2924}
2925
2926def getFlatScratchInstSVfromSS : InstrMapping {
2927  let FilterClass = "FlatScratchInst";
2928  let RowFields = ["SVOp"];
2929  let ColFields = ["Mode"];
2930  let KeyCol = ["SS"];
2931  let ValueCols = [["SV"]];
2932}
2933
2934def getMFMAEarlyClobberOp : InstrMapping {
2935  let FilterClass = "MFMATable";
2936  let RowFields = ["FMAOp"];
2937  let ColFields = ["IsMac"];
2938  let KeyCol = ["1"];
2939  let ValueCols = [["0"]];
2940}
2941
2942// Maps an v_cmp instruction to its v_cmpx equivalent.
2943def getVCMPXOpFromVCMP : InstrMapping {
2944  let FilterClass = "VCMPVCMPXTable";
2945  let RowFields = ["VCMPOp"];
2946  let ColFields = ["IsVCMPX"];
2947  let KeyCol = ["0"];
2948  let ValueCols = [["1"]];
2949}
2950
2951include "SIInstructions.td"
2952
2953include "DSInstructions.td"
2954include "MIMGInstructions.td"
2955