SIInstrInfo.td revision 285181
11592Srgrimes//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
21592Srgrimes//
31592Srgrimes//                     The LLVM Compiler Infrastructure
41592Srgrimes//
51592Srgrimes// This file is distributed under the University of Illinois Open Source
61592Srgrimes// License. See LICENSE.TXT for details.
71592Srgrimes//
81592Srgrimes//===----------------------------------------------------------------------===//
91592Srgrimesdef isCI : Predicate<"Subtarget->getGeneration() "
101592Srgrimes                      ">= AMDGPUSubtarget::SEA_ISLANDS">;
111592Srgrimesdef isVI : Predicate <
121592Srgrimes  "Subtarget->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS">,
131592Srgrimes  AssemblerPredicate<"FeatureGCN3Encoding">;
141592Srgrimes
151592Srgrimesdef DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">;
161592Srgrimes
171592Srgrimesclass vop {
181592Srgrimes  field bits<9> SI3;
191592Srgrimes  field bits<10> VI3;
201592Srgrimes}
211592Srgrimes
221592Srgrimesclass vopc <bits<8> si, bits<8> vi = !add(0x40, si)> : vop {
231592Srgrimes  field bits<8> SI = si;
241592Srgrimes  field bits<8> VI = vi;
251592Srgrimes
261592Srgrimes  field bits<9>  SI3 = {0, si{7-0}};
271592Srgrimes  field bits<10> VI3 = {0, 0, vi{7-0}};
281592Srgrimes}
291592Srgrimes
301592Srgrimesclass vop1 <bits<8> si, bits<8> vi = si> : vop {
311592Srgrimes  field bits<8> SI = si;
321592Srgrimes  field bits<8> VI = vi;
331592Srgrimes
341592Srgrimes  field bits<9>  SI3 = {1, 1, si{6-0}};
3531491Scharnier  field bits<10> VI3 = !add(0x140, vi);
3621838Spst}
3731491Scharnier
3831491Scharnierclass vop2 <bits<6> si, bits<6> vi = si> : vop {
3950476Speter  field bits<6> SI = si;
401592Srgrimes  field bits<6> VI = vi;
411592Srgrimes
421592Srgrimes  field bits<9>  SI3 = {1, 0, 0, si{5-0}};
431592Srgrimes  field bits<10> VI3 = {0, 1, 0, 0, vi{5-0}};
441592Srgrimes}
451592Srgrimes
461592Srgrimes// Specify a VOP2 opcode for SI and VOP3 opcode for VI
471592Srgrimes// that doesn't have VOP2 encoding on VI
4821838Spstclass vop23 <bits<6> si, bits<10> vi> : vop2 <si> {
491592Srgrimes  let VI3 = vi;
5021838Spst}
511592Srgrimes
5221838Spstclass vop3 <bits<9> si, bits<10> vi = {0, si}> : vop {
5321838Spst  let SI3 = si;
5421838Spst  let VI3 = vi;
5521838Spst}
561592Srgrimes
571592Srgrimesclass sop1 <bits<8> si, bits<8> vi = si> {
5821838Spst  field bits<8> SI = si;
591592Srgrimes  field bits<8> VI = vi;
601592Srgrimes}
611592Srgrimes
6231491Scharnierclass sop2 <bits<7> si, bits<7> vi = si> {
6331491Scharnier  field bits<7> SI = si;
6431491Scharnier  field bits<7> VI = vi;
651592Srgrimes}
661592Srgrimes
671592Srgrimesclass sopk <bits<5> si, bits<5> vi = si> {
688870Srgrimes  field bits<5> SI = si;
691592Srgrimes  field bits<5> VI = vi;
708870Srgrimes}
711592Srgrimes
721592Srgrimes// Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
7331491Scharnier// in AMDGPUInstrInfo.cpp
741592Srgrimesdef SISubtarget {
751592Srgrimes  int NONE = -1;
761592Srgrimes  int SI = 0;
771592Srgrimes  int VI = 1;
781592Srgrimes}
791592Srgrimes
801592Srgrimes//===----------------------------------------------------------------------===//
811592Srgrimes// SI DAG Nodes
821592Srgrimes//===----------------------------------------------------------------------===//
831592Srgrimes
841592Srgrimesdef SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
851592Srgrimes  SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
861592Srgrimes                      [SDNPMayLoad, SDNPMemOperand]
871592Srgrimes>;
881592Srgrimes
891592Srgrimesdef SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
901592Srgrimes  SDTypeProfile<0, 13,
9121838Spst    [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
921592Srgrimes     SDTCisVT<1, iAny>,   // vdata(VGPR)
931592Srgrimes     SDTCisVT<2, i32>,    // num_channels(imm)
948870Srgrimes     SDTCisVT<3, i32>,    // vaddr(VGPR)
951592Srgrimes     SDTCisVT<4, i32>,    // soffset(SGPR)
961592Srgrimes     SDTCisVT<5, i32>,    // inst_offset(imm)
971592Srgrimes     SDTCisVT<6, i32>,    // dfmt(imm)
981592Srgrimes     SDTCisVT<7, i32>,    // nfmt(imm)
9931491Scharnier     SDTCisVT<8, i32>,    // offen(imm)
1001592Srgrimes     SDTCisVT<9, i32>,    // idxen(imm)
1011592Srgrimes     SDTCisVT<10, i32>,   // glc(imm)
1021592Srgrimes     SDTCisVT<11, i32>,   // slc(imm)
1031592Srgrimes     SDTCisVT<12, i32>    // tfe(imm)
1041592Srgrimes    ]>,
1051592Srgrimes  [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
1061592Srgrimes>;
10737262Sbde
1081592Srgrimesdef SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
1091592Srgrimes  SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
1101592Srgrimes                       SDTCisVT<3, i32>]>
1111592Srgrimes>;
1121592Srgrimes
1131592Srgrimesclass SDSample<string opcode> : SDNode <opcode,
1141592Srgrimes  SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
11521838Spst                       SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
1161592Srgrimes>;
1171592Srgrimes
1181592Srgrimesdef SIsample : SDSample<"AMDGPUISD::SAMPLE">;
1191592Srgrimesdef SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
1201592Srgrimesdef SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
12137262Sbdedef SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
12237262Sbde
12321838Spstdef SIconstdata_ptr : SDNode<
1241592Srgrimes  "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 0, [SDTCisVT<0, i64>]>
1251592Srgrimes>;
1261592Srgrimes
12721838Spst//===----------------------------------------------------------------------===//
12877862Sdd// SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1
12977862Sdd// to be glued to the memory instructions.
13079674Sbrian//===----------------------------------------------------------------------===//
13177862Sdd
1321592Srgrimesdef SIld_local : SDNode <"ISD::LOAD", SDTLoad,
1331592Srgrimes  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
1341592Srgrimes>;
13521838Spst
13621838Spstdef si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{
13721838Spst  return isLocalLoad(cast<LoadSDNode>(N));
13821838Spst}]>;
13921838Spst
1401592Srgrimesdef si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
1411592Srgrimes  return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
1421592Srgrimes         cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
14321838Spst}]>;
14421838Spst
1451592Srgrimesdef si_load_local_align8 : Aligned8Bytes <
1461592Srgrimes  (ops node:$ptr), (si_load_local node:$ptr)
1471592Srgrimes>;
14821838Spst
1491592Srgrimesdef si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
1501592Srgrimes  return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
1511592Srgrimes}]>;
1521592Srgrimesdef si_az_extload_local : AZExtLoadBase <si_ld_local>;
1531801Sphk
1541592Srgrimesmulticlass SIExtLoadLocal <PatFrag ld_node> {
1551592Srgrimes
1561592Srgrimes  def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
1571592Srgrimes                     [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}]
1581592Srgrimes  >;
1591592Srgrimes
1601592Srgrimes  def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
1611592Srgrimes                     [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}]
1621592Srgrimes  >;
1631592Srgrimes}
1641592Srgrimes
1651592Srgrimesdefm si_sextload_local : SIExtLoadLocal <si_sextload_local>;
1661592Srgrimesdefm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>;
1671592Srgrimes
1681592Srgrimesdef SIst_local : SDNode <"ISD::STORE", SDTStore,
1691592Srgrimes  [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
1701592Srgrimes>;
1711592Srgrimes
1721592Srgrimesdef si_st_local : PatFrag <
1731592Srgrimes  (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{
1741592Srgrimes  return isLocalStore(cast<StoreSDNode>(N));
1751592Srgrimes}]>;
1761592Srgrimes
1771592Srgrimesdef si_store_local : PatFrag <
1781592Srgrimes  (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
1791592Srgrimes  return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
180         !cast<StoreSDNode>(N)->isTruncatingStore();
181}]>;
182
183def si_store_local_align8 : Aligned8Bytes <
184  (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr)
185>;
186
187def si_truncstore_local : PatFrag <
188  (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
189  return cast<StoreSDNode>(N)->isTruncatingStore();
190}]>;
191
192def si_truncstore_local_i8 : PatFrag <
193  (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
194  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
195}]>;
196
197def si_truncstore_local_i16 : PatFrag <
198  (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
199  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
200}]>;
201
202multiclass SIAtomicM0Glue2 <string op_name> {
203
204  def _glue : SDNode <"ISD::ATOMIC_"#op_name, SDTAtomic2,
205    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
206  >;
207
208  def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>;
209}
210
211defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
212defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
213defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
214defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
215defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
216defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
217defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
218defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
219defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
220defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">;
221
222def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3,
223  [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
224>;
225
226defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>;
227
228// Transformation function, extract the lower 32bit of a 64bit immediate
229def LO32 : SDNodeXForm<imm, [{
230  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, SDLoc(N),
231                                   MVT::i32);
232}]>;
233
234def LO32f : SDNodeXForm<fpimm, [{
235  APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
236  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
237}]>;
238
239// Transformation function, extract the upper 32bit of a 64bit immediate
240def HI32 : SDNodeXForm<imm, [{
241  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, SDLoc(N), MVT::i32);
242}]>;
243
244def HI32f : SDNodeXForm<fpimm, [{
245  APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
246  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), SDLoc(N),
247                                     MVT::f32);
248}]>;
249
250def IMM8bitDWORD : PatLeaf <(imm),
251  [{return (N->getZExtValue() & ~0x3FC) == 0;}]
252>;
253
254def as_dword_i32imm : SDNodeXForm<imm, [{
255  return CurDAG->getTargetConstant(N->getZExtValue() >> 2, SDLoc(N), MVT::i32);
256}]>;
257
258def as_i1imm : SDNodeXForm<imm, [{
259  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
260}]>;
261
262def as_i8imm : SDNodeXForm<imm, [{
263  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
264}]>;
265
266def as_i16imm : SDNodeXForm<imm, [{
267  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
268}]>;
269
270def as_i32imm: SDNodeXForm<imm, [{
271  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
272}]>;
273
274def as_i64imm: SDNodeXForm<imm, [{
275  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
276}]>;
277
278// Copied from the AArch64 backend:
279def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
280return CurDAG->getTargetConstant(
281  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
282}]>;
283
284// Copied from the AArch64 backend:
285def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
286return CurDAG->getTargetConstant(
287  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
288}]>;
289
290def IMM8bit : PatLeaf <(imm),
291  [{return isUInt<8>(N->getZExtValue());}]
292>;
293
294def IMM12bit : PatLeaf <(imm),
295  [{return isUInt<12>(N->getZExtValue());}]
296>;
297
298def IMM16bit : PatLeaf <(imm),
299  [{return isUInt<16>(N->getZExtValue());}]
300>;
301
302def IMM20bit : PatLeaf <(imm),
303  [{return isUInt<20>(N->getZExtValue());}]
304>;
305
306def IMM32bit : PatLeaf <(imm),
307  [{return isUInt<32>(N->getZExtValue());}]
308>;
309
310def mubuf_vaddr_offset : PatFrag<
311  (ops node:$ptr, node:$offset, node:$imm_offset),
312  (add (add node:$ptr, node:$offset), node:$imm_offset)
313>;
314
315class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
316  return isInlineImmediate(N);
317}]>;
318
319class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
320  return isInlineImmediate(N);
321}]>;
322
323class SGPRImm <dag frag> : PatLeaf<frag, [{
324  if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) {
325    return false;
326  }
327  const SIRegisterInfo *SIRI =
328      static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo());
329  for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
330                                                U != E; ++U) {
331    if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
332      return true;
333    }
334  }
335  return false;
336}]>;
337
338//===----------------------------------------------------------------------===//
339// Custom Operands
340//===----------------------------------------------------------------------===//
341
342def FRAMEri32 : Operand<iPTR> {
343  let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
344}
345
346def SoppBrTarget : AsmOperandClass {
347  let Name = "SoppBrTarget";
348  let ParserMethod = "parseSOppBrTarget";
349}
350
351def sopp_brtarget : Operand<OtherVT> {
352  let EncoderMethod = "getSOPPBrEncoding";
353  let OperandType = "OPERAND_PCREL";
354  let ParserMatchClass = SoppBrTarget;
355}
356
357include "SIInstrFormats.td"
358include "VIInstrFormats.td"
359
360def MubufOffsetMatchClass : AsmOperandClass {
361  let Name = "MubufOffset";
362  let ParserMethod = "parseMubufOptionalOps";
363  let RenderMethod = "addImmOperands";
364}
365
366class DSOffsetBaseMatchClass <string parser> : AsmOperandClass {
367  let Name = "DSOffset"#parser;
368  let ParserMethod = parser;
369  let RenderMethod = "addImmOperands";
370  let PredicateMethod = "isDSOffset";
371}
372
373def DSOffsetMatchClass : DSOffsetBaseMatchClass <"parseDSOptionalOps">;
374def DSOffsetGDSMatchClass : DSOffsetBaseMatchClass <"parseDSOffsetOptional">;
375
376def DSOffset01MatchClass : AsmOperandClass {
377  let Name = "DSOffset1";
378  let ParserMethod = "parseDSOff01OptionalOps";
379  let RenderMethod = "addImmOperands";
380  let PredicateMethod = "isDSOffset01";
381}
382
383class GDSBaseMatchClass <string parser> : AsmOperandClass {
384  let Name = "GDS"#parser;
385  let PredicateMethod = "isImm";
386  let ParserMethod = parser;
387  let RenderMethod = "addImmOperands";
388}
389
390def GDSMatchClass : GDSBaseMatchClass <"parseDSOptionalOps">;
391def GDS01MatchClass : GDSBaseMatchClass <"parseDSOff01OptionalOps">;
392
393class GLCBaseMatchClass <string parser> : AsmOperandClass {
394  let Name = "GLC"#parser;
395  let PredicateMethod = "isImm";
396  let ParserMethod = parser; 
397  let RenderMethod = "addImmOperands";
398}
399
400def GLCMubufMatchClass : GLCBaseMatchClass <"parseMubufOptionalOps">;
401def GLCFlatMatchClass : GLCBaseMatchClass <"parseFlatOptionalOps">;
402
403class SLCBaseMatchClass <string parser> : AsmOperandClass {
404  let Name = "SLC"#parser;
405  let PredicateMethod = "isImm";
406  let ParserMethod = parser;
407  let RenderMethod = "addImmOperands";
408}
409
410def SLCMubufMatchClass : SLCBaseMatchClass <"parseMubufOptionalOps">;
411def SLCFlatMatchClass : SLCBaseMatchClass <"parseFlatOptionalOps">;
412def SLCFlatAtomicMatchClass : SLCBaseMatchClass <"parseFlatAtomicOptionalOps">;
413
414class TFEBaseMatchClass <string parser> : AsmOperandClass {
415  let Name = "TFE"#parser;
416  let PredicateMethod = "isImm";
417  let ParserMethod = parser;
418  let RenderMethod = "addImmOperands";
419}
420
421def TFEMubufMatchClass : TFEBaseMatchClass <"parseMubufOptionalOps">;
422def TFEFlatMatchClass : TFEBaseMatchClass <"parseFlatOptionalOps">;
423def TFEFlatAtomicMatchClass : TFEBaseMatchClass <"parseFlatAtomicOptionalOps">;
424
425def OModMatchClass : AsmOperandClass {
426  let Name = "OMod";
427  let PredicateMethod = "isImm";
428  let ParserMethod = "parseVOP3OptionalOps";
429  let RenderMethod = "addImmOperands";
430}
431
432def ClampMatchClass : AsmOperandClass {
433  let Name = "Clamp";
434  let PredicateMethod = "isImm";
435  let ParserMethod = "parseVOP3OptionalOps";
436  let RenderMethod = "addImmOperands";
437}
438
439let OperandType = "OPERAND_IMMEDIATE" in {
440
441def offen : Operand<i1> {
442  let PrintMethod = "printOffen";
443}
444def idxen : Operand<i1> {
445  let PrintMethod = "printIdxen";
446}
447def addr64 : Operand<i1> {
448  let PrintMethod = "printAddr64";
449}
450def mbuf_offset : Operand<i16> {
451  let PrintMethod = "printMBUFOffset";
452  let ParserMatchClass = MubufOffsetMatchClass;
453}
454class ds_offset_base <AsmOperandClass mc> : Operand<i16> {
455  let PrintMethod = "printDSOffset";
456  let ParserMatchClass = mc;
457}
458def ds_offset : ds_offset_base <DSOffsetMatchClass>;
459def ds_offset_gds : ds_offset_base <DSOffsetGDSMatchClass>;
460
461def ds_offset0 : Operand<i8> {
462  let PrintMethod = "printDSOffset0";
463  let ParserMatchClass = DSOffset01MatchClass;
464}
465def ds_offset1 : Operand<i8> {
466  let PrintMethod = "printDSOffset1";
467  let ParserMatchClass = DSOffset01MatchClass;
468}
469class gds_base <AsmOperandClass mc> : Operand <i1> {
470  let PrintMethod = "printGDS";
471  let ParserMatchClass = mc;
472}
473def gds : gds_base <GDSMatchClass>;
474
475def gds01 : gds_base <GDS01MatchClass>;
476
477class glc_base <AsmOperandClass mc> : Operand <i1> {
478  let PrintMethod = "printGLC";
479  let ParserMatchClass = mc;
480}
481
482def glc : glc_base <GLCMubufMatchClass>;
483def glc_flat : glc_base <GLCFlatMatchClass>;
484
485class slc_base <AsmOperandClass mc> : Operand <i1> {
486  let PrintMethod = "printSLC";
487  let ParserMatchClass = mc;
488}
489
490def slc : slc_base <SLCMubufMatchClass>;
491def slc_flat : slc_base <SLCFlatMatchClass>;
492def slc_flat_atomic : slc_base <SLCFlatAtomicMatchClass>;
493
494class tfe_base <AsmOperandClass mc> : Operand <i1> {
495  let PrintMethod = "printTFE";
496  let ParserMatchClass = mc;
497}
498
499def tfe : tfe_base <TFEMubufMatchClass>;
500def tfe_flat : tfe_base <TFEFlatMatchClass>;
501def tfe_flat_atomic : tfe_base <TFEFlatAtomicMatchClass>;
502
503def omod : Operand <i32> {
504  let PrintMethod = "printOModSI";
505  let ParserMatchClass = OModMatchClass;
506}
507
508def ClampMod : Operand <i1> {
509  let PrintMethod = "printClampSI";
510  let ParserMatchClass = ClampMatchClass;
511}
512
513} // End OperandType = "OPERAND_IMMEDIATE"
514
515def VOPDstS64 : VOPDstOperand <SReg_64>;
516
517//===----------------------------------------------------------------------===//
518// Complex patterns
519//===----------------------------------------------------------------------===//
520
521def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
522def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
523
524def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
525def MUBUFAddr64 : ComplexPattern<i64, 7, "SelectMUBUFAddr64">;
526def MUBUFAddr64Atomic : ComplexPattern<i64, 5, "SelectMUBUFAddr64">;
527def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
528def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
529def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
530
531def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
532def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
533def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
534def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
535
536//===----------------------------------------------------------------------===//
537// SI assembler operands
538//===----------------------------------------------------------------------===//
539
540def SIOperand {
541  int ZERO = 0x80;
542  int VCC = 0x6A;
543  int FLAT_SCR = 0x68;
544}
545
546def SRCMODS {
547  int NONE = 0;
548  int NEG = 1;
549}
550
551def DSTCLAMP {
552  int NONE = 0;
553}
554
555def DSTOMOD {
556  int NONE = 0;
557}
558
559//===----------------------------------------------------------------------===//
560//
561// SI Instruction multiclass helpers.
562//
563// Instructions with _32 take 32-bit operands.
564// Instructions with _64 take 64-bit operands.
565//
566// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
567// encoding is the standard encoding, but instruction that make use of
568// any of the instruction modifiers must use the 64-bit encoding.
569//
570// Instructions with _e32 use the 32-bit encoding.
571// Instructions with _e64 use the 64-bit encoding.
572//
573//===----------------------------------------------------------------------===//
574
575class SIMCInstr <string pseudo, int subtarget> {
576  string PseudoInstr = pseudo;
577  int Subtarget = subtarget;
578}
579
580//===----------------------------------------------------------------------===//
581// EXP classes
582//===----------------------------------------------------------------------===//
583
584class EXPCommon : InstSI<
585  (outs),
586  (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
587       VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3),
588  "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
589  [] > {
590
591  let EXP_CNT = 1;
592  let Uses = [EXEC];
593}
594
595multiclass EXP_m {
596
597  let isPseudo = 1, isCodeGenOnly = 1 in {
598    def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ;
599  }
600
601  def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe;
602
603  def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi;
604}
605
606//===----------------------------------------------------------------------===//
607// Scalar classes
608//===----------------------------------------------------------------------===//
609
610class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
611  SOP1 <outs, ins, "", pattern>,
612  SIMCInstr<opName, SISubtarget.NONE> {
613  let isPseudo = 1;
614  let isCodeGenOnly = 1;
615}
616
617class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> :
618  SOP1 <outs, ins, asm, []>,
619  SOP1e <op.SI>,
620  SIMCInstr<opName, SISubtarget.SI> {
621  let isCodeGenOnly = 0;
622  let AssemblerPredicates = [isSICI];
623}
624
625class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> :
626  SOP1 <outs, ins, asm, []>,
627  SOP1e <op.VI>,
628  SIMCInstr<opName, SISubtarget.VI> {
629  let isCodeGenOnly = 0;
630  let AssemblerPredicates = [isVI];
631}
632
633multiclass SOP1_m <sop1 op, string opName, dag outs, dag ins, string asm,
634                   list<dag> pattern> {
635
636  def "" : SOP1_Pseudo <opName, outs, ins, pattern>;
637
638  def _si : SOP1_Real_si <op, opName, outs, ins, asm>;
639
640  def _vi : SOP1_Real_vi <op, opName, outs, ins, asm>;
641
642}
643
644multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
645    op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
646    opName#" $dst, $src0", pattern
647>;
648
649multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
650    op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
651    opName#" $dst, $src0", pattern
652>;
653
654// no input, 64-bit output.
655multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> {
656  def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins), pattern>;
657
658  def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins),
659    opName#" $dst"> {
660    let ssrc0 = 0;
661  }
662
663  def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins),
664    opName#" $dst"> {
665    let ssrc0 = 0;
666  }
667}
668
669// 64-bit input, no output
670multiclass SOP1_1 <sop1 op, string opName, list<dag> pattern> {
671  def "" : SOP1_Pseudo <opName, (outs), (ins SReg_64:$src0), pattern>;
672
673  def _si : SOP1_Real_si <op, opName, (outs), (ins SReg_64:$src0),
674    opName#" $src0"> {
675    let sdst = 0;
676  }
677
678  def _vi : SOP1_Real_vi <op, opName, (outs), (ins SReg_64:$src0),
679    opName#" $src0"> {
680    let sdst = 0;
681  }
682}
683
684// 64-bit input, 32-bit output.
685multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
686    op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
687    opName#" $dst, $src0", pattern
688>;
689
690class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> :
691  SOP2<outs, ins, "", pattern>,
692  SIMCInstr<opName, SISubtarget.NONE> {
693  let isPseudo = 1;
694  let isCodeGenOnly = 1;
695  let Size = 4;
696
697  // Pseudo instructions have no encodings, but adding this field here allows
698  // us to do:
699  // let sdst = xxx in {
700  // for multiclasses that include both real and pseudo instructions.
701  field bits<7> sdst = 0;
702}
703
704class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm> :
705  SOP2<outs, ins, asm, []>,
706  SOP2e<op.SI>,
707  SIMCInstr<opName, SISubtarget.SI> {
708  let AssemblerPredicates = [isSICI];
709}
710
711class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm> :
712  SOP2<outs, ins, asm, []>,
713  SOP2e<op.VI>,
714  SIMCInstr<opName, SISubtarget.VI> {
715  let AssemblerPredicates = [isVI];
716}
717
718multiclass SOP2_SELECT_32 <sop2 op, string opName, list<dag> pattern> {
719  def "" : SOP2_Pseudo <opName, (outs SReg_32:$dst),
720    (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc), pattern>;
721
722  def _si : SOP2_Real_si <op, opName, (outs SReg_32:$dst),
723    (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc),
724    opName#" $dst, $src0, $src1 [$scc]">;
725
726  def _vi : SOP2_Real_vi <op, opName, (outs SReg_32:$dst),
727    (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc),
728    opName#" $dst, $src0, $src1 [$scc]">;
729}
730
731multiclass SOP2_m <sop2 op, string opName, dag outs, dag ins, string asm,
732                   list<dag> pattern> {
733
734  def "" : SOP2_Pseudo <opName, outs, ins, pattern>;
735
736  def _si : SOP2_Real_si <op, opName, outs, ins, asm>;
737
738  def _vi : SOP2_Real_vi <op, opName, outs, ins, asm>;
739
740}
741
742multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
743    op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
744    opName#" $dst, $src0, $src1", pattern
745>;
746
747multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
748    op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
749    opName#" $dst, $src0, $src1", pattern
750>;
751
752multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
753    op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
754    opName#" $dst, $src0, $src1", pattern
755>;
756
757class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
758                    string opName, PatLeaf cond> : SOPC <
759  op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
760  opName#" $src0, $src1", []>;
761
762class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
763  : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
764
765class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
766  : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
767
768class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
769  SOPK <outs, ins, "", pattern>,
770  SIMCInstr<opName, SISubtarget.NONE> {
771  let isPseudo = 1;
772  let isCodeGenOnly = 1;
773}
774
775class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm> :
776  SOPK <outs, ins, asm, []>,
777  SOPKe <op.SI>,
778  SIMCInstr<opName, SISubtarget.SI> {
779  let AssemblerPredicates = [isSICI];
780  let isCodeGenOnly = 0;
781}
782
783class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm> :
784  SOPK <outs, ins, asm, []>,
785  SOPKe <op.VI>,
786  SIMCInstr<opName, SISubtarget.VI> {
787  let AssemblerPredicates = [isVI];
788  let isCodeGenOnly = 0;
789}
790
791multiclass SOPK_m <sopk op, string opName, dag outs, dag ins, string opAsm,
792                   string asm = opName#opAsm> {
793  def "" : SOPK_Pseudo <opName, outs, ins, []>;
794
795  def _si : SOPK_Real_si <op, opName, outs, ins, asm>;
796
797  def _vi : SOPK_Real_vi <op, opName, outs, ins, asm>;
798
799}
800
801multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> {
802  def "" : SOPK_Pseudo <opName, (outs SReg_32:$dst), (ins u16imm:$src0),
803    pattern>;
804
805  def _si : SOPK_Real_si <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
806    opName#" $dst, $src0">;
807
808  def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
809    opName#" $dst, $src0">;
810}
811
812multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> {
813  def "" : SOPK_Pseudo <opName, (outs SCCReg:$dst),
814    (ins SReg_32:$src0, u16imm:$src1), pattern>;
815
816  let DisableEncoding = "$dst" in {
817    def _si : SOPK_Real_si <op, opName, (outs SCCReg:$dst),
818      (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16">;
819
820    def _vi : SOPK_Real_vi <op, opName, (outs SCCReg:$dst),
821      (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16">;
822  }
823}
824
825multiclass SOPK_32TIE <sopk op, string opName, list<dag> pattern> : SOPK_m <
826  op, opName, (outs SReg_32:$sdst), (ins SReg_32:$src0, u16imm:$simm16),
827  " $sdst, $simm16"
828>;
829
830multiclass SOPK_IMM32 <sopk op, string opName, dag outs, dag ins,
831                       string argAsm, string asm = opName#argAsm> {
832
833  def "" : SOPK_Pseudo <opName, outs, ins, []>;
834
835  def _si : SOPK <outs, ins, asm, []>,
836            SOPK64e <op.SI>,
837            SIMCInstr<opName, SISubtarget.SI> {
838              let AssemblerPredicates = [isSICI];
839              let isCodeGenOnly = 0;
840            }
841
842  def _vi : SOPK <outs, ins, asm, []>,
843            SOPK64e <op.VI>,
844            SIMCInstr<opName, SISubtarget.VI> {
845              let AssemblerPredicates = [isVI];
846              let isCodeGenOnly = 0;
847            }
848}
849//===----------------------------------------------------------------------===//
850// SMRD classes
851//===----------------------------------------------------------------------===//
852
853class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
854  SMRD <outs, ins, "", pattern>,
855  SIMCInstr<opName, SISubtarget.NONE> {
856  let isPseudo = 1;
857  let isCodeGenOnly = 1;
858}
859
860class SMRD_Real_si <bits<5> op, string opName, bit imm, dag outs, dag ins,
861                    string asm> :
862  SMRD <outs, ins, asm, []>,
863  SMRDe <op, imm>,
864  SIMCInstr<opName, SISubtarget.SI> {
865  let AssemblerPredicates = [isSICI];
866}
867
868class SMRD_Real_vi <bits<8> op, string opName, bit imm, dag outs, dag ins,
869                    string asm> :
870  SMRD <outs, ins, asm, []>,
871  SMEMe_vi <op, imm>,
872  SIMCInstr<opName, SISubtarget.VI> {
873  let AssemblerPredicates = [isVI];
874}
875
876multiclass SMRD_m <bits<5> op, string opName, bit imm, dag outs, dag ins,
877                   string asm, list<dag> pattern> {
878
879  def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
880
881  def _si : SMRD_Real_si <op, opName, imm, outs, ins, asm>;
882
883  // glc is only applicable to scalar stores, which are not yet
884  // implemented.
885  let glc = 0 in {
886    def _vi : SMRD_Real_vi <{0, 0, 0, op}, opName, imm, outs, ins, asm>;
887  }
888}
889
890multiclass SMRD_Helper <bits<5> op, string opName, RegisterClass baseClass,
891                        RegisterClass dstClass> {
892  defm _IMM : SMRD_m <
893    op, opName#"_IMM", 1, (outs dstClass:$dst),
894    (ins baseClass:$sbase, u32imm:$offset),
895    opName#" $dst, $sbase, $offset", []
896  >;
897
898  defm _SGPR : SMRD_m <
899    op, opName#"_SGPR", 0, (outs dstClass:$dst),
900    (ins baseClass:$sbase, SReg_32:$soff),
901    opName#" $dst, $sbase, $soff", []
902  >;
903}
904
905//===----------------------------------------------------------------------===//
906// Vector ALU classes
907//===----------------------------------------------------------------------===//
908
909// This must always be right before the operand being input modified.
910def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
911  let PrintMethod = "printOperandAndMods";
912}
913
914def InputModsMatchClass : AsmOperandClass {
915  let Name = "RegWithInputMods";
916}
917
918def InputModsNoDefault : Operand <i32> {
919  let PrintMethod = "printOperandAndMods";
920  let ParserMatchClass = InputModsMatchClass;
921}
922
923class getNumSrcArgs<ValueType Src1, ValueType Src2> {
924  int ret =
925    !if (!eq(Src1.Value, untyped.Value),      1,   // VOP1
926         !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
927                                              3)); // VOP3
928}
929
930// Returns the register class to use for the destination of VOP[123C]
931// instructions for the given VT.
932class getVALUDstForVT<ValueType VT> {
933  RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
934                          !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
935                            VOPDstOperand<SReg_64>)); // else VT == i1
936}
937
938// Returns the register class to use for source 0 of VOP[12C]
939// instructions for the given VT.
940class getVOPSrc0ForVT<ValueType VT> {
941  RegisterOperand ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64);
942}
943
944// Returns the register class to use for source 1 of VOP[12C] for the
945// given VT.
946class getVOPSrc1ForVT<ValueType VT> {
947  RegisterClass ret = !if(!eq(VT.Size, 32), VGPR_32, VReg_64);
948}
949
950// Returns the register class to use for sources of VOP3 instructions for the
951// given VT.
952class getVOP3SrcForVT<ValueType VT> {
953  RegisterOperand ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64);
954}
955
956// Returns 1 if the source arguments have modifiers, 0 if they do not.
957class hasModifiers<ValueType SrcVT> {
958  bit ret = !if(!eq(SrcVT.Value, f32.Value), 1,
959            !if(!eq(SrcVT.Value, f64.Value), 1, 0));
960}
961
962// Returns the input arguments for VOP[12C] instructions for the given SrcVT.
963class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
964  dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
965            !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
966                                    (ins)));
967}
968
969// Returns the input arguments for VOP3 instructions for the given SrcVT.
970class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
971                RegisterOperand Src2RC, int NumSrcArgs,
972                bit HasModifiers> {
973
974  dag ret =
975    !if (!eq(NumSrcArgs, 1),
976      !if (!eq(HasModifiers, 1),
977        // VOP1 with modifiers
978        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
979             ClampMod:$clamp, omod:$omod)
980      /* else */,
981        // VOP1 without modifiers
982        (ins Src0RC:$src0)
983      /* endif */ ),
984    !if (!eq(NumSrcArgs, 2),
985      !if (!eq(HasModifiers, 1),
986        // VOP 2 with modifiers
987        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
988             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
989             ClampMod:$clamp, omod:$omod)
990      /* else */,
991        // VOP2 without modifiers
992        (ins Src0RC:$src0, Src1RC:$src1)
993      /* endif */ )
994    /* NumSrcArgs == 3 */,
995      !if (!eq(HasModifiers, 1),
996        // VOP3 with modifiers
997        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
998             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
999             InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
1000             ClampMod:$clamp, omod:$omod)
1001      /* else */,
1002        // VOP3 without modifiers
1003        (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
1004      /* endif */ )));
1005}
1006
1007// Returns the assembly string for the inputs and outputs of a VOP[12C]
1008// instruction.  This does not add the _e32 suffix, so it can be reused
1009// by getAsm64.
1010class getAsm32 <int NumSrcArgs> {
1011  string src1 = ", $src1";
1012  string src2 = ", $src2";
1013  string ret = "$dst, $src0"#
1014               !if(!eq(NumSrcArgs, 1), "", src1)#
1015               !if(!eq(NumSrcArgs, 3), src2, "");
1016}
1017
1018// Returns the assembly string for the inputs and outputs of a VOP3
1019// instruction.
1020class getAsm64 <int NumSrcArgs, bit HasModifiers> {
1021  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1022  string src1 = !if(!eq(NumSrcArgs, 1), "",
1023                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1024                                           " $src1_modifiers,"));
1025  string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1026  string ret =
1027  !if(!eq(HasModifiers, 0),
1028      getAsm32<NumSrcArgs>.ret,
1029      "$dst, "#src0#src1#src2#"$clamp"#"$omod");
1030}
1031
1032
1033class VOPProfile <list<ValueType> _ArgVT> {
1034
1035  field list<ValueType> ArgVT = _ArgVT;
1036
1037  field ValueType DstVT = ArgVT[0];
1038  field ValueType Src0VT = ArgVT[1];
1039  field ValueType Src1VT = ArgVT[2];
1040  field ValueType Src2VT = ArgVT[3];
1041  field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
1042  field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
1043  field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
1044  field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
1045  field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
1046  field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
1047
1048  field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
1049  field bit HasModifiers = hasModifiers<Src0VT>.ret;
1050
1051  field dag Outs = (outs DstRC:$dst);
1052
1053  field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
1054  field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
1055                             HasModifiers>.ret;
1056
1057  field string Asm32 = getAsm32<NumSrcArgs>.ret;
1058  field string Asm64 = getAsm64<NumSrcArgs, HasModifiers>.ret;
1059}
1060
1061// FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order
1062//        for the instruction patterns to work.
1063def VOP_F16_F16 : VOPProfile <[f32, f32, untyped, untyped]>;
1064def VOP_F16_I16 : VOPProfile <[f32, i32, untyped, untyped]>;
1065def VOP_I16_F16 : VOPProfile <[i32, f32, untyped, untyped]>;
1066
1067def VOP_F16_F16_F16 : VOPProfile <[f32, f32, f32, untyped]>;
1068def VOP_F16_F16_I16 : VOPProfile <[f32, f32, i32, untyped]>;
1069def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
1070
1071def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
1072def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
1073def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
1074def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
1075def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
1076def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
1077def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
1078def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
1079def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
1080
1081def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
1082def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
1083def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
1084def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
1085def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
1086def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
1087def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
1088def VOP_I32_I32_I32_VCC : VOPProfile <[i32, i32, i32, untyped]> {
1089  let Src0RC32 = VCSrc_32;
1090}
1091
1092def VOP_I1_F32_I32 : VOPProfile <[i1, f32, i32, untyped]> {
1093  let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
1094  let Asm64 = "$dst, $src0_modifiers, $src1";
1095}
1096
1097def VOP_I1_F64_I32 : VOPProfile <[i1, f64, i32, untyped]> {
1098  let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
1099  let Asm64 = "$dst, $src0_modifiers, $src1";
1100}
1101
1102def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
1103def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
1104def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
1105def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> {
1106  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VCCReg:$src2);
1107  let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2);
1108  let Asm64 = "$dst, $src0, $src1, $src2";
1109}
1110
1111def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
1112def VOP_MADK : VOPProfile <[f32, f32, f32, f32]> {
1113  field dag Ins = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$src2);
1114  field string Asm = "$dst, $src0, $vsrc1, $src2";
1115}
1116def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
1117def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
1118def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
1119
1120
1121class VOP <string opName> {
1122  string OpName = opName;
1123}
1124
1125class VOP2_REV <string revOp, bit isOrig> {
1126  string RevOp = revOp;
1127  bit IsOrig = isOrig;
1128}
1129
1130class AtomicNoRet <string noRetOp, bit isRet> {
1131  string NoRetOp = noRetOp;
1132  bit IsRet = isRet;
1133}
1134
1135class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1136  VOP1Common <outs, ins, "", pattern>,
1137  VOP <opName>,
1138  SIMCInstr <opName#"_e32", SISubtarget.NONE>,
1139  MnemonicAlias<opName#"_e32", opName> {
1140  let isPseudo = 1;
1141  let isCodeGenOnly = 1;
1142
1143  field bits<8> vdst;
1144  field bits<9> src0;
1145}
1146
1147class VOP1_Real_si <string opName, vop1 op, dag outs, dag ins, string asm> :
1148  VOP1<op.SI, outs, ins, asm, []>,
1149  SIMCInstr <opName#"_e32", SISubtarget.SI> {
1150  let AssemblerPredicate = SIAssemblerPredicate;
1151}
1152
1153class VOP1_Real_vi <string opName, vop1 op, dag outs, dag ins, string asm> :
1154  VOP1<op.VI, outs, ins, asm, []>,
1155  SIMCInstr <opName#"_e32", SISubtarget.VI> {
1156  let AssemblerPredicates = [isVI];
1157}
1158
1159multiclass VOP1_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
1160                   string opName> {
1161  def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
1162
1163  def _si : VOP1_Real_si <opName, op, outs, ins, asm>;
1164
1165  def _vi : VOP1_Real_vi <opName, op, outs, ins, asm>;
1166}
1167
1168multiclass VOP1SI_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
1169                   string opName> {
1170  def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
1171
1172  def _si : VOP1_Real_si <opName, op, outs, ins, asm>;
1173}
1174
1175class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1176  VOP2Common <outs, ins, "", pattern>,
1177  VOP <opName>,
1178  SIMCInstr<opName#"_e32", SISubtarget.NONE>,
1179  MnemonicAlias<opName#"_e32", opName> {
1180  let isPseudo = 1;
1181  let isCodeGenOnly = 1;
1182}
1183
1184class VOP2_Real_si <string opName, vop2 op, dag outs, dag ins, string asm> :
1185  VOP2 <op.SI, outs, ins, opName#asm, []>,
1186  SIMCInstr <opName#"_e32", SISubtarget.SI> {
1187  let AssemblerPredicates = [isSICI];
1188}
1189
1190class VOP2_Real_vi <string opName, vop2 op, dag outs, dag ins, string asm> :
1191  VOP2 <op.VI, outs, ins, opName#asm, []>,
1192  SIMCInstr <opName#"_e32", SISubtarget.VI> {
1193  let AssemblerPredicates = [isVI];
1194}
1195
1196multiclass VOP2SI_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
1197                     string opName, string revOp> {
1198  def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
1199           VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1200
1201  def _si : VOP2_Real_si <opName, op, outs, ins, asm>;
1202}
1203
1204multiclass VOP2_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
1205                   string opName, string revOp> {
1206  def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
1207           VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1208
1209  def _si : VOP2_Real_si <opName, op, outs, ins, asm>;
1210
1211  def _vi : VOP2_Real_vi <opName, op, outs, ins, asm>;
1212
1213}
1214
1215class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
1216
1217  bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
1218  bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
1219  bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ?, 0), 0);
1220  bits<2> omod = !if(HasModifiers, ?, 0);
1221  bits<1> clamp = !if(HasModifiers, ?, 0);
1222  bits<9> src1 = !if(HasSrc1, ?, 0);
1223  bits<9> src2 = !if(HasSrc2, ?, 0);
1224}
1225
1226class VOP3DisableModFields <bit HasSrc0Mods,
1227                            bit HasSrc1Mods = 0,
1228                            bit HasSrc2Mods = 0,
1229                            bit HasOutputMods = 0> {
1230  bits<2> src0_modifiers = !if(HasSrc0Mods, ?, 0);
1231  bits<2> src1_modifiers = !if(HasSrc1Mods, ?, 0);
1232  bits<2> src2_modifiers = !if(HasSrc2Mods, ?, 0);
1233  bits<2> omod = !if(HasOutputMods, ?, 0);
1234  bits<1> clamp = !if(HasOutputMods, ?, 0);
1235}
1236
1237class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1238  VOP3Common <outs, ins, "", pattern>,
1239  VOP <opName>,
1240  SIMCInstr<opName#"_e64", SISubtarget.NONE>,
1241  MnemonicAlias<opName#"_e64", opName> {
1242  let isPseudo = 1;
1243  let isCodeGenOnly = 1;
1244}
1245
1246class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
1247  VOP3Common <outs, ins, asm, []>,
1248  VOP3e <op>,
1249  SIMCInstr<opName#"_e64", SISubtarget.SI> {
1250  let AssemblerPredicates = [isSICI];
1251}
1252
1253class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
1254  VOP3Common <outs, ins, asm, []>,
1255  VOP3e_vi <op>,
1256  SIMCInstr <opName#"_e64", SISubtarget.VI> {
1257  let AssemblerPredicates = [isVI];
1258}
1259
1260class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
1261  VOP3Common <outs, ins, asm, []>,
1262  VOP3be <op>,
1263  SIMCInstr<opName#"_e64", SISubtarget.SI> {
1264  let AssemblerPredicates = [isSICI];
1265}
1266
1267class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
1268  VOP3Common <outs, ins, asm, []>,
1269  VOP3be_vi <op>,
1270  SIMCInstr <opName#"_e64", SISubtarget.VI> {
1271  let AssemblerPredicates = [isVI];
1272}
1273
1274multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1275                   string opName, int NumSrcArgs, bit HasMods = 1> {
1276
1277  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1278
1279  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1280            VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1281                              !if(!eq(NumSrcArgs, 2), 0, 1),
1282                              HasMods>;
1283  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1284            VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1285                              !if(!eq(NumSrcArgs, 2), 0, 1),
1286                              HasMods>;
1287}
1288
1289// VOP3_m without source modifiers
1290multiclass VOP3_m_nomods <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1291                   string opName, int NumSrcArgs, bit HasMods = 1> {
1292
1293  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1294
1295  let src0_modifiers = 0,
1296      src1_modifiers = 0,
1297      src2_modifiers = 0,
1298      clamp = 0,
1299      omod = 0 in {
1300    def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>;
1301    def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>;
1302  }
1303}
1304
1305multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
1306                     list<dag> pattern, string opName, bit HasMods = 1> {
1307
1308  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1309
1310  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1311            VOP3DisableFields<0, 0, HasMods>;
1312
1313  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1314            VOP3DisableFields<0, 0, HasMods>;
1315}
1316
1317multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm,
1318                     list<dag> pattern, string opName, bit HasMods = 1> {
1319
1320  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1321
1322  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1323            VOP3DisableFields<0, 0, HasMods>;
1324  // No VI instruction. This class is for SI only.
1325}
1326
1327multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
1328                     list<dag> pattern, string opName, string revOp,
1329                     bit HasMods = 1, bit UseFullOp = 0> {
1330
1331  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1332           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1333
1334  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1335            VOP3DisableFields<1, 0, HasMods>;
1336
1337  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1338            VOP3DisableFields<1, 0, HasMods>;
1339}
1340
1341multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm,
1342                     list<dag> pattern, string opName, string revOp,
1343                     bit HasMods = 1, bit UseFullOp = 0> {
1344
1345  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1346           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1347
1348  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1349            VOP3DisableFields<1, 0, HasMods>;
1350
1351  // No VI instruction. This class is for SI only.
1352}
1353
1354// XXX - Is v_div_scale_{f32|f64} only available in vop3b without
1355// option of implicit vcc use?
1356multiclass VOP3b_2_m <vop op, dag outs, dag ins, string asm,
1357                      list<dag> pattern, string opName, string revOp,
1358                      bit HasMods = 1, bit UseFullOp = 0> {
1359  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1360           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1361
1362  // The VOP2 variant puts the carry out into VCC, the VOP3 variant
1363  // can write it into any SGPR. We currently don't use the carry out,
1364  // so for now hardcode it to VCC as well.
1365  let sdst = SIOperand.VCC, Defs = [VCC] in {
1366    def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>,
1367              VOP3DisableFields<1, 0, HasMods>;
1368
1369    def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>,
1370              VOP3DisableFields<1, 0, HasMods>;
1371  } // End sdst = SIOperand.VCC, Defs = [VCC]
1372}
1373
1374multiclass VOP3b_3_m <vop op, dag outs, dag ins, string asm,
1375                      list<dag> pattern, string opName, string revOp,
1376                      bit HasMods = 1, bit UseFullOp = 0> {
1377  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1378
1379
1380  def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>,
1381            VOP3DisableFields<1, 1, HasMods>;
1382
1383  def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>,
1384            VOP3DisableFields<1, 1, HasMods>;
1385}
1386
1387multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
1388                     list<dag> pattern, string opName,
1389                     bit HasMods, bit defExec, string revOp> {
1390
1391  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1392           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1393
1394  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1395            VOP3DisableFields<1, 0, HasMods> {
1396    let Defs = !if(defExec, [EXEC], []);
1397  }
1398
1399  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1400            VOP3DisableFields<1, 0, HasMods> {
1401    let Defs = !if(defExec, [EXEC], []);
1402  }
1403}
1404
1405// An instruction that is VOP2 on SI and VOP3 on VI, no modifiers.
1406multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins,
1407                         string asm, list<dag> pattern = []> {
1408  let isPseudo = 1, isCodeGenOnly = 1 in {
1409    def "" : VOPAnyCommon <outs, ins, "", pattern>,
1410             SIMCInstr<opName, SISubtarget.NONE>;
1411  }
1412
1413  def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>,
1414            SIMCInstr <opName, SISubtarget.SI> {
1415            let AssemblerPredicates = [isSICI];
1416  }
1417
1418  def _vi : VOP3Common <outs, ins, asm, []>,
1419            VOP3e_vi <op.VI3>,
1420            VOP3DisableFields <1, 0, 0>,
1421            SIMCInstr <opName, SISubtarget.VI> {
1422            let AssemblerPredicates = [isVI];
1423  }
1424}
1425
1426multiclass VOP1_Helper <vop1 op, string opName, dag outs,
1427                        dag ins32, string asm32, list<dag> pat32,
1428                        dag ins64, string asm64, list<dag> pat64,
1429                        bit HasMods> {
1430
1431  defm _e32 : VOP1_m <op, outs, ins32, opName#asm32, pat32, opName>;
1432
1433  defm _e64 : VOP3_1_m <op, outs, ins64, opName#asm64, pat64, opName, HasMods>;
1434}
1435
1436multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
1437                     SDPatternOperator node = null_frag> : VOP1_Helper <
1438  op, opName, P.Outs,
1439  P.Ins32, P.Asm32, [],
1440  P.Ins64, P.Asm64,
1441  !if(P.HasModifiers,
1442      [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1443                                i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1444      [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1445  P.HasModifiers
1446>;
1447
1448multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
1449                       SDPatternOperator node = null_frag> {
1450
1451  defm _e32 : VOP1SI_m <op, P.Outs, P.Ins32, opName#P.Asm32, [], opName>;
1452
1453  defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1454    !if(P.HasModifiers,
1455      [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1456                                i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1457      [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1458    opName, P.HasModifiers>;
1459}
1460
1461multiclass VOP2_Helper <vop2 op, string opName, dag outs,
1462                        dag ins32, string asm32, list<dag> pat32,
1463                        dag ins64, string asm64, list<dag> pat64,
1464                        string revOp, bit HasMods> {
1465  defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1466
1467  defm _e64 : VOP3_2_m <op,
1468    outs, ins64, opName#asm64, pat64, opName, revOp, HasMods
1469  >;
1470}
1471
1472multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
1473                     SDPatternOperator node = null_frag,
1474                     string revOp = opName> : VOP2_Helper <
1475  op, opName, P.Outs,
1476  P.Ins32, P.Asm32, [],
1477  P.Ins64, P.Asm64,
1478  !if(P.HasModifiers,
1479      [(set P.DstVT:$dst,
1480           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1481                                      i1:$clamp, i32:$omod)),
1482                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1483      [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1484  revOp, P.HasModifiers
1485>;
1486
1487multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P,
1488                       SDPatternOperator node = null_frag,
1489                       string revOp = opName> {
1490  defm _e32 : VOP2SI_m <op, P.Outs, P.Ins32, P.Asm32, [], opName, revOp>;
1491
1492  defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1493    !if(P.HasModifiers,
1494        [(set P.DstVT:$dst,
1495             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1496                                        i1:$clamp, i32:$omod)),
1497                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1498        [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1499    opName, revOp, P.HasModifiers>;
1500}
1501
1502multiclass VOP2b_Helper <vop2 op, string opName, dag outs,
1503                         dag ins32, string asm32, list<dag> pat32,
1504                         dag ins64, string asm64, list<dag> pat64,
1505                         string revOp, bit HasMods> {
1506
1507  defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1508
1509  defm _e64 : VOP3b_2_m <op,
1510    outs, ins64, opName#asm64, pat64, opName, revOp, HasMods
1511  >;
1512}
1513
1514multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
1515                      SDPatternOperator node = null_frag,
1516                      string revOp = opName> : VOP2b_Helper <
1517  op, opName, P.Outs,
1518  P.Ins32, P.Asm32, [],
1519  P.Ins64, P.Asm64,
1520  !if(P.HasModifiers,
1521      [(set P.DstVT:$dst,
1522           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1523                                      i1:$clamp, i32:$omod)),
1524                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1525      [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1526  revOp, P.HasModifiers
1527>;
1528
1529// A VOP2 instruction that is VOP3-only on VI.
1530multiclass VOP2_VI3_Helper <vop23 op, string opName, dag outs,
1531                            dag ins32, string asm32, list<dag> pat32,
1532                            dag ins64, string asm64, list<dag> pat64,
1533                            string revOp, bit HasMods> {
1534  defm _e32 : VOP2SI_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1535
1536  defm _e64 : VOP3_2_m <op, outs, ins64, opName#asm64, pat64, opName,
1537                        revOp, HasMods>;
1538}
1539
1540multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P,
1541                          SDPatternOperator node = null_frag,
1542                          string revOp = opName>
1543                          : VOP2_VI3_Helper <
1544  op, opName, P.Outs,
1545  P.Ins32, P.Asm32, [],
1546  P.Ins64, P.Asm64,
1547  !if(P.HasModifiers,
1548      [(set P.DstVT:$dst,
1549           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1550                                      i1:$clamp, i32:$omod)),
1551                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1552      [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1553  revOp, P.HasModifiers
1554>;
1555
1556multiclass VOP2MADK <vop2 op, string opName, list<dag> pattern = []> {
1557
1558  def "" : VOP2_Pseudo <VOP_MADK.Outs, VOP_MADK.Ins, pattern, opName>;
1559
1560let isCodeGenOnly = 0 in {
1561  def _si : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1562                        !strconcat(opName, VOP_MADK.Asm), []>,
1563            SIMCInstr <opName#"_e32", SISubtarget.SI>,
1564            VOP2_MADKe <op.SI> {
1565            let AssemblerPredicates = [isSICI];
1566            }
1567
1568  def _vi : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1569                        !strconcat(opName, VOP_MADK.Asm), []>,
1570            SIMCInstr <opName#"_e32", SISubtarget.VI>,
1571            VOP2_MADKe <op.VI> {
1572            let AssemblerPredicates = [isVI];
1573            }
1574} // End isCodeGenOnly = 0
1575}
1576
1577class VOPC_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1578  VOPCCommon <ins, "", pattern>,
1579  VOP <opName>,
1580  SIMCInstr<opName#"_e32", SISubtarget.NONE>,
1581  MnemonicAlias<opName#"_e32", opName> {
1582  let isPseudo = 1;
1583  let isCodeGenOnly = 1;
1584}
1585
1586multiclass VOPC_m <vopc op, dag outs, dag ins, string asm, list<dag> pattern,
1587                   string opName, bit DefExec, string revOpName = ""> {
1588  def "" : VOPC_Pseudo <outs, ins, pattern, opName>;
1589
1590  def _si : VOPC<op.SI, ins, asm, []>,
1591            SIMCInstr <opName#"_e32", SISubtarget.SI> {
1592    let Defs = !if(DefExec, [EXEC], []);
1593    let hasSideEffects = DefExec;
1594  }
1595
1596  def _vi : VOPC<op.VI, ins, asm, []>,
1597            SIMCInstr <opName#"_e32", SISubtarget.VI> {
1598    let Defs = !if(DefExec, [EXEC], []);
1599    let hasSideEffects = DefExec;
1600  }
1601}
1602
1603multiclass VOPC_Helper <vopc op, string opName,
1604                        dag ins32, string asm32, list<dag> pat32,
1605                        dag out64, dag ins64, string asm64, list<dag> pat64,
1606                        bit HasMods, bit DefExec, string revOp> {
1607  defm _e32 : VOPC_m <op, (outs), ins32, opName#asm32, pat32, opName, DefExec>;
1608
1609  defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64,
1610                        opName, HasMods, DefExec, revOp>;
1611}
1612
1613// Special case for class instructions which only have modifiers on
1614// the 1st source operand.
1615multiclass VOPC_Class_Helper <vopc op, string opName,
1616                             dag ins32, string asm32, list<dag> pat32,
1617                             dag out64, dag ins64, string asm64, list<dag> pat64,
1618                             bit HasMods, bit DefExec, string revOp> {
1619  defm _e32 : VOPC_m <op, (outs), ins32, opName#asm32, pat32, opName, DefExec>;
1620
1621  defm _e64 : VOP3_C_m <op, out64, ins64, opName#asm64, pat64,
1622                        opName, HasMods, DefExec, revOp>,
1623                        VOP3DisableModFields<1, 0, 0>;
1624}
1625
1626multiclass VOPCInst <vopc op, string opName,
1627                     VOPProfile P, PatLeaf cond = COND_NULL,
1628                     string revOp = opName,
1629                     bit DefExec = 0> : VOPC_Helper <
1630  op, opName,
1631  P.Ins32, P.Asm32, [],
1632  (outs VOPDstS64:$dst), P.Ins64, P.Asm64,
1633  !if(P.HasModifiers,
1634      [(set i1:$dst,
1635          (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1636                                      i1:$clamp, i32:$omod)),
1637                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1638                 cond))],
1639      [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
1640  P.HasModifiers, DefExec, revOp
1641>;
1642
1643multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
1644                     bit DefExec = 0> : VOPC_Class_Helper <
1645  op, opName,
1646  P.Ins32, P.Asm32, [],
1647  (outs VOPDstS64:$dst), P.Ins64, P.Asm64,
1648  !if(P.HasModifiers,
1649      [(set i1:$dst,
1650          (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
1651      [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
1652  P.HasModifiers, DefExec, opName
1653>;
1654
1655
1656multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1657  VOPCInst <op, opName, VOP_F32_F32_F32, cond, revOp>;
1658
1659multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1660  VOPCInst <op, opName, VOP_F64_F64_F64, cond, revOp>;
1661
1662multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1663  VOPCInst <op, opName, VOP_I32_I32_I32, cond, revOp>;
1664
1665multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
1666  VOPCInst <op, opName, VOP_I64_I64_I64, cond, revOp>;
1667
1668
1669multiclass VOPCX <vopc op, string opName, VOPProfile P,
1670                  PatLeaf cond = COND_NULL,
1671                  string revOp = "">
1672  : VOPCInst <op, opName, P, cond, revOp, 1>;
1673
1674multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> :
1675  VOPCX <op, opName, VOP_F32_F32_F32, COND_NULL, revOp>;
1676
1677multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> :
1678  VOPCX <op, opName, VOP_F64_F64_F64, COND_NULL, revOp>;
1679
1680multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> :
1681  VOPCX <op, opName, VOP_I32_I32_I32, COND_NULL, revOp>;
1682
1683multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> :
1684  VOPCX <op, opName, VOP_I64_I64_I64, COND_NULL, revOp>;
1685
1686multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
1687                        list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m <
1688    op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods
1689>;
1690
1691multiclass VOPC_CLASS_F32 <vopc op, string opName> :
1692  VOPCClassInst <op, opName, VOP_I1_F32_I32, 0>;
1693
1694multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
1695  VOPCClassInst <op, opName, VOP_I1_F32_I32, 1>;
1696
1697multiclass VOPC_CLASS_F64 <vopc op, string opName> :
1698  VOPCClassInst <op, opName, VOP_I1_F64_I32, 0>;
1699
1700multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
1701  VOPCClassInst <op, opName, VOP_I1_F64_I32, 1>;
1702
1703multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
1704                     SDPatternOperator node = null_frag> : VOP3_Helper <
1705  op, opName, (outs P.DstRC.RegClass:$dst), P.Ins64, P.Asm64,
1706  !if(!eq(P.NumSrcArgs, 3),
1707    !if(P.HasModifiers,
1708        [(set P.DstVT:$dst,
1709            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1710                                       i1:$clamp, i32:$omod)),
1711                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1712                  (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
1713        [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1,
1714                                  P.Src2VT:$src2))]),
1715  !if(!eq(P.NumSrcArgs, 2),
1716    !if(P.HasModifiers,
1717        [(set P.DstVT:$dst,
1718            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1719                                       i1:$clamp, i32:$omod)),
1720                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1721        [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
1722  /* P.NumSrcArgs == 1 */,
1723    !if(P.HasModifiers,
1724        [(set P.DstVT:$dst,
1725            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1726                                       i1:$clamp, i32:$omod))))],
1727        [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),
1728  P.NumSrcArgs, P.HasModifiers
1729>;
1730
1731// Special case for v_div_fmas_{f32|f64}, since it seems to be the
1732// only VOP instruction that implicitly reads VCC.
1733multiclass VOP3_VCC_Inst <vop3 op, string opName,
1734                          VOPProfile P,
1735                          SDPatternOperator node = null_frag> : VOP3_Helper <
1736  op, opName,
1737  (outs P.DstRC.RegClass:$dst),
1738  (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0,
1739       InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1,
1740       InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2,
1741       ClampMod:$clamp,
1742       omod:$omod),
1743  "$dst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
1744  [(set P.DstVT:$dst,
1745            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1746                                       i1:$clamp, i32:$omod)),
1747                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1748                  (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)),
1749                  (i1 VCC)))],
1750  3, 1
1751>;
1752
1753multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc,
1754                    string opName, list<dag> pattern> :
1755  VOP3b_3_m <
1756  op, (outs vrc:$vdst, SReg_64:$sdst),
1757      (ins InputModsNoDefault:$src0_modifiers, arc:$src0,
1758           InputModsNoDefault:$src1_modifiers, arc:$src1,
1759           InputModsNoDefault:$src2_modifiers, arc:$src2,
1760           ClampMod:$clamp, omod:$omod),
1761  opName#" $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern,
1762  opName, opName, 1, 1
1763>;
1764
1765multiclass VOP3b_64 <vop3 op, string opName, list<dag> pattern> :
1766  VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
1767
1768multiclass VOP3b_32 <vop3 op, string opName, list<dag> pattern> :
1769  VOP3b_Helper <op, VGPR_32, VSrc_32, opName, pattern>;
1770
1771
1772class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
1773  (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
1774        (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1775        (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
1776  (Inst i32:$src0_modifiers, P.Src0VT:$src0,
1777        i32:$src1_modifiers, P.Src1VT:$src1,
1778        i32:$src2_modifiers, P.Src2VT:$src2,
1779        i1:$clamp,
1780        i32:$omod)>;
1781
1782//===----------------------------------------------------------------------===//
1783// Interpolation opcodes
1784//===----------------------------------------------------------------------===//
1785
1786class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1787  VINTRPCommon <outs, ins, "", pattern>,
1788  SIMCInstr<opName, SISubtarget.NONE> {
1789  let isPseudo = 1;
1790  let isCodeGenOnly = 1;
1791}
1792
1793class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
1794                      string asm> :
1795  VINTRPCommon <outs, ins, asm, []>,
1796  VINTRPe <op>,
1797  SIMCInstr<opName, SISubtarget.SI>;
1798
1799class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
1800                      string asm> :
1801  VINTRPCommon <outs, ins, asm, []>,
1802  VINTRPe_vi <op>,
1803  SIMCInstr<opName, SISubtarget.VI>;
1804
1805multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
1806                     list<dag> pattern = []> {
1807  def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
1808
1809  def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
1810
1811  def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
1812}
1813
1814//===----------------------------------------------------------------------===//
1815// Vector I/O classes
1816//===----------------------------------------------------------------------===//
1817
1818class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1819  DS <outs, ins, "", pattern>,
1820  SIMCInstr <opName, SISubtarget.NONE> {
1821  let isPseudo = 1;
1822  let isCodeGenOnly = 1;
1823}
1824
1825class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1826  DS <outs, ins, asm, []>,
1827  DSe <op>,
1828  SIMCInstr <opName, SISubtarget.SI> {
1829  let isCodeGenOnly = 0;
1830}
1831
1832class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1833  DS <outs, ins, asm, []>,
1834  DSe_vi <op>,
1835  SIMCInstr <opName, SISubtarget.VI>;
1836
1837class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1838  DS_Real_si <op,opName, outs, ins, asm> {
1839
1840  // Single load interpret the 2 i8imm operands as a single i16 offset.
1841  bits<16> offset;
1842  let offset0 = offset{7-0};
1843  let offset1 = offset{15-8};
1844  let isCodeGenOnly = 0;
1845}
1846
1847class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1848  DS_Real_vi <op, opName, outs, ins, asm> {
1849
1850  // Single load interpret the 2 i8imm operands as a single i16 offset.
1851  bits<16> offset;
1852  let offset0 = offset{7-0};
1853  let offset1 = offset{15-8};
1854}
1855
1856multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc,
1857  dag outs = (outs rc:$vdst),
1858  dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
1859  string asm = opName#" $vdst, $addr"#"$offset$gds"> {
1860
1861  def "" : DS_Pseudo <opName, outs, ins, []>;
1862
1863  let data0 = 0, data1 = 0 in {
1864    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1865    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1866  }
1867}
1868
1869multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc,
1870  dag outs = (outs rc:$vdst),
1871  dag ins = (ins VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1,
1872                 gds01:$gds),
1873  string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> {
1874
1875  def "" : DS_Pseudo <opName, outs, ins, []>;
1876
1877  let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in {
1878    def _si : DS_Real_si <op, opName, outs, ins, asm>;
1879    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1880  }
1881}
1882
1883multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc,
1884  dag outs = (outs),
1885  dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
1886  string asm = opName#" $addr, $data0"#"$offset$gds"> {
1887
1888  def "" : DS_Pseudo <opName, outs, ins, []>,
1889           AtomicNoRet<opName, 0>;
1890
1891  let data1 = 0, vdst = 0 in {
1892    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1893    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1894  }
1895}
1896
1897multiclass DS_1A1D_Off8_NORET <bits<8> op, string opName, RegisterClass rc,
1898  dag outs = (outs),
1899  dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
1900              ds_offset0:$offset0, ds_offset1:$offset1, gds01:$gds),
1901  string asm = opName#" $addr, $data0, $data1"#"$offset0"#"$offset1"#"$gds"> {
1902
1903  def "" : DS_Pseudo <opName, outs, ins, []>;
1904
1905  let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in {
1906    def _si : DS_Real_si <op, opName, outs, ins, asm>;
1907    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1908  }
1909}
1910
1911multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc,
1912                        string noRetOp = "",
1913  dag outs = (outs rc:$vdst),
1914  dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
1915  string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> {
1916
1917  def "" : DS_Pseudo <opName, outs, ins, []>,
1918           AtomicNoRet<noRetOp, 1>;
1919
1920  let data1 = 0 in {
1921    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1922    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1923  }
1924}
1925
1926multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc,
1927                          string noRetOp = "", dag ins,
1928  dag outs = (outs rc:$vdst),
1929  string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> {
1930
1931  def "" : DS_Pseudo <opName, outs, ins, []>,
1932           AtomicNoRet<noRetOp, 1>;
1933
1934  def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1935  def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1936}
1937
1938multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc,
1939                        string noRetOp = "", RegisterClass src = rc> :
1940  DS_1A2D_RET_m <op, asm, rc, noRetOp,
1941                 (ins VGPR_32:$addr, src:$data0, src:$data1,
1942                      ds_offset:$offset, gds:$gds)
1943>;
1944
1945multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc,
1946                          string noRetOp = opName,
1947  dag outs = (outs),
1948  dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
1949                 ds_offset:$offset, gds:$gds),
1950  string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> {
1951
1952  def "" : DS_Pseudo <opName, outs, ins, []>,
1953           AtomicNoRet<noRetOp, 0>;
1954
1955  let vdst = 0 in {
1956    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1957    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1958  }
1959}
1960
1961multiclass DS_0A_RET <bits<8> op, string opName,
1962  dag outs = (outs VGPR_32:$vdst),
1963  dag ins = (ins ds_offset:$offset, gds:$gds),
1964  string asm = opName#" $vdst"#"$offset"#"$gds"> {
1965
1966  let mayLoad = 1, mayStore = 1 in {
1967    def "" : DS_Pseudo <opName, outs, ins, []>;
1968
1969    let addr = 0, data0 = 0, data1 = 0 in {
1970      def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1971      def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1972    } // end addr = 0, data0 = 0, data1 = 0
1973  } // end mayLoad = 1, mayStore = 1
1974}
1975
1976multiclass DS_1A_RET_GDS <bits<8> op, string opName,
1977  dag outs = (outs VGPR_32:$vdst),
1978  dag ins = (ins VGPR_32:$addr, ds_offset_gds:$offset),
1979  string asm = opName#" $vdst, $addr"#"$offset gds"> {
1980
1981  def "" : DS_Pseudo <opName, outs, ins, []>;
1982
1983  let data0 = 0, data1 = 0, gds = 1 in {
1984    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
1985    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
1986  } // end data0 = 0, data1 = 0, gds = 1
1987}
1988
1989multiclass DS_1A_GDS <bits<8> op, string opName,
1990  dag outs = (outs),
1991  dag ins = (ins VGPR_32:$addr),
1992  string asm = opName#" $addr gds"> {
1993
1994  def "" : DS_Pseudo <opName, outs, ins, []>;
1995
1996  let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in {
1997    def _si : DS_Real_si <op, opName, outs, ins, asm>;
1998    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1999  } // end vdst = 0, data = 0, data1 = 0, gds = 1
2000}
2001
2002multiclass DS_1A <bits<8> op, string opName,
2003  dag outs = (outs),
2004  dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
2005  string asm = opName#" $addr"#"$offset"#"$gds"> {
2006
2007  let mayLoad = 1, mayStore = 1 in {
2008    def "" : DS_Pseudo <opName, outs, ins, []>;
2009
2010    let vdst = 0, data0 = 0, data1 = 0 in {
2011      def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2012      def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2013    } // let vdst = 0, data0 = 0, data1 = 0
2014  } // end mayLoad = 1, mayStore = 1
2015}
2016
2017//===----------------------------------------------------------------------===//
2018// MTBUF classes
2019//===----------------------------------------------------------------------===//
2020
2021class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2022  MTBUF <outs, ins, "", pattern>,
2023  SIMCInstr<opName, SISubtarget.NONE> {
2024  let isPseudo = 1;
2025  let isCodeGenOnly = 1;
2026}
2027
2028class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
2029                    string asm> :
2030  MTBUF <outs, ins, asm, []>,
2031  MTBUFe <op>,
2032  SIMCInstr<opName, SISubtarget.SI>;
2033
2034class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
2035  MTBUF <outs, ins, asm, []>,
2036  MTBUFe_vi <op>,
2037  SIMCInstr <opName, SISubtarget.VI>;
2038
2039multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
2040                    list<dag> pattern> {
2041
2042  def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
2043
2044  def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
2045
2046  def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
2047
2048}
2049
2050let mayStore = 1, mayLoad = 0 in {
2051
2052multiclass MTBUF_Store_Helper <bits<3> op, string opName,
2053                               RegisterClass regClass> : MTBUF_m <
2054  op, opName, (outs),
2055  (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
2056   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
2057   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2058  opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2059        #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2060>;
2061
2062} // mayStore = 1, mayLoad = 0
2063
2064let mayLoad = 1, mayStore = 0 in {
2065
2066multiclass MTBUF_Load_Helper <bits<3> op, string opName,
2067                              RegisterClass regClass> : MTBUF_m <
2068  op, opName, (outs regClass:$dst),
2069  (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
2070       i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
2071       i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2072  opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2073        #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2074>;
2075
2076} // mayLoad = 1, mayStore = 0
2077
2078//===----------------------------------------------------------------------===//
2079// MUBUF classes
2080//===----------------------------------------------------------------------===//
2081
2082class mubuf <bits<7> si, bits<7> vi = si> {
2083  field bits<7> SI = si;
2084  field bits<7> VI = vi;
2085}
2086
2087let isCodeGenOnly = 0 in {
2088
2089class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2090  MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
2091  let lds  = 0;
2092}
2093
2094} // End let isCodeGenOnly = 0
2095
2096class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2097  MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> {
2098  let lds = 0;
2099}
2100
2101class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
2102  bit IsAddr64 = is_addr64;
2103  string OpName = NAME # suffix;
2104}
2105
2106class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2107  MUBUF <outs, ins, "", pattern>,
2108  SIMCInstr<opName, SISubtarget.NONE> {
2109  let isPseudo = 1;
2110  let isCodeGenOnly = 1;
2111
2112  // dummy fields, so that we can use let statements around multiclasses
2113  bits<1> offen;
2114  bits<1> idxen;
2115  bits<8> vaddr;
2116  bits<1> glc;
2117  bits<1> slc;
2118  bits<1> tfe;
2119  bits<8> soffset;
2120}
2121
2122class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins,
2123                     string asm> :
2124  MUBUF <outs, ins, asm, []>,
2125  MUBUFe <op.SI>,
2126  SIMCInstr<opName, SISubtarget.SI> {
2127  let lds = 0;
2128}
2129
2130class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins,
2131                     string asm> :
2132  MUBUF <outs, ins, asm, []>,
2133  MUBUFe_vi <op.VI>,
2134  SIMCInstr<opName, SISubtarget.VI> {
2135  let lds = 0;
2136}
2137
2138multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm,
2139                    list<dag> pattern> {
2140
2141  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2142           MUBUFAddr64Table <0>;
2143
2144  let addr64 = 0, isCodeGenOnly = 0 in {
2145    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2146  }
2147
2148  def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2149}
2150
2151multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
2152                          dag ins, string asm, list<dag> pattern> {
2153
2154  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2155           MUBUFAddr64Table <1>;
2156
2157  let addr64 = 1, isCodeGenOnly = 0 in {
2158    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2159  }
2160
2161  // There is no VI version. If the pseudo is selected, it should be lowered
2162  // for VI appropriately.
2163}
2164
2165multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
2166                                string asm, list<dag> pattern, bit is_return> {
2167
2168  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2169           MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
2170           AtomicNoRet<NAME#"_OFFSET", is_return>;
2171
2172  let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
2173    let addr64 = 0 in {
2174      def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2175    }
2176
2177    def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2178  }
2179}
2180
2181multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
2182                                string asm, list<dag> pattern, bit is_return> {
2183
2184  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2185           MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
2186           AtomicNoRet<NAME#"_ADDR64", is_return>;
2187
2188  let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in {
2189    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2190  }
2191
2192  // There is no VI version. If the pseudo is selected, it should be lowered
2193  // for VI appropriately.
2194}
2195
2196multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
2197                         ValueType vt, SDPatternOperator atomic> {
2198
2199  let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in {
2200
2201    // No return variants
2202    let glc = 0 in {
2203
2204      defm _ADDR64 : MUBUFAtomicAddr64_m <
2205        op, name#"_addr64", (outs),
2206        (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
2207             SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2208        name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#"$slc", [], 0
2209      >;
2210
2211      defm _OFFSET : MUBUFAtomicOffset_m <
2212        op, name#"_offset", (outs),
2213        (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, mbuf_offset:$offset,
2214             slc:$slc),
2215        name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0
2216      >;
2217    } // glc = 0
2218
2219    // Variant that return values
2220    let glc = 1, Constraints = "$vdata = $vdata_in",
2221        DisableEncoding = "$vdata_in"  in {
2222
2223      defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
2224        op, name#"_rtn_addr64", (outs rc:$vdata),
2225        (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr,
2226             SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2227        name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc",
2228        [(set vt:$vdata,
2229         (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
2230	                            i16:$offset, i1:$slc), vt:$vdata_in))], 1
2231      >;
2232
2233      defm _RTN_OFFSET : MUBUFAtomicOffset_m <
2234        op, name#"_rtn_offset", (outs rc:$vdata),
2235        (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
2236             mbuf_offset:$offset, slc:$slc),
2237        name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc",
2238        [(set vt:$vdata,
2239         (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
2240                                    i1:$slc), vt:$vdata_in))], 1
2241      >;
2242
2243    } // glc = 1
2244
2245  } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
2246}
2247
2248multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
2249                              ValueType load_vt = i32,
2250                              SDPatternOperator ld = null_frag> {
2251
2252  let mayLoad = 1, mayStore = 0 in {
2253    let offen = 0, idxen = 0, vaddr = 0 in {
2254      defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
2255                           (ins SReg_128:$srsrc, SCSrc_32:$soffset,
2256                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2257                           name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2258                           [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
2259                                                     i32:$soffset, i16:$offset,
2260                                                     i1:$glc, i1:$slc, i1:$tfe)))]>;
2261    }
2262
2263    let offen = 1, idxen = 0  in {
2264      defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
2265                           (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2266                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
2267                           tfe:$tfe),
2268                           name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2269    }
2270
2271    let offen = 0, idxen = 1 in {
2272      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
2273                           (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2274                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2275                           slc:$slc, tfe:$tfe),
2276                           name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2277    }
2278
2279    let offen = 1, idxen = 1 in {
2280      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
2281                           (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2282                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2283                           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2284    }
2285
2286    let offen = 0, idxen = 0 in {
2287      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
2288                           (ins VReg_64:$vaddr, SReg_128:$srsrc,
2289                                SCSrc_32:$soffset, mbuf_offset:$offset,
2290				glc:$glc, slc:$slc, tfe:$tfe),
2291                           name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#
2292                                "$glc"#"$slc"#"$tfe",
2293                           [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
2294                                                  i64:$vaddr, i32:$soffset,
2295                                                  i16:$offset, i1:$glc, i1:$slc,
2296						  i1:$tfe)))]>;
2297    }
2298  }
2299}
2300
2301multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
2302                          ValueType store_vt = i32, SDPatternOperator st = null_frag> {
2303  let mayLoad = 0, mayStore = 1 in {
2304    defm : MUBUF_m <op, name, (outs),
2305                    (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2306                    mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
2307                    tfe:$tfe),
2308                    name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
2309                         "$glc"#"$slc"#"$tfe", []>;
2310
2311    let offen = 0, idxen = 0, vaddr = 0 in {
2312      defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
2313                              (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset,
2314                              mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2315                              name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2316                              [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
2317                                   i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
2318    } // offen = 0, idxen = 0, vaddr = 0
2319
2320    let offen = 1, idxen = 0  in {
2321      defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
2322                             (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2323                              SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2324                              slc:$slc, tfe:$tfe),
2325                             name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
2326                             "$glc"#"$slc"#"$tfe", []>;
2327    } // end offen = 1, idxen = 0
2328
2329    let offen = 0, idxen = 1 in {
2330      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs),
2331                           (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2332                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2333                           slc:$slc, tfe:$tfe),
2334                           name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2335    }
2336
2337    let offen = 1, idxen = 1 in {
2338      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs),
2339                           (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2340                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2341                           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2342    }
2343
2344    let offen = 0, idxen = 0 in {
2345      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
2346                                    (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
2347                                         SCSrc_32:$soffset,
2348                                         mbuf_offset:$offset, glc:$glc, slc:$slc,
2349                                         tfe:$tfe),
2350                                    name#" $vdata, $vaddr, $srsrc, $soffset addr64"#
2351                                         "$offset"#"$glc"#"$slc"#"$tfe",
2352                                    [(st store_vt:$vdata,
2353                                      (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr,
2354                                                   i32:$soffset, i16:$offset,
2355                                                   i1:$glc, i1:$slc, i1:$tfe))]>;
2356    }
2357  } // End mayLoad = 0, mayStore = 1
2358}
2359
2360class FLAT_Load_Helper <bits<7> op, string asm, RegisterClass regClass> :
2361      FLAT <op, (outs regClass:$vdst),
2362                (ins VReg_64:$addr, glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2363            asm#" $vdst, $addr"#"$glc"#"$slc"#"$tfe", []> {
2364  let data = 0;
2365  let mayLoad = 1;
2366}
2367
2368class FLAT_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
2369      FLAT <op, (outs), (ins vdataClass:$data, VReg_64:$addr,
2370                             glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2371          name#" $data, $addr"#"$glc"#"$slc"#"$tfe",
2372         []> {
2373
2374  let mayLoad = 0;
2375  let mayStore = 1;
2376
2377  // Encoding
2378  let vdst = 0;
2379}
2380
2381multiclass FLAT_ATOMIC <bits<7> op, string name, RegisterClass vdst_rc,
2382                        RegisterClass data_rc = vdst_rc> {
2383
2384  let mayLoad = 1, mayStore = 1 in {
2385    def "" : FLAT <op, (outs),
2386                  (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2387                       tfe_flat_atomic:$tfe),
2388                   name#" $addr, $data"#"$slc"#"$tfe", []>,
2389             AtomicNoRet <NAME, 0> {
2390      let glc = 0;
2391      let vdst = 0;
2392    }
2393
2394    def _RTN : FLAT <op, (outs vdst_rc:$vdst),
2395                     (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2396                          tfe_flat_atomic:$tfe),
2397                     name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>,
2398               AtomicNoRet <NAME, 1> {
2399      let glc = 1;
2400    }
2401  }
2402}
2403
2404class MIMG_Mask <string op, int channels> {
2405  string Op = op;
2406  int Channels = channels;
2407}
2408
2409class MIMG_NoSampler_Helper <bits<7> op, string asm,
2410                             RegisterClass dst_rc,
2411                             RegisterClass src_rc> : MIMG <
2412  op,
2413  (outs dst_rc:$vdata),
2414  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2415       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2416       SReg_256:$srsrc),
2417  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2418     #" $tfe, $lwe, $slc, $vaddr, $srsrc",
2419  []> {
2420  let ssamp = 0;
2421  let mayLoad = 1;
2422  let mayStore = 0;
2423  let hasPostISelHook = 1;
2424}
2425
2426multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
2427                                      RegisterClass dst_rc,
2428                                      int channels> {
2429  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32>,
2430            MIMG_Mask<asm#"_V1", channels>;
2431  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
2432            MIMG_Mask<asm#"_V2", channels>;
2433  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
2434            MIMG_Mask<asm#"_V4", channels>;
2435}
2436
2437multiclass MIMG_NoSampler <bits<7> op, string asm> {
2438  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
2439  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
2440  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
2441  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
2442}
2443
2444class MIMG_Sampler_Helper <bits<7> op, string asm,
2445                           RegisterClass dst_rc,
2446                           RegisterClass src_rc, int wqm> : MIMG <
2447  op,
2448  (outs dst_rc:$vdata),
2449  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2450       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2451       SReg_256:$srsrc, SReg_128:$ssamp),
2452  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2453     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2454  []> {
2455  let mayLoad = 1;
2456  let mayStore = 0;
2457  let hasPostISelHook = 1;
2458  let WQM = wqm;
2459}
2460
2461multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
2462                                    RegisterClass dst_rc,
2463                                    int channels, int wqm> {
2464  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2465            MIMG_Mask<asm#"_V1", channels>;
2466  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
2467            MIMG_Mask<asm#"_V2", channels>;
2468  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
2469            MIMG_Mask<asm#"_V4", channels>;
2470  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
2471            MIMG_Mask<asm#"_V8", channels>;
2472  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
2473            MIMG_Mask<asm#"_V16", channels>;
2474}
2475
2476multiclass MIMG_Sampler <bits<7> op, string asm> {
2477  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 0>;
2478  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 0>;
2479  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 0>;
2480  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 0>;
2481}
2482
2483multiclass MIMG_Sampler_WQM <bits<7> op, string asm> {
2484  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 1>;
2485  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 1>;
2486  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 1>;
2487  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 1>;
2488}
2489
2490class MIMG_Gather_Helper <bits<7> op, string asm,
2491                          RegisterClass dst_rc,
2492                          RegisterClass src_rc, int wqm> : MIMG <
2493  op,
2494  (outs dst_rc:$vdata),
2495  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2496       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2497       SReg_256:$srsrc, SReg_128:$ssamp),
2498  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2499     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2500  []> {
2501  let mayLoad = 1;
2502  let mayStore = 0;
2503
2504  // DMASK was repurposed for GATHER4. 4 components are always
2505  // returned and DMASK works like a swizzle - it selects
2506  // the component to fetch. The only useful DMASK values are
2507  // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
2508  // (red,red,red,red) etc.) The ISA document doesn't mention
2509  // this.
2510  // Therefore, disable all code which updates DMASK by setting these two:
2511  let MIMG = 0;
2512  let hasPostISelHook = 0;
2513  let WQM = wqm;
2514}
2515
2516multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
2517                                    RegisterClass dst_rc,
2518                                    int channels, int wqm> {
2519  def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2520            MIMG_Mask<asm#"_V1", channels>;
2521  def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
2522            MIMG_Mask<asm#"_V2", channels>;
2523  def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
2524            MIMG_Mask<asm#"_V4", channels>;
2525  def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
2526            MIMG_Mask<asm#"_V8", channels>;
2527  def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
2528            MIMG_Mask<asm#"_V16", channels>;
2529}
2530
2531multiclass MIMG_Gather <bits<7> op, string asm> {
2532  defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 0>;
2533  defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 0>;
2534  defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 0>;
2535  defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 0>;
2536}
2537
2538multiclass MIMG_Gather_WQM <bits<7> op, string asm> {
2539  defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 1>;
2540  defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 1>;
2541  defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 1>;
2542  defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 1>;
2543}
2544
2545//===----------------------------------------------------------------------===//
2546// Vector instruction mappings
2547//===----------------------------------------------------------------------===//
2548
2549// Maps an opcode in e32 form to its e64 equivalent
2550def getVOPe64 : InstrMapping {
2551  let FilterClass = "VOP";
2552  let RowFields = ["OpName"];
2553  let ColFields = ["Size"];
2554  let KeyCol = ["4"];
2555  let ValueCols = [["8"]];
2556}
2557
2558// Maps an opcode in e64 form to its e32 equivalent
2559def getVOPe32 : InstrMapping {
2560  let FilterClass = "VOP";
2561  let RowFields = ["OpName"];
2562  let ColFields = ["Size"];
2563  let KeyCol = ["8"];
2564  let ValueCols = [["4"]];
2565}
2566
2567def getMaskedMIMGOp : InstrMapping {
2568  let FilterClass = "MIMG_Mask";
2569  let RowFields = ["Op"];
2570  let ColFields = ["Channels"];
2571  let KeyCol = ["4"];
2572  let ValueCols = [["1"], ["2"], ["3"] ];
2573}
2574
2575// Maps an commuted opcode to its original version
2576def getCommuteOrig : InstrMapping {
2577  let FilterClass = "VOP2_REV";
2578  let RowFields = ["RevOp"];
2579  let ColFields = ["IsOrig"];
2580  let KeyCol = ["0"];
2581  let ValueCols = [["1"]];
2582}
2583
2584// Maps an original opcode to its commuted version
2585def getCommuteRev : InstrMapping {
2586  let FilterClass = "VOP2_REV";
2587  let RowFields = ["RevOp"];
2588  let ColFields = ["IsOrig"];
2589  let KeyCol = ["1"];
2590  let ValueCols = [["0"]];
2591}
2592
2593def getCommuteCmpOrig : InstrMapping {
2594  let FilterClass = "VOP2_REV";
2595  let RowFields = ["RevOp"];
2596  let ColFields = ["IsOrig"];
2597  let KeyCol = ["0"];
2598  let ValueCols = [["1"]];
2599}
2600
2601// Maps an original opcode to its commuted version
2602def getCommuteCmpRev : InstrMapping {
2603  let FilterClass = "VOP2_REV";
2604  let RowFields = ["RevOp"];
2605  let ColFields = ["IsOrig"];
2606  let KeyCol = ["1"];
2607  let ValueCols = [["0"]];
2608}
2609
2610
2611def getMCOpcodeGen : InstrMapping {
2612  let FilterClass = "SIMCInstr";
2613  let RowFields = ["PseudoInstr"];
2614  let ColFields = ["Subtarget"];
2615  let KeyCol = [!cast<string>(SISubtarget.NONE)];
2616  let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]];
2617}
2618
2619def getAddr64Inst : InstrMapping {
2620  let FilterClass = "MUBUFAddr64Table";
2621  let RowFields = ["OpName"];
2622  let ColFields = ["IsAddr64"];
2623  let KeyCol = ["0"];
2624  let ValueCols = [["1"]];
2625}
2626
2627// Maps an atomic opcode to its version with a return value.
2628def getAtomicRetOp : InstrMapping {
2629  let FilterClass = "AtomicNoRet";
2630  let RowFields = ["NoRetOp"];
2631  let ColFields = ["IsRet"];
2632  let KeyCol = ["0"];
2633  let ValueCols = [["1"]];
2634}
2635
2636// Maps an atomic opcode to its returnless version.
2637def getAtomicNoRetOp : InstrMapping {
2638  let FilterClass = "AtomicNoRet";
2639  let RowFields = ["NoRetOp"];
2640  let ColFields = ["IsRet"];
2641  let KeyCol = ["1"];
2642  let ValueCols = [["0"]];
2643}
2644
2645include "SIInstructions.td"
2646include "CIInstructions.td"
2647include "VIInstructions.td"
2648