1//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9def isCI : Predicate<"Subtarget->getGeneration() "
10                      ">= SISubtarget::SEA_ISLANDS">;
11def isCIOnly : Predicate<"Subtarget->getGeneration() =="
12                         "SISubtarget::SEA_ISLANDS">,
13  AssemblerPredicate <"FeatureSeaIslands">;
14
15def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">;
16
17// Execpt for the NONE field, this must be kept in sync with the
18// SIEncodingFamily enum in AMDGPUInstrInfo.cpp
19def SIEncodingFamily {
20  int NONE = -1;
21  int SI = 0;
22  int VI = 1;
23}
24
25//===----------------------------------------------------------------------===//
26// SI DAG Nodes
27//===----------------------------------------------------------------------===//
28
29def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
30  SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
31                      [SDNPMayLoad, SDNPMemOperand]
32>;
33
34def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2,
35  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
36>;
37
38def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2,
39  [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
40>;
41
42def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
43  SDTypeProfile<0, 13,
44    [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
45     SDTCisVT<1, iAny>,   // vdata(VGPR)
46     SDTCisVT<2, i32>,    // num_channels(imm)
47     SDTCisVT<3, i32>,    // vaddr(VGPR)
48     SDTCisVT<4, i32>,    // soffset(SGPR)
49     SDTCisVT<5, i32>,    // inst_offset(imm)
50     SDTCisVT<6, i32>,    // dfmt(imm)
51     SDTCisVT<7, i32>,    // nfmt(imm)
52     SDTCisVT<8, i32>,    // offen(imm)
53     SDTCisVT<9, i32>,    // idxen(imm)
54     SDTCisVT<10, i32>,   // glc(imm)
55     SDTCisVT<11, i32>,   // slc(imm)
56     SDTCisVT<12, i32>    // tfe(imm)
57    ]>,
58  [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
59>;
60
61def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
62  SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
63                       SDTCisVT<3, i32>]>
64>;
65
66class SDSample<string opcode> : SDNode <opcode,
67  SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v8i32>,
68                       SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
69>;
70
71def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
72def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
73def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
74def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
75
76def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET",
77  SDTypeProfile<1, 2, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]>
78>;
79
80//===----------------------------------------------------------------------===//
81// PatFrags for global memory operations
82//===----------------------------------------------------------------------===//
83
84def atomic_inc_global : global_binary_atomic_op<SIatomic_inc>;
85def atomic_dec_global : global_binary_atomic_op<SIatomic_dec>;
86
87//===----------------------------------------------------------------------===//
88// SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1
89// to be glued to the memory instructions.
90//===----------------------------------------------------------------------===//
91
92def SIld_local : SDNode <"ISD::LOAD", SDTLoad,
93  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
94>;
95
96def si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{
97  return cast<LoadSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
98}]>;
99
100def si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
101  return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
102         cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
103}]>;
104
105def si_load_local_align8 : Aligned8Bytes <
106  (ops node:$ptr), (si_load_local node:$ptr)
107>;
108
109def si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
110  return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
111}]>;
112def si_az_extload_local : AZExtLoadBase <si_ld_local>;
113
114multiclass SIExtLoadLocal <PatFrag ld_node> {
115
116  def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
117                     [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}]
118  >;
119
120  def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
121                     [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}]
122  >;
123}
124
125defm si_sextload_local : SIExtLoadLocal <si_sextload_local>;
126defm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>;
127
128def SIst_local : SDNode <"ISD::STORE", SDTStore,
129  [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
130>;
131
132def si_st_local : PatFrag <
133  (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{
134  return cast<StoreSDNode>(N)->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS;
135}]>;
136
137def si_store_local : PatFrag <
138  (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
139  return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
140         !cast<StoreSDNode>(N)->isTruncatingStore();
141}]>;
142
143def si_store_local_align8 : Aligned8Bytes <
144  (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr)
145>;
146
147def si_truncstore_local : PatFrag <
148  (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
149  return cast<StoreSDNode>(N)->isTruncatingStore();
150}]>;
151
152def si_truncstore_local_i8 : PatFrag <
153  (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
154  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
155}]>;
156
157def si_truncstore_local_i16 : PatFrag <
158  (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
159  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
160}]>;
161
162def si_setcc_uniform : PatFrag <
163  (ops node:$lhs, node:$rhs, node:$cond),
164  (setcc node:$lhs, node:$rhs, node:$cond), [{
165  for (SDNode *Use : N->uses()) {
166    if (Use->isMachineOpcode() || Use->getOpcode() != ISD::CopyToReg)
167      return false;
168
169    unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
170    if (Reg != AMDGPU::SCC)
171      return false;
172  }
173  return true;
174}]>;
175
176def si_uniform_br : PatFrag <
177  (ops node:$cond, node:$bb), (brcond node:$cond, node:$bb), [{
178  return isUniformBr(N);
179}]>;
180
181def si_uniform_br_scc : PatFrag <
182  (ops node:$cond, node:$bb), (si_uniform_br node:$cond, node:$bb), [{
183  return isCBranchSCC(N);
184}]>;
185
186multiclass SIAtomicM0Glue2 <string op_name, bit is_amdgpu = 0> {
187
188  def _glue : SDNode <
189    !if(is_amdgpu, "AMDGPUISD", "ISD")#"::ATOMIC_"#op_name, SDTAtomic2,
190    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
191  >;
192
193  def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>;
194}
195
196defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
197defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
198defm si_atomic_inc : SIAtomicM0Glue2 <"INC", 1>;
199defm si_atomic_dec : SIAtomicM0Glue2 <"DEC", 1>;
200defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
201defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
202defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
203defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
204defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
205defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
206defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
207defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">;
208
209def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3,
210  [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
211>;
212
213defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>;
214
215def as_i1imm : SDNodeXForm<imm, [{
216  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
217}]>;
218
219def as_i8imm : SDNodeXForm<imm, [{
220  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
221}]>;
222
223def as_i16imm : SDNodeXForm<imm, [{
224  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
225}]>;
226
227def as_i32imm: SDNodeXForm<imm, [{
228  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
229}]>;
230
231def as_i64imm: SDNodeXForm<imm, [{
232  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
233}]>;
234
235// Copied from the AArch64 backend:
236def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
237return CurDAG->getTargetConstant(
238  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
239}]>;
240
241def frameindex_to_targetframeindex : SDNodeXForm<frameindex, [{
242  auto FI = cast<FrameIndexSDNode>(N);
243  return CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32);
244}]>;
245
246// Copied from the AArch64 backend:
247def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
248return CurDAG->getTargetConstant(
249  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
250}]>;
251
252def SIMM16bit : PatLeaf <(imm),
253  [{return isInt<16>(N->getSExtValue());}]
254>;
255
256def IMM20bit : PatLeaf <(imm),
257  [{return isUInt<20>(N->getZExtValue());}]
258>;
259
260class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
261  return isInlineImmediate(N);
262}]>;
263
264class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
265  return isInlineImmediate(N);
266}]>;
267
268class SGPRImm <dag frag> : PatLeaf<frag, [{
269  if (Subtarget->getGeneration() < SISubtarget::SOUTHERN_ISLANDS) {
270    return false;
271  }
272  const SIRegisterInfo *SIRI =
273      static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo());
274  for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
275                                                U != E; ++U) {
276    const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo());
277    if (RC && SIRI->isSGPRClass(RC))
278      return true;
279  }
280  return false;
281}]>;
282
283//===----------------------------------------------------------------------===//
284// Custom Operands
285//===----------------------------------------------------------------------===//
286
287def SoppBrTarget : AsmOperandClass {
288  let Name = "SoppBrTarget";
289  let ParserMethod = "parseSOppBrTarget";
290}
291
292def sopp_brtarget : Operand<OtherVT> {
293  let EncoderMethod = "getSOPPBrEncoding";
294  let DecoderMethod = "decodeSoppBrTarget";
295  let OperandType = "OPERAND_PCREL";
296  let ParserMatchClass = SoppBrTarget;
297}
298
299def si_ga : Operand<iPTR>;
300
301def InterpSlot : Operand<i32> {
302  let PrintMethod = "printInterpSlot";
303}
304
305def SendMsgMatchClass : AsmOperandClass {
306  let Name = "SendMsg";
307  let PredicateMethod = "isSendMsg";
308  let ParserMethod = "parseSendMsgOp";
309  let RenderMethod = "addImmOperands";
310}
311
312def SendMsgImm : Operand<i32> {
313  let PrintMethod = "printSendMsg";
314  let ParserMatchClass = SendMsgMatchClass;
315}
316
317def SWaitMatchClass : AsmOperandClass {
318  let Name = "SWaitCnt";
319  let RenderMethod = "addImmOperands";
320  let ParserMethod = "parseSWaitCntOps";
321}
322
323def WAIT_FLAG : Operand <i32> {
324  let ParserMatchClass = SWaitMatchClass;
325  let PrintMethod = "printWaitFlag";
326}
327
328include "SIInstrFormats.td"
329include "VIInstrFormats.td"
330
331class NamedMatchClass<string CName, bit Optional = 1> : AsmOperandClass {
332  let Name = "Imm"#CName;
333  let PredicateMethod = "is"#CName;
334  let ParserMethod = !if(Optional, "parseOptionalOperand", "parse"#CName);
335  let RenderMethod = "addImmOperands";
336  let IsOptional = Optional;
337  let DefaultMethod = !if(Optional, "default"#CName, ?);
338}
339
340class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> {
341  let PrintMethod = "print"#Name;
342  let ParserMatchClass = MatchClass;
343}
344
345class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> {
346  let PrintMethod = "print"#Name;
347  let ParserMatchClass = MatchClass;
348}
349
350class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> {
351  let PrintMethod = "print"#Name;
352  let ParserMatchClass = MatchClass;
353}
354
355class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> {
356  let PrintMethod = "print"#Name;
357  let ParserMatchClass = MatchClass;
358}
359
360let OperandType = "OPERAND_IMMEDIATE" in {
361
362def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>;
363def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>;
364def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>;
365
366def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>;
367def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>;
368def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>;
369
370def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>;
371
372def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>;
373def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>;
374
375def glc : NamedOperandBit<"GLC", NamedMatchClass<"GLC">>;
376def slc : NamedOperandBit<"SLC", NamedMatchClass<"SLC">>;
377def tfe : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>;
378def unorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>;
379def da : NamedOperandBit<"DA", NamedMatchClass<"DA">>;
380def r128 : NamedOperandBit<"R128", NamedMatchClass<"R128">>;
381def lwe : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>;
382
383def dmask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>;
384
385def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>;
386def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>;
387def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>;
388def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>;
389
390def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>;
391def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>;
392def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>;
393def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>;
394
395def hwreg : NamedOperandU16<"Hwreg", NamedMatchClass<"Hwreg", 0>>;
396
397} // End OperandType = "OPERAND_IMMEDIATE"
398
399
400// 32-bit VALU immediate operand that uses the constant bus.
401def KImmFP32MatchClass : AsmOperandClass {
402  let Name = "KImmFP32";
403  let PredicateMethod = "isKImmFP32";
404  let ParserMethod = "parseImm";
405  let RenderMethod = "addKImmFP32Operands";
406}
407
408def f32kimm : Operand<i32> {
409  let OperandNamespace = "AMDGPU";
410  let OperandType = "OPERAND_KIMM32";
411  let PrintMethod = "printU32ImmOperand";
412  let ParserMatchClass = KImmFP32MatchClass;
413}
414
415def VOPDstS64 : VOPDstOperand <SReg_64>;
416
417class FPInputModsMatchClass <int opSize> : AsmOperandClass {
418  let Name = "RegOrImmWithFP"#opSize#"InputMods";
419  let ParserMethod = "parseRegOrImmWithFPInputMods";
420  let PredicateMethod = "isRegOrImmWithFP"#opSize#"InputMods";
421}
422def FP32InputModsMatchClass : FPInputModsMatchClass<32>;
423def FP64InputModsMatchClass : FPInputModsMatchClass<64>;
424
425class InputMods <AsmOperandClass matchClass> : Operand <i32> {
426  let OperandNamespace = "AMDGPU";
427  let OperandType = "OPERAND_INPUT_MODS";
428  let ParserMatchClass = matchClass;
429}
430
431class FPInputMods <FPInputModsMatchClass matchClass> : InputMods <matchClass> {
432  let PrintMethod = "printOperandAndFPInputMods";
433}
434def FP32InputMods : FPInputMods<FP32InputModsMatchClass>;
435def FP64InputMods : FPInputMods<FP64InputModsMatchClass>;
436
437class IntInputModsMatchClass <int opSize> : AsmOperandClass {
438  let Name = "RegOrImmWithInt"#opSize#"InputMods";
439  let ParserMethod = "parseRegOrImmWithIntInputMods";
440  let PredicateMethod = "isRegOrImmWithInt"#opSize#"InputMods";
441}
442def Int32InputModsMatchClass : IntInputModsMatchClass<32>;
443def Int64InputModsMatchClass : IntInputModsMatchClass<64>;
444
445class IntInputMods <IntInputModsMatchClass matchClass> : InputMods <matchClass> {
446  let PrintMethod = "printOperandAndIntInputMods";
447}
448def Int32InputMods : IntInputMods<Int32InputModsMatchClass>;
449def Int64InputMods : IntInputMods<Int64InputModsMatchClass>;
450
451//===----------------------------------------------------------------------===//
452// Complex patterns
453//===----------------------------------------------------------------------===//
454
455def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
456def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
457
458def MOVRELOffset : ComplexPattern<i32, 2, "SelectMOVRELOffset">;
459
460def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
461def VOP3NoMods0 : ComplexPattern<untyped, 4, "SelectVOP3NoMods0">;
462def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
463def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
464def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
465def VOP3NoMods : ComplexPattern<untyped, 2, "SelectVOP3NoMods">;
466
467//===----------------------------------------------------------------------===//
468// SI assembler operands
469//===----------------------------------------------------------------------===//
470
471def SIOperand {
472  int ZERO = 0x80;
473  int VCC = 0x6A;
474  int FLAT_SCR = 0x68;
475}
476
477def SRCMODS {
478  int NONE = 0;
479  int NEG = 1;
480}
481
482def DSTCLAMP {
483  int NONE = 0;
484}
485
486def DSTOMOD {
487  int NONE = 0;
488}
489
490//===----------------------------------------------------------------------===//
491//
492// SI Instruction multiclass helpers.
493//
494// Instructions with _32 take 32-bit operands.
495// Instructions with _64 take 64-bit operands.
496//
497// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
498// encoding is the standard encoding, but instruction that make use of
499// any of the instruction modifiers must use the 64-bit encoding.
500//
501// Instructions with _e32 use the 32-bit encoding.
502// Instructions with _e64 use the 64-bit encoding.
503//
504//===----------------------------------------------------------------------===//
505
506class SIMCInstr <string pseudo, int subtarget> {
507  string PseudoInstr = pseudo;
508  int Subtarget = subtarget;
509}
510
511//===----------------------------------------------------------------------===//
512// EXP classes
513//===----------------------------------------------------------------------===//
514
515class EXPCommon : InstSI<
516  (outs),
517  (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
518       VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3),
519  "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
520  [] > {
521
522  let EXP_CNT = 1;
523  let Uses = [EXEC];
524  let SchedRW = [WriteExport];
525}
526
527multiclass EXP_m {
528
529  let isPseudo = 1, isCodeGenOnly = 1 in {
530    def "" : EXPCommon, SIMCInstr <"exp", SIEncodingFamily.NONE> ;
531  }
532
533  def _si : EXPCommon, SIMCInstr <"exp", SIEncodingFamily.SI>, EXPe {
534    let DecoderNamespace="SICI";
535    let DisableDecoder = DisableSIDecoder;
536  }
537
538  def _vi : EXPCommon, SIMCInstr <"exp", SIEncodingFamily.VI>, EXPe_vi {
539    let DecoderNamespace="VI";
540    let DisableDecoder = DisableVIDecoder;
541  }
542}
543
544//===----------------------------------------------------------------------===//
545// Vector ALU classes
546//===----------------------------------------------------------------------===//
547
548class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
549  int ret =
550    !if (!eq(Src0.Value, untyped.Value),      0,
551      !if (!eq(Src1.Value, untyped.Value),    1,   // VOP1
552         !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
553                                              3))); // VOP3
554}
555
556// Returns the register class to use for the destination of VOP[123C]
557// instructions for the given VT.
558class getVALUDstForVT<ValueType VT> {
559  RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
560                          !if(!eq(VT.Size, 128), VOPDstOperand<VReg_128>,
561                            !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
562                              !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>,
563                              VOPDstOperand<SReg_64>)))); // else VT == i1
564}
565
566// Returns the register class to use for source 0 of VOP[12C]
567// instructions for the given VT.
568class getVOPSrc0ForVT<ValueType VT> {
569  bit isFP = !if(!eq(VT.Value, f16.Value), 1,
570             !if(!eq(VT.Value, f32.Value), 1,
571             !if(!eq(VT.Value, f64.Value), 1,
572             0)));
573  RegisterOperand ret = !if(isFP,
574                            !if(!eq(VT.Size, 64), VSrc_f64, VSrc_f32),
575                            !if(!eq(VT.Size, 64), VSrc_b64, VSrc_b32));
576}
577
578// Returns the vreg register class to use for source operand given VT
579class getVregSrcForVT<ValueType VT> {
580  RegisterClass ret = !if(!eq(VT.Size, 128), VReg_128,
581                        !if(!eq(VT.Size, 64), VReg_64, VGPR_32));
582}
583
584
585// Returns the register class to use for sources of VOP3 instructions for the
586// given VT.
587class getVOP3SrcForVT<ValueType VT> {
588  bit isFP = !if(!eq(VT.Value, f16.Value), 1,
589             !if(!eq(VT.Value, f32.Value), 1,
590             !if(!eq(VT.Value, f64.Value), 1,
591             0)));
592  RegisterOperand ret =
593  !if(!eq(VT.Size, 128),
594      VSrc_128,
595    !if(!eq(VT.Size, 64),
596        !if(isFP,
597            VCSrc_f64,
598            VCSrc_b64),
599        !if(!eq(VT.Value, i1.Value),
600            SCSrc_b64,
601            !if(isFP,
602                VCSrc_f32,
603                VCSrc_b32)
604         )
605	   )
606     );
607}
608
609// Returns 1 if the source arguments have modifiers, 0 if they do not.
610// XXX - do f16 instructions?
611class isFloatType<ValueType SrcVT> {
612  bit ret =
613    !if(!eq(SrcVT.Value, f16.Value), 1,
614    !if(!eq(SrcVT.Value, f32.Value), 1,
615    !if(!eq(SrcVT.Value, f64.Value), 1,
616    0)));
617}
618
619class isIntType<ValueType SrcVT> {
620  bit ret =
621    !if(!eq(SrcVT.Value, i16.Value), 1,
622    !if(!eq(SrcVT.Value, i32.Value), 1,
623    !if(!eq(SrcVT.Value, i64.Value), 1,
624    0)));
625}
626
627
628// Return type of input modifiers operand for specified input operand
629class getSrcMod <ValueType VT> {
630  bit isFP = !if(!eq(VT.Value, f16.Value), 1,
631               !if(!eq(VT.Value, f32.Value), 1,
632               !if(!eq(VT.Value, f64.Value), 1,
633               0)));
634  Operand ret =  !if(!eq(VT.Size, 64),
635                     !if(isFP, FP64InputMods, Int64InputMods),
636                     !if(isFP, FP32InputMods, Int32InputMods));
637}
638
639// Returns the input arguments for VOP[12C] instructions for the given SrcVT.
640class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
641  dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
642            !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
643                                    (ins)));
644}
645
646// Returns the input arguments for VOP3 instructions for the given SrcVT.
647class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
648                RegisterOperand Src2RC, int NumSrcArgs,
649                bit HasModifiers, Operand Src0Mod, Operand Src1Mod,
650                Operand Src2Mod> {
651
652  dag ret =
653    !if (!eq(NumSrcArgs, 0),
654      // VOP1 without input operands (V_NOP, V_CLREXCP)
655      (ins),
656      /* else */
657    !if (!eq(NumSrcArgs, 1),
658      !if (!eq(HasModifiers, 1),
659        // VOP1 with modifiers
660        (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
661             clampmod:$clamp, omod:$omod)
662      /* else */,
663        // VOP1 without modifiers
664        (ins Src0RC:$src0)
665      /* endif */ ),
666    !if (!eq(NumSrcArgs, 2),
667      !if (!eq(HasModifiers, 1),
668        // VOP 2 with modifiers
669        (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
670             Src1Mod:$src1_modifiers, Src1RC:$src1,
671             clampmod:$clamp, omod:$omod)
672      /* else */,
673        // VOP2 without modifiers
674        (ins Src0RC:$src0, Src1RC:$src1)
675      /* endif */ )
676    /* NumSrcArgs == 3 */,
677      !if (!eq(HasModifiers, 1),
678        // VOP3 with modifiers
679        (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
680             Src1Mod:$src1_modifiers, Src1RC:$src1,
681             Src2Mod:$src2_modifiers, Src2RC:$src2,
682             clampmod:$clamp, omod:$omod)
683      /* else */,
684        // VOP3 without modifiers
685        (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
686      /* endif */ ))));
687}
688
689class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
690                 bit HasModifiers, Operand Src0Mod, Operand Src1Mod> {
691
692  dag ret = !if (!eq(NumSrcArgs, 0),
693                // VOP1 without input operands (V_NOP)
694                (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
695                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl),
696            !if (!eq(NumSrcArgs, 1),
697              !if (!eq(HasModifiers, 1),
698                // VOP1_DPP with modifiers
699                (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
700                     dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
701                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
702              /* else */,
703                // VOP1_DPP without modifiers
704                (ins Src0RC:$src0, dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
705                bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
706              /* endif */)
707              /* NumSrcArgs == 2 */,
708              !if (!eq(HasModifiers, 1),
709                // VOP2_DPP with modifiers
710                (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
711                     Src1Mod:$src1_modifiers, Src1RC:$src1,
712                     dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
713                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
714              /* else */,
715                // VOP2_DPP without modifiers
716                (ins Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl,
717                row_mask:$row_mask, bank_mask:$bank_mask,
718                bound_ctrl:$bound_ctrl)
719             /* endif */)));
720}
721
722class getInsSDWA <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
723                  bit HasFloatModifiers, Operand Src0Mod, Operand Src1Mod,
724                  ValueType DstVT> {
725
726  dag ret = !if(!eq(NumSrcArgs, 0),
727               // VOP1 without input operands (V_NOP)
728               (ins),
729            !if(!eq(NumSrcArgs, 1),
730               (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
731                    clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
732                    src0_sel:$src0_sel),
733            !if(!eq(NumSrcArgs, 2),
734               !if(!eq(DstVT.Size, 1),
735                  // VOPC_SDWA with float modifiers
736                  (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
737                       Src1Mod:$src1_modifiers, Src1RC:$src1,
738                       clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel),
739                  // VOP2_SDWA or VOPC_SDWA with float modifiers
740                  (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
741                       Src1Mod:$src1_modifiers, Src1RC:$src1,
742                       clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
743                       src0_sel:$src0_sel, src1_sel:$src1_sel)),
744            (ins)/* endif */)));
745}
746
747// Outs for DPP and SDWA
748class getOutsExt <bit HasDst, ValueType DstVT, RegisterOperand DstRCDPP> {
749  dag ret = !if(HasDst,
750                !if(!eq(DstVT.Size, 1),
751                    (outs), // no dst for VOPC, we use "vcc"-token as dst in SDWA VOPC instructions
752                    (outs DstRCDPP:$vdst)),
753                (outs)); // V_NOP
754}
755
756// Returns the assembly string for the inputs and outputs of a VOP[12C]
757// instruction.  This does not add the _e32 suffix, so it can be reused
758// by getAsm64.
759class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
760  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
761  string src0 = ", $src0";
762  string src1 = ", $src1";
763  string src2 = ", $src2";
764  string ret = !if(HasDst, dst, "") #
765               !if(!eq(NumSrcArgs, 1), src0, "") #
766               !if(!eq(NumSrcArgs, 2), src0#src1, "") #
767               !if(!eq(NumSrcArgs, 3), src0#src1#src2, "");
768}
769
770// Returns the assembly string for the inputs and outputs of a VOP3
771// instruction.
772class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
773  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
774  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
775  string src1 = !if(!eq(NumSrcArgs, 1), "",
776                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
777                                           " $src1_modifiers,"));
778  string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
779  string ret =
780  !if(!eq(HasModifiers, 0),
781      getAsm32<HasDst, NumSrcArgs, DstVT>.ret,
782      dst#", "#src0#src1#src2#"$clamp"#"$omod");
783}
784
785class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
786  string dst = !if(HasDst,
787                   !if(!eq(DstVT.Size, 1),
788                       "$sdst",
789                       "$vdst"),
790                    ""); // use $sdst for VOPC
791  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
792  string src1 = !if(!eq(NumSrcArgs, 1), "",
793                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
794                                           " $src1_modifiers,"));
795  string args = !if(!eq(HasModifiers, 0),
796                     getAsm32<0, NumSrcArgs, DstVT>.ret,
797                     ", "#src0#src1);
798  string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
799}
800
801class getAsmSDWA <bit HasDst, int NumSrcArgs, bit HasFloatModifiers,
802                  ValueType DstVT = i32> {
803  string dst = !if(HasDst,
804                   !if(!eq(DstVT.Size, 1),
805                       " vcc", // use vcc token as dst for VOPC instructioins
806                       "$vdst"),
807                    "");
808  string src0 = "$src0_modifiers";
809  string src1 = "$src1_modifiers";
810  string args = !if(!eq(NumSrcArgs, 0),
811                    "",
812                    !if(!eq(NumSrcArgs, 1),
813                        ", "#src0#"$clamp",
814                        ", "#src0#", "#src1#"$clamp"
815                     )
816                );
817  string sdwa = !if(!eq(NumSrcArgs, 0),
818                    "",
819                    !if(!eq(NumSrcArgs, 1),
820                        " $dst_sel $dst_unused $src0_sel",
821                        !if(!eq(DstVT.Size, 1),
822                            " $src0_sel $src1_sel", // No dst_sel and dst_unused for VOPC
823                            " $dst_sel $dst_unused $src0_sel $src1_sel"
824                        )
825                    )
826                );
827  string ret = dst#args#sdwa;
828}
829
830// Function that checks if instruction supports DPP and SDWA
831class getHasExt <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
832                 ValueType Src1VT = i32> {
833  bit ret = !if(!eq(NumSrcArgs, 3),
834                0, // NumSrcArgs == 3 - No DPP or SDWA for VOP3
835                !if(!eq(DstVT.Size, 64),
836                    0, // 64-bit dst - No DPP or SDWA for 64-bit operands
837                    !if(!eq(Src0VT.Size, 64),
838                        0, // 64-bit src0
839                        !if(!eq(Src0VT.Size, 64),
840                            0, // 64-bit src2
841                            1
842                        )
843                    )
844                )
845            );
846}
847
848class BitOr<bit a, bit b> {
849  bit ret = !if(a, 1, !if(b, 1, 0));
850}
851
852class BitAnd<bit a, bit b> {
853  bit ret = !if(a, !if(b, 1, 0), 0);
854}
855
856class VOPProfile <list<ValueType> _ArgVT> {
857
858  field list<ValueType> ArgVT = _ArgVT;
859
860  field ValueType DstVT = ArgVT[0];
861  field ValueType Src0VT = ArgVT[1];
862  field ValueType Src1VT = ArgVT[2];
863  field ValueType Src2VT = ArgVT[3];
864  field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
865  field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret;
866  field RegisterOperand DstRCSDWA = getVALUDstForVT<DstVT>.ret;
867  field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
868  field RegisterClass Src1RC32 = getVregSrcForVT<Src1VT>.ret;
869  field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
870  field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
871  field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
872  field RegisterClass Src0DPP = getVregSrcForVT<Src0VT>.ret;
873  field RegisterClass Src1DPP = getVregSrcForVT<Src1VT>.ret;
874  field RegisterClass Src0SDWA = getVregSrcForVT<Src0VT>.ret;
875  field RegisterClass Src1SDWA = getVregSrcForVT<Src1VT>.ret;
876  field Operand Src0Mod = getSrcMod<Src0VT>.ret;
877  field Operand Src1Mod = getSrcMod<Src1VT>.ret;
878  field Operand Src2Mod = getSrcMod<Src2VT>.ret;
879
880  field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1);
881  field bit HasDst32 = HasDst;
882  field bit EmitDst = HasDst; // force dst encoding, see v_movreld_b32 special case
883  field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
884  field bit HasSrc0 = !if(!eq(Src0VT.Value, untyped.Value), 0, 1);
885  field bit HasSrc1 = !if(!eq(Src1VT.Value, untyped.Value), 0, 1);
886  field bit HasSrc2 = !if(!eq(Src2VT.Value, untyped.Value), 0, 1);
887
888  // TODO: Modifiers logic is somewhat adhoc here, to be refined later
889  field bit HasModifiers = isFloatType<Src0VT>.ret;
890
891  field bit HasSrc0FloatMods = isFloatType<Src0VT>.ret;
892  field bit HasSrc1FloatMods = isFloatType<Src1VT>.ret;
893  field bit HasSrc2FloatMods = isFloatType<Src2VT>.ret;
894
895  field bit HasSrc0IntMods = isIntType<Src0VT>.ret;
896  field bit HasSrc1IntMods = isIntType<Src1VT>.ret;
897  field bit HasSrc2IntMods = isIntType<Src2VT>.ret;
898
899  field bit HasSrc0Mods = HasModifiers;
900  field bit HasSrc1Mods = !if(HasModifiers, BitOr<HasSrc1FloatMods, HasSrc1IntMods>.ret, 0);
901  field bit HasSrc2Mods = !if(HasModifiers, BitOr<HasSrc2FloatMods, HasSrc2IntMods>.ret, 0);
902
903  field bit HasOMod = HasModifiers;
904  field bit HasClamp = HasModifiers;
905  field bit HasSDWAClamp = HasSrc0;
906
907  field bit HasExt = getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
908
909  field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs));
910
911  // VOP3b instructions are a special case with a second explicit
912  // output. This is manually overridden for them.
913  field dag Outs32 = Outs;
914  field dag Outs64 = Outs;
915  field dag OutsDPP = getOutsExt<HasDst, DstVT, DstRCDPP>.ret;
916  field dag OutsSDWA = getOutsExt<HasDst, DstVT, DstRCDPP>.ret;
917
918  field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
919  field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
920                             HasModifiers, Src0Mod, Src1Mod, Src2Mod>.ret;
921  field dag InsDPP = getInsDPP<Src0DPP, Src1DPP, NumSrcArgs,
922                               HasModifiers, Src0Mod, Src1Mod>.ret;
923  field dag InsSDWA = getInsSDWA<Src0SDWA, Src1SDWA, NumSrcArgs,
924                                 HasModifiers, Src0Mod, Src1Mod, DstVT>.ret;
925
926  field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret;
927  field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
928  field string AsmDPP = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
929  field string AsmSDWA = getAsmSDWA<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
930}
931
932class VOP_NO_EXT <VOPProfile p> : VOPProfile <p.ArgVT> {
933  let HasExt = 0;
934}
935
936// FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order
937//        for the instruction patterns to work.
938def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
939def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>;
940def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>;
941
942def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
943def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>;
944def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
945
946def VOP_I16_I16_I16_I16 : VOPProfile <[i32, i32, i32, i32, untyped]>;
947def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>;
948
949def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
950
951def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
952def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
953def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
954def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
955def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
956def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
957def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
958def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
959def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
960
961def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
962def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
963def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
964def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
965def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
966def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
967def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
968
969def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
970def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
971def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
972
973def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
974def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
975def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
976def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
977def VOP_I32_F32_I32_I32 : VOPProfile <[i32, f32, i32, i32]>;
978def VOP_I64_I64_I32_I64 : VOPProfile <[i64, i64, i32, i64]>;
979def VOP_V4I32_I64_I32_V4I32 : VOPProfile <[v4i32, i64, i32, v4i32]>;
980
981class Commutable_REV <string revOp, bit isOrig> {
982  string RevOp = revOp;
983  bit IsOrig = isOrig;
984}
985
986class AtomicNoRet <string noRetOp, bit isRet> {
987  string NoRetOp = noRetOp;
988  bit IsRet = isRet;
989}
990
991//===----------------------------------------------------------------------===//
992// Interpolation opcodes
993//===----------------------------------------------------------------------===//
994
995class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
996  VINTRPCommon <outs, ins, "", pattern>,
997  SIMCInstr<opName, SIEncodingFamily.NONE> {
998  let isPseudo = 1;
999  let isCodeGenOnly = 1;
1000}
1001
1002class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
1003                      string asm> :
1004  VINTRPCommon <outs, ins, asm, []>,
1005  VINTRPe <op>,
1006  SIMCInstr<opName, SIEncodingFamily.SI> {
1007  let AssemblerPredicate = SIAssemblerPredicate;
1008  let DecoderNamespace = "SICI";
1009  let DisableDecoder = DisableSIDecoder;
1010}
1011
1012class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
1013                      string asm> :
1014  VINTRPCommon <outs, ins, asm, []>,
1015  VINTRPe_vi <op>,
1016  SIMCInstr<opName, SIEncodingFamily.VI> {
1017  let AssemblerPredicate = VIAssemblerPredicate;
1018  let DecoderNamespace = "VI";
1019  let DisableDecoder = DisableVIDecoder;
1020}
1021
1022multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
1023                     list<dag> pattern = []> {
1024  def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
1025
1026  def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
1027
1028  def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
1029}
1030
1031//===----------------------------------------------------------------------===//
1032// Vector instruction mappings
1033//===----------------------------------------------------------------------===//
1034
1035// Maps an opcode in e32 form to its e64 equivalent
1036def getVOPe64 : InstrMapping {
1037  let FilterClass = "VOP";
1038  let RowFields = ["OpName"];
1039  let ColFields = ["Size"];
1040  let KeyCol = ["4"];
1041  let ValueCols = [["8"]];
1042}
1043
1044// Maps an opcode in e64 form to its e32 equivalent
1045def getVOPe32 : InstrMapping {
1046  let FilterClass = "VOP";
1047  let RowFields = ["OpName"];
1048  let ColFields = ["Size"];
1049  let KeyCol = ["8"];
1050  let ValueCols = [["4"]];
1051}
1052
1053def getMaskedMIMGOp : InstrMapping {
1054  let FilterClass = "MIMG_Mask";
1055  let RowFields = ["Op"];
1056  let ColFields = ["Channels"];
1057  let KeyCol = ["4"];
1058  let ValueCols = [["1"], ["2"], ["3"] ];
1059}
1060
1061// Maps an commuted opcode to its original version
1062def getCommuteOrig : InstrMapping {
1063  let FilterClass = "Commutable_REV";
1064  let RowFields = ["RevOp"];
1065  let ColFields = ["IsOrig"];
1066  let KeyCol = ["0"];
1067  let ValueCols = [["1"]];
1068}
1069
1070// Maps an original opcode to its commuted version
1071def getCommuteRev : InstrMapping {
1072  let FilterClass = "Commutable_REV";
1073  let RowFields = ["RevOp"];
1074  let ColFields = ["IsOrig"];
1075  let KeyCol = ["1"];
1076  let ValueCols = [["0"]];
1077}
1078
1079def getMCOpcodeGen : InstrMapping {
1080  let FilterClass = "SIMCInstr";
1081  let RowFields = ["PseudoInstr"];
1082  let ColFields = ["Subtarget"];
1083  let KeyCol = [!cast<string>(SIEncodingFamily.NONE)];
1084  let ValueCols = [[!cast<string>(SIEncodingFamily.SI)],
1085                   [!cast<string>(SIEncodingFamily.VI)]];
1086}
1087
1088// Get equivalent SOPK instruction.
1089def getSOPKOp : InstrMapping {
1090  let FilterClass = "SOPKInstTable";
1091  let RowFields = ["BaseCmpOp"];
1092  let ColFields = ["IsSOPK"];
1093  let KeyCol = ["0"];
1094  let ValueCols = [["1"]];
1095}
1096
1097def getAddr64Inst : InstrMapping {
1098  let FilterClass = "MUBUFAddr64Table";
1099  let RowFields = ["OpName"];
1100  let ColFields = ["IsAddr64"];
1101  let KeyCol = ["0"];
1102  let ValueCols = [["1"]];
1103}
1104
1105// Maps an atomic opcode to its version with a return value.
1106def getAtomicRetOp : InstrMapping {
1107  let FilterClass = "AtomicNoRet";
1108  let RowFields = ["NoRetOp"];
1109  let ColFields = ["IsRet"];
1110  let KeyCol = ["0"];
1111  let ValueCols = [["1"]];
1112}
1113
1114// Maps an atomic opcode to its returnless version.
1115def getAtomicNoRetOp : InstrMapping {
1116  let FilterClass = "AtomicNoRet";
1117  let RowFields = ["NoRetOp"];
1118  let ColFields = ["IsRet"];
1119  let KeyCol = ["1"];
1120  let ValueCols = [["0"]];
1121}
1122
1123include "SIInstructions.td"
1124include "CIInstructions.td"
1125include "VIInstructions.td"
1126
1127include "DSInstructions.td"
1128include "MIMGInstructions.td"
1129