1//===-- BUFInstructions.td - Buffer Instruction Definitions ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9def MUBUFAddr64 : ComplexPattern<i64, 4, "SelectMUBUFAddr64">;
10def MUBUFOffset : ComplexPattern<i64, 3, "SelectMUBUFOffset">;
11
12def MUBUFScratchOffen : ComplexPattern<i64, 4, "SelectMUBUFScratchOffen", [], [SDNPWantParent]>;
13def MUBUFScratchOffset : ComplexPattern<i64, 3, "SelectMUBUFScratchOffset", [], [SDNPWantParent], 20>;
14
15def BUFAddrKind {
16  int Offset = 0;
17  int OffEn  = 1;
18  int IdxEn  = 2;
19  int BothEn = 3;
20  int Addr64 = 4;
21}
22
23class getAddrName<int addrKind> {
24  string ret =
25    !if(!eq(addrKind, BUFAddrKind.Offset), "offset",
26    !if(!eq(addrKind, BUFAddrKind.OffEn),  "offen",
27    !if(!eq(addrKind, BUFAddrKind.IdxEn),  "idxen",
28    !if(!eq(addrKind, BUFAddrKind.BothEn), "bothen",
29    !if(!eq(addrKind, BUFAddrKind.Addr64), "addr64",
30    "")))));
31}
32
33class MUBUFAddr64Table <bit is_addr64, string Name> {
34  bit IsAddr64 = is_addr64;
35  string OpName = Name;
36}
37
38class MUBUFLdsTable <bit is_lds, string Name> {
39  bit IsLds = is_lds;
40  string OpName = Name;
41}
42
43class MTBUFAddr64Table <bit is_addr64, string Name> {
44  bit IsAddr64 = is_addr64;
45  string OpName = Name;
46}
47
48//===----------------------------------------------------------------------===//
49// MTBUF classes
50//===----------------------------------------------------------------------===//
51
52class MTBUFGetBaseOpcode<string Op> {
53  string ret = !subst("FORMAT_XY", "FORMAT_X",
54    !subst("FORMAT_XYZ", "FORMAT_X",
55    !subst("FORMAT_XYZW", "FORMAT_X", Op)));
56}
57
58class getMTBUFElements<string Op> {
59  int ret = 1;
60}
61
62
63class MTBUF_Pseudo <string opName, dag outs, dag ins,
64                    string asmOps, list<dag> pattern=[]> :
65  InstSI<outs, ins, "", pattern>,
66  SIMCInstr<opName, SIEncodingFamily.NONE> {
67
68  let isPseudo = 1;
69  let isCodeGenOnly = 1;
70  let Size = 8;
71  let UseNamedOperandTable = 1;
72
73  string Mnemonic = opName;
74  string AsmOperands = asmOps;
75
76  Instruction Opcode = !cast<Instruction>(NAME);
77  Instruction BaseOpcode = !cast<Instruction>(MTBUFGetBaseOpcode<NAME>.ret);
78
79  let VM_CNT = 1;
80  let EXP_CNT = 1;
81  let MTBUF = 1;
82  let Uses = [EXEC];
83  let hasSideEffects = 0;
84  let SchedRW = [WriteVMEM];
85
86  let AsmMatchConverter = "cvtMtbuf";
87
88  bits<1> offen       = 0;
89  bits<1> idxen       = 0;
90  bits<1> addr64      = 0;
91  bits<1> has_vdata   = 1;
92  bits<1> has_vaddr   = 1;
93  bits<1> has_glc     = 1;
94  bits<1> has_dlc     = 1;
95  bits<1> glc_value   = 0; // the value for glc if no such operand
96  bits<1> dlc_value   = 0; // the value for dlc if no such operand
97  bits<1> has_srsrc   = 1;
98  bits<1> has_soffset = 1;
99  bits<1> has_offset  = 1;
100  bits<1> has_slc     = 1;
101  bits<1> has_tfe     = 1;
102  bits<4> elements    = 0;
103  bits<1> has_sccb    = 1;
104  bits<1> sccb_value  = 0;
105}
106
107class MTBUF_Real <MTBUF_Pseudo ps> :
108  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []> {
109
110  let isPseudo = 0;
111  let isCodeGenOnly = 0;
112
113  let VM_CNT = 1;
114  let EXP_CNT = 1;
115  let MTBUF = 1;
116
117  // copy relevant pseudo op flags
118  let UseNamedOperandTable = ps.UseNamedOperandTable;
119  let SubtargetPredicate = ps.SubtargetPredicate;
120  let AsmMatchConverter  = ps.AsmMatchConverter;
121  let Constraints        = ps.Constraints;
122  let DisableEncoding    = ps.DisableEncoding;
123  let TSFlags            = ps.TSFlags;
124  let SchedRW            = ps.SchedRW;
125  let mayLoad            = ps.mayLoad;
126  let mayStore           = ps.mayStore;
127  let IsAtomicRet        = ps.IsAtomicRet;
128  let IsAtomicNoRet      = ps.IsAtomicNoRet;
129
130  bits<12> offset;
131  bits<5>  cpol;
132  bits<7>  format;
133  bits<8>  vaddr;
134  bits<10> vdata;
135  bits<7>  srsrc;
136  bits<1>  tfe;
137  bits<8>  soffset;
138
139  bits<4> dfmt = format{3-0};
140  bits<3> nfmt = format{6-4};
141
142  // GFX90A+ only: instruction uses AccVGPR for data
143  // Bit superceedes tfe.
144  bits<1> acc = !if(ps.has_vdata, vdata{9}, 0);
145}
146
147class getMTBUFInsDA<list<RegisterClass> vdataList,
148                    list<RegisterClass> vaddrList=[]> {
149  RegisterClass vdataClass = !if(!empty(vdataList), ?, !head(vdataList));
150  RegisterClass vaddrClass = !if(!empty(vaddrList), ?, !head(vaddrList));
151  RegisterOperand vdata_op = getLdStRegisterOperand<vdataClass>.ret;
152  dag InsNoData = !if(!empty(vaddrList),
153    (ins                    SReg_128:$srsrc, SCSrc_b32:$soffset,
154         offset:$offset, FORMAT:$format, CPol:$cpol, TFE:$tfe, SWZ:$swz),
155    (ins vaddrClass:$vaddr, SReg_128:$srsrc, SCSrc_b32:$soffset,
156         offset:$offset, FORMAT:$format, CPol:$cpol, TFE:$tfe, SWZ:$swz)
157  );
158  dag InsData = !if(!empty(vaddrList),
159    (ins vdata_op:$vdata,                    SReg_128:$srsrc,
160         SCSrc_b32:$soffset, offset:$offset, FORMAT:$format, CPol:$cpol,
161         TFE:$tfe, SWZ:$swz),
162    (ins vdata_op:$vdata, vaddrClass:$vaddr, SReg_128:$srsrc,
163         SCSrc_b32:$soffset, offset:$offset, FORMAT:$format, CPol:$cpol,
164         TFE:$tfe, SWZ:$swz)
165  );
166  dag ret = !if(!empty(vdataList), InsNoData, InsData);
167}
168
169class getMTBUFIns<int addrKind, list<RegisterClass> vdataList=[]> {
170  dag ret =
171    !if(!eq(addrKind, BUFAddrKind.Offset), getMTBUFInsDA<vdataList>.ret,
172    !if(!eq(addrKind, BUFAddrKind.OffEn),  getMTBUFInsDA<vdataList, [VGPR_32]>.ret,
173    !if(!eq(addrKind, BUFAddrKind.IdxEn),  getMTBUFInsDA<vdataList, [VGPR_32]>.ret,
174    !if(!eq(addrKind, BUFAddrKind.BothEn), getMTBUFInsDA<vdataList, [VReg_64]>.ret,
175    !if(!eq(addrKind, BUFAddrKind.Addr64), getMTBUFInsDA<vdataList, [VReg_64]>.ret,
176    (ins))))));
177}
178
179class getMTBUFAsmOps<int addrKind> {
180  string Pfx =
181    !if(!eq(addrKind, BUFAddrKind.Offset), "off, $srsrc,$format $soffset",
182    !if(!eq(addrKind, BUFAddrKind.OffEn),
183            "$vaddr, $srsrc,$format $soffset offen",
184    !if(!eq(addrKind, BUFAddrKind.IdxEn),
185            "$vaddr, $srsrc,$format $soffset idxen",
186    !if(!eq(addrKind, BUFAddrKind.BothEn),
187            "$vaddr, $srsrc,$format $soffset idxen offen",
188    !if(!eq(addrKind, BUFAddrKind.Addr64),
189            "$vaddr, $srsrc,$format $soffset addr64",
190    "")))));
191  string ret = Pfx # "$offset";
192}
193
194class MTBUF_SetupAddr<int addrKind> {
195  bits<1> offen  = !or(!eq(addrKind, BUFAddrKind.OffEn),
196                       !eq(addrKind, BUFAddrKind.BothEn));
197
198  bits<1> idxen  = !or(!eq(addrKind, BUFAddrKind.IdxEn),
199                       !eq(addrKind, BUFAddrKind.BothEn));
200
201  bits<1> addr64 = !eq(addrKind, BUFAddrKind.Addr64);
202
203  bits<1> has_vaddr = !ne(addrKind, BUFAddrKind.Offset);
204}
205
206class MTBUF_Load_Pseudo <string opName,
207                         int addrKind,
208                         RegisterClass vdataClass,
209                         int elems,
210                         list<dag> pattern=[],
211                         // Workaround bug bz30254
212                         int addrKindCopy = addrKind>
213  : MTBUF_Pseudo<opName,
214                 (outs getLdStRegisterOperand<vdataClass>.ret:$vdata),
215                 getMTBUFIns<addrKindCopy>.ret,
216                 " $vdata, " # getMTBUFAsmOps<addrKindCopy>.ret # "$cpol$tfe$swz",
217                 pattern>,
218    MTBUF_SetupAddr<addrKindCopy> {
219  let PseudoInstr = opName # "_" # getAddrName<addrKindCopy>.ret;
220  let mayLoad = 1;
221  let mayStore = 0;
222  let elements = elems;
223}
224
225multiclass MTBUF_Pseudo_Loads<string opName, RegisterClass vdataClass,
226                              int elems, ValueType load_vt = i32,
227                              SDPatternOperator ld = null_frag> {
228
229  def _OFFSET : MTBUF_Load_Pseudo <opName, BUFAddrKind.Offset, vdataClass, elems>,
230                MTBUFAddr64Table<0, NAME>;
231
232  def _ADDR64 : MTBUF_Load_Pseudo <opName, BUFAddrKind.Addr64, vdataClass, elems>,
233                MTBUFAddr64Table<1, NAME>;
234
235  def _OFFEN  : MTBUF_Load_Pseudo <opName, BUFAddrKind.OffEn, vdataClass, elems>;
236  def _IDXEN  : MTBUF_Load_Pseudo <opName, BUFAddrKind.IdxEn, vdataClass, elems>;
237  def _BOTHEN : MTBUF_Load_Pseudo <opName, BUFAddrKind.BothEn, vdataClass, elems>;
238
239  let DisableWQM = 1 in {
240    def _OFFSET_exact : MTBUF_Load_Pseudo <opName, BUFAddrKind.Offset, vdataClass, elems>;
241    def _OFFEN_exact  : MTBUF_Load_Pseudo <opName, BUFAddrKind.OffEn, vdataClass, elems>;
242    def _IDXEN_exact  : MTBUF_Load_Pseudo <opName, BUFAddrKind.IdxEn, vdataClass, elems>;
243    def _BOTHEN_exact : MTBUF_Load_Pseudo <opName, BUFAddrKind.BothEn, vdataClass, elems>;
244  }
245}
246
247class MTBUF_Store_Pseudo <string opName,
248                          int addrKind,
249                          RegisterClass vdataClass,
250                          int elems,
251                          list<dag> pattern=[],
252                          // Workaround bug bz30254
253                          int addrKindCopy = addrKind,
254                          RegisterClass vdataClassCopy = vdataClass>
255  : MTBUF_Pseudo<opName,
256                 (outs),
257                 getMTBUFIns<addrKindCopy, [vdataClassCopy]>.ret,
258                 " $vdata, " # getMTBUFAsmOps<addrKindCopy>.ret # "$cpol$tfe$swz",
259                 pattern>,
260    MTBUF_SetupAddr<addrKindCopy> {
261  let PseudoInstr = opName # "_" # getAddrName<addrKindCopy>.ret;
262  let mayLoad = 0;
263  let mayStore = 1;
264  let elements = elems;
265}
266
267multiclass MTBUF_Pseudo_Stores<string opName, RegisterClass vdataClass,
268                               int elems, ValueType store_vt = i32,
269                               SDPatternOperator st = null_frag> {
270
271  def _OFFSET : MTBUF_Store_Pseudo <opName, BUFAddrKind.Offset, vdataClass, elems>,
272    MTBUFAddr64Table<0, NAME>;
273
274  def _ADDR64 : MTBUF_Store_Pseudo <opName, BUFAddrKind.Addr64, vdataClass, elems>,
275    MTBUFAddr64Table<1, NAME>;
276
277  def _OFFEN  : MTBUF_Store_Pseudo <opName, BUFAddrKind.OffEn, vdataClass, elems>;
278  def _IDXEN  : MTBUF_Store_Pseudo <opName, BUFAddrKind.IdxEn, vdataClass, elems>;
279  def _BOTHEN : MTBUF_Store_Pseudo <opName, BUFAddrKind.BothEn, vdataClass, elems>;
280
281  let DisableWQM = 1 in {
282    def _OFFSET_exact : MTBUF_Store_Pseudo <opName, BUFAddrKind.Offset, vdataClass, elems>;
283    def _OFFEN_exact  : MTBUF_Store_Pseudo <opName, BUFAddrKind.OffEn, vdataClass, elems>;
284    def _IDXEN_exact  : MTBUF_Store_Pseudo <opName, BUFAddrKind.IdxEn, vdataClass, elems>;
285    def _BOTHEN_exact : MTBUF_Store_Pseudo <opName, BUFAddrKind.BothEn, vdataClass, elems>;
286  }
287}
288
289
290//===----------------------------------------------------------------------===//
291// MUBUF classes
292//===----------------------------------------------------------------------===//
293
294class MUBUFGetBaseOpcode<string Op> {
295  string ret = !subst("DWORDX2", "DWORD",
296    !subst("DWORDX3", "DWORD",
297    !subst("DWORDX4", "DWORD", Op)));
298}
299
300class MUBUF_Pseudo <string opName, dag outs, dag ins,
301                    string asmOps, list<dag> pattern=[]> :
302  InstSI<outs, ins, "", pattern>,
303  SIMCInstr<opName, SIEncodingFamily.NONE> {
304
305  let isPseudo = 1;
306  let isCodeGenOnly = 1;
307  let Size = 8;
308  let UseNamedOperandTable = 1;
309
310  string Mnemonic = opName;
311  string AsmOperands = asmOps;
312
313  Instruction Opcode = !cast<Instruction>(NAME);
314  Instruction BaseOpcode = !cast<Instruction>(MUBUFGetBaseOpcode<NAME>.ret);
315
316  let VM_CNT = 1;
317  let EXP_CNT = 1;
318  let MUBUF = 1;
319  let Uses = [EXEC];
320  let hasSideEffects = 0;
321  let SchedRW = [WriteVMEM];
322
323  let AsmMatchConverter = "cvtMubuf";
324
325  bits<1> offen       = 0;
326  bits<1> idxen       = 0;
327  bits<1> addr64      = 0;
328  bits<1> lds         = 0;
329  bits<1> has_vdata   = 1;
330  bits<1> has_vaddr   = 1;
331  bits<1> has_glc     = 1;
332  bits<1> has_dlc     = 1;
333  bits<1> glc_value   = 0; // the value for glc if no such operand
334  bits<1> dlc_value   = 0; // the value for dlc if no such operand
335  bits<1> has_srsrc   = 1;
336  bits<1> has_soffset = 1;
337  bits<1> has_offset  = 1;
338  bits<1> has_slc     = 1;
339  bits<1> has_tfe     = 1;
340  bits<4> elements    = 0;
341  bits<1> has_sccb    = 1;
342  bits<1> sccb_value  = 0;
343  bits<1> IsBufferInv = 0;
344}
345
346class MUBUF_Real <MUBUF_Pseudo ps> :
347  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []> {
348
349  let isPseudo = 0;
350  let isCodeGenOnly = 0;
351
352  let VM_CNT = 1;
353  let EXP_CNT = 1;
354  let MUBUF = 1;
355
356  // copy relevant pseudo op flags
357  let SubtargetPredicate   = ps.SubtargetPredicate;
358  let AsmMatchConverter    = ps.AsmMatchConverter;
359  let OtherPredicates      = ps.OtherPredicates;
360  let Constraints          = ps.Constraints;
361  let DisableEncoding      = ps.DisableEncoding;
362  let TSFlags              = ps.TSFlags;
363  let UseNamedOperandTable = ps.UseNamedOperandTable;
364  let SchedRW              = ps.SchedRW;
365  let mayLoad              = ps.mayLoad;
366  let mayStore             = ps.mayStore;
367  let IsAtomicRet          = ps.IsAtomicRet;
368  let IsAtomicNoRet        = ps.IsAtomicNoRet;
369
370  bits<12> offset;
371  bits<5>  cpol;
372  bits<8>  vaddr;
373  bits<10> vdata;
374  bits<7>  srsrc;
375  bits<1>  tfe;
376  bits<8>  soffset;
377
378  // GFX90A+ only: instruction uses AccVGPR for data
379  // Bit superceedes tfe.
380  bits<1> acc = !if(ps.has_vdata, vdata{9}, 0);
381}
382
383
384// For cache invalidation instructions.
385class MUBUF_Invalidate <string opName, SDPatternOperator node = null_frag> :
386  MUBUF_Pseudo<opName, (outs), (ins), "", [(node)]> {
387
388  let AsmMatchConverter = "";
389
390  let hasSideEffects = 1;
391  let mayLoad = 0;
392  let mayStore = 0;
393
394  let IsBufferInv = 1;
395  // Set everything else to 0.
396  let offen       = 0;
397  let idxen       = 0;
398  let addr64      = 0;
399  let has_vdata   = 0;
400  let has_vaddr   = 0;
401  let has_glc     = 0;
402  let has_dlc     = 0;
403  let glc_value   = 0;
404  let dlc_value   = 0;
405  let has_srsrc   = 0;
406  let has_soffset = 0;
407  let has_offset  = 0;
408  let has_slc     = 0;
409  let has_tfe     = 0;
410  let has_sccb    = 0;
411  let sccb_value  = 0;
412}
413
414class getMUBUFInsDA<list<RegisterClass> vdataList,
415                    list<RegisterClass> vaddrList=[],
416                    bit isLds = 0> {
417  RegisterClass vdataClass = !if(!empty(vdataList), ?, !head(vdataList));
418  RegisterClass vaddrClass = !if(!empty(vaddrList), ?, !head(vaddrList));
419  RegisterOperand vdata_op = getLdStRegisterOperand<vdataClass>.ret;
420  dag InsNoData = !if(!empty(vaddrList),
421    (ins                    SReg_128:$srsrc, SCSrc_b32:$soffset,
422         offset:$offset, CPol_0:$cpol),
423    (ins vaddrClass:$vaddr, SReg_128:$srsrc, SCSrc_b32:$soffset,
424         offset:$offset, CPol_0:$cpol)
425  );
426  dag InsData = !if(!empty(vaddrList),
427    (ins vdata_op:$vdata,                    SReg_128:$srsrc,
428         SCSrc_b32:$soffset, offset:$offset, CPol_0:$cpol),
429    (ins vdata_op:$vdata, vaddrClass:$vaddr, SReg_128:$srsrc,
430         SCSrc_b32:$soffset, offset:$offset, CPol_0:$cpol)
431  );
432  dag ret = !con(
433              !if(!empty(vdataList), InsNoData, InsData),
434              !if(isLds, (ins SWZ_0:$swz), (ins TFE_0:$tfe, SWZ_0:$swz))
435             );
436}
437
438class getMUBUFElements<ValueType vt> {
439  // eq does not support ValueType for some reason.
440  string vtAsStr = !cast<string>(vt);
441
442  int ret =
443    !if(!eq(vtAsStr, "f16"), 1,
444      !if(!eq(vtAsStr, "v2f16"), 2,
445        !if(!eq(vtAsStr, "v3f16"), 3,
446          !if(!eq(vtAsStr, "v4f16"), 4,
447            !if(!eq(vt.Size, 32), 1,
448              !if(!eq(vt.Size, 64), 2,
449                !if(!eq(vt.Size, 96), 3,
450                  !if(!eq(vt.Size, 128), 4, 0)
451                )
452              )
453            )
454          )
455        )
456      )
457    );
458}
459
460class getMUBUFIns<int addrKind, list<RegisterClass> vdataList=[], bit isLds = 0> {
461  dag ret =
462    !if(!eq(addrKind, BUFAddrKind.Offset), getMUBUFInsDA<vdataList, [], isLds>.ret,
463    !if(!eq(addrKind, BUFAddrKind.OffEn),  getMUBUFInsDA<vdataList, [VGPR_32], isLds>.ret,
464    !if(!eq(addrKind, BUFAddrKind.IdxEn),  getMUBUFInsDA<vdataList, [VGPR_32], isLds>.ret,
465    !if(!eq(addrKind, BUFAddrKind.BothEn), getMUBUFInsDA<vdataList, [VReg_64], isLds>.ret,
466    !if(!eq(addrKind, BUFAddrKind.Addr64), getMUBUFInsDA<vdataList, [VReg_64], isLds>.ret,
467    (ins))))));
468}
469
470class getMUBUFAsmOps<int addrKind> {
471  string Pfx =
472    !if(!eq(addrKind, BUFAddrKind.Offset), "off, $srsrc, $soffset",
473    !if(!eq(addrKind, BUFAddrKind.OffEn),  "$vaddr, $srsrc, $soffset offen",
474    !if(!eq(addrKind, BUFAddrKind.IdxEn),  "$vaddr, $srsrc, $soffset idxen",
475    !if(!eq(addrKind, BUFAddrKind.BothEn), "$vaddr, $srsrc, $soffset idxen offen",
476    !if(!eq(addrKind, BUFAddrKind.Addr64), "$vaddr, $srsrc, $soffset addr64",
477    "")))));
478  string ret = Pfx # "$offset";
479}
480
481class MUBUF_SetupAddr<int addrKind> {
482  bits<1> offen  = !or(!eq(addrKind, BUFAddrKind.OffEn),
483                       !eq(addrKind, BUFAddrKind.BothEn));
484
485  bits<1> idxen  = !or(!eq(addrKind, BUFAddrKind.IdxEn),
486                       !eq(addrKind, BUFAddrKind.BothEn));
487
488  bits<1> addr64 = !eq(addrKind, BUFAddrKind.Addr64);
489
490  bits<1> has_vaddr = !ne(addrKind, BUFAddrKind.Offset);
491}
492
493class MUBUF_Load_Pseudo <string opName,
494                         int addrKind,
495                         ValueType vdata_vt,
496                         bit HasTiedDest = 0,
497                         bit isLds = 0,
498                         list<dag> pattern=[],
499                         // Workaround bug bz30254
500                         int addrKindCopy = addrKind,
501                         RegisterClass vdata_rc = getVregSrcForVT<vdata_vt>.ret,
502                         RegisterOperand vdata_op = getLdStRegisterOperand<vdata_rc>.ret>
503  : MUBUF_Pseudo<opName,
504                 (outs vdata_op:$vdata),
505                 !con(getMUBUFIns<addrKindCopy, [], isLds>.ret,
506                      !if(HasTiedDest, (ins vdata_op:$vdata_in), (ins))),
507                 " $vdata, " # getMUBUFAsmOps<addrKindCopy>.ret # "$cpol" #
508                   !if(isLds, " lds", "$tfe") # "$swz",
509                 pattern>,
510    MUBUF_SetupAddr<addrKindCopy> {
511  let PseudoInstr = opName # !if(isLds, "_lds", "") #
512                    "_" # getAddrName<addrKindCopy>.ret;
513  let AsmMatchConverter = !if(isLds, "cvtMubufLds", "cvtMubuf");
514
515  let Constraints = !if(HasTiedDest, "$vdata = $vdata_in", "");
516  let mayLoad = 1;
517  let mayStore = 0;
518  let maybeAtomic = 1;
519  let Uses = !if(isLds, [EXEC, M0], [EXEC]);
520  let has_tfe = !not(isLds);
521  let lds = isLds;
522  let elements = getMUBUFElements<vdata_vt>.ret;
523}
524
525class MUBUF_Offset_Load_Pat <Instruction inst, ValueType load_vt = i32, SDPatternOperator ld = null_frag> : Pat <
526  (load_vt (ld (MUBUFOffset v4i32:$srsrc, i32:$soffset, i16:$offset))),
527  (load_vt (inst v4i32:$srsrc, i32:$soffset, i16:$offset))
528>;
529
530class MUBUF_Addr64_Load_Pat <Instruction inst,
531                            ValueType load_vt = i32,
532                            SDPatternOperator ld = null_frag> : Pat <
533  (load_vt (ld (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i32:$soffset, i16:$offset))),
534  (load_vt (inst i64:$vaddr, v4i32:$srsrc, i32:$soffset, i16:$offset))
535>;
536
537multiclass MUBUF_Pseudo_Load_Pats<string BaseInst, ValueType load_vt = i32, SDPatternOperator ld = null_frag> {
538  def : MUBUF_Offset_Load_Pat<!cast<Instruction>(BaseInst#"_OFFSET"), load_vt, ld>;
539  def : MUBUF_Addr64_Load_Pat<!cast<Instruction>(BaseInst#"_ADDR64"), load_vt, ld>;
540}
541
542
543// FIXME: tfe can't be an operand because it requires a separate
544// opcode because it needs an N+1 register class dest register.
545multiclass MUBUF_Pseudo_Loads<string opName,
546                              ValueType load_vt = i32,
547                              SDPatternOperator ld = null_frag,
548                              bit TiedDest = 0,
549                              bit isLds = 0> {
550
551  defvar legal_load_vt = !if(!eq(!cast<string>(load_vt), !cast<string>(v3f16)), v4f16, load_vt);
552
553  def _OFFSET : MUBUF_Load_Pseudo <opName, BUFAddrKind.Offset, legal_load_vt, TiedDest, isLds>,
554    MUBUFAddr64Table<0, NAME # !if(isLds, "_LDS", "")>;
555
556  def _ADDR64 : MUBUF_Load_Pseudo <opName, BUFAddrKind.Addr64, legal_load_vt, TiedDest, isLds>,
557    MUBUFAddr64Table<1, NAME # !if(isLds, "_LDS", "")>;
558
559  def _OFFEN  : MUBUF_Load_Pseudo <opName, BUFAddrKind.OffEn, legal_load_vt, TiedDest, isLds>;
560  def _IDXEN  : MUBUF_Load_Pseudo <opName, BUFAddrKind.IdxEn, legal_load_vt, TiedDest, isLds>;
561  def _BOTHEN : MUBUF_Load_Pseudo <opName, BUFAddrKind.BothEn, legal_load_vt, TiedDest, isLds>;
562
563  let DisableWQM = 1 in {
564    def _OFFSET_exact : MUBUF_Load_Pseudo <opName, BUFAddrKind.Offset, legal_load_vt, TiedDest, isLds>;
565    def _OFFEN_exact  : MUBUF_Load_Pseudo <opName, BUFAddrKind.OffEn, legal_load_vt, TiedDest, isLds>;
566    def _IDXEN_exact  : MUBUF_Load_Pseudo <opName, BUFAddrKind.IdxEn, legal_load_vt, TiedDest, isLds>;
567    def _BOTHEN_exact : MUBUF_Load_Pseudo <opName, BUFAddrKind.BothEn, legal_load_vt, TiedDest, isLds>;
568  }
569}
570
571multiclass MUBUF_Pseudo_Loads_Lds<string opName, ValueType load_vt = i32,
572                                  SDPatternOperator ld_nolds = null_frag,
573                                  SDPatternOperator ld_lds = null_frag> {
574  defm NAME : MUBUF_Pseudo_Loads<opName, load_vt, ld_nolds>;
575  defm _LDS : MUBUF_Pseudo_Loads<opName, load_vt, ld_lds, 0, 1>;
576}
577
578class MUBUF_Store_Pseudo <string opName,
579                          int addrKind,
580                          ValueType store_vt,
581                          list<dag> pattern=[],
582                          // Workaround bug bz30254
583                          int addrKindCopy = addrKind>
584  : MUBUF_Pseudo<opName,
585                 (outs),
586                 getMUBUFIns<addrKindCopy, [getVregSrcForVT<store_vt>.ret]>.ret,
587                 " $vdata, " # getMUBUFAsmOps<addrKindCopy>.ret # "$cpol$tfe$swz",
588                 pattern>,
589    MUBUF_SetupAddr<addrKindCopy> {
590  let PseudoInstr = opName # "_" # getAddrName<addrKindCopy>.ret;
591  let mayLoad = 0;
592  let mayStore = 1;
593  let maybeAtomic = 1;
594  let elements = getMUBUFElements<store_vt>.ret;
595}
596
597multiclass MUBUF_Pseudo_Stores<string opName,
598                               ValueType store_vt = i32,
599                               SDPatternOperator st = null_frag> {
600
601  defvar legal_store_vt = !if(!eq(!cast<string>(store_vt), !cast<string>(v3f16)), v4f16, store_vt);
602
603  def _OFFSET : MUBUF_Store_Pseudo <opName, BUFAddrKind.Offset, legal_store_vt,
604    [(st legal_store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
605                                             i16:$offset))]>,
606    MUBUFAddr64Table<0, NAME>;
607
608  def _ADDR64 : MUBUF_Store_Pseudo <opName, BUFAddrKind.Addr64, legal_store_vt,
609    [(st legal_store_vt:$vdata, (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i32:$soffset,
610                                             i16:$offset))]>,
611    MUBUFAddr64Table<1, NAME>;
612
613  def _OFFEN  : MUBUF_Store_Pseudo <opName, BUFAddrKind.OffEn, legal_store_vt>;
614  def _IDXEN  : MUBUF_Store_Pseudo <opName, BUFAddrKind.IdxEn, legal_store_vt>;
615  def _BOTHEN : MUBUF_Store_Pseudo <opName, BUFAddrKind.BothEn, legal_store_vt>;
616
617  let DisableWQM = 1 in {
618    def _OFFSET_exact : MUBUF_Store_Pseudo <opName, BUFAddrKind.Offset, legal_store_vt>;
619    def _OFFEN_exact  : MUBUF_Store_Pseudo <opName, BUFAddrKind.OffEn, legal_store_vt>;
620    def _IDXEN_exact  : MUBUF_Store_Pseudo <opName, BUFAddrKind.IdxEn, legal_store_vt>;
621    def _BOTHEN_exact : MUBUF_Store_Pseudo <opName, BUFAddrKind.BothEn, legal_store_vt>;
622  }
623}
624
625class MUBUF_Pseudo_Store_Lds<string opName>
626  : MUBUF_Pseudo<opName,
627                 (outs),
628                 (ins SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, CPol:$cpol, SWZ:$swz),
629                 " $srsrc, $soffset$offset lds$cpol$swz"> {
630  let mayLoad = 0;
631  let mayStore = 1;
632  let maybeAtomic = 1;
633
634  let has_vdata = 0;
635  let has_vaddr = 0;
636  let has_tfe = 0;
637  let lds = 1;
638
639  let Uses = [EXEC, M0];
640  let AsmMatchConverter = "cvtMubufLds";
641}
642
643class getMUBUFAtomicInsDA<RegisterClass vdataClass, bit vdata_in,
644                          list<RegisterClass> vaddrList=[]> {
645  RegisterClass vaddrClass = !if(!empty(vaddrList), ?, !head(vaddrList));
646  RegisterOperand vdata_op = getLdStRegisterOperand<vdataClass>.ret;
647  dag ret = !if(vdata_in,
648    !if(!empty(vaddrList),
649      (ins vdata_op:$vdata_in,
650           SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, CPol_GLC1:$cpol),
651      (ins vdata_op:$vdata_in, vaddrClass:$vaddr,
652           SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, CPol_GLC1:$cpol)
653    ),
654    !if(!empty(vaddrList),
655      (ins vdata_op:$vdata,
656           SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, CPol_0:$cpol),
657      (ins vdata_op:$vdata, vaddrClass:$vaddr,
658           SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, CPol_0:$cpol)
659  ));
660}
661
662class getMUBUFAtomicIns<int addrKind,
663                        RegisterClass vdataClass,
664                        bit vdata_in,
665                        // Workaround bug bz30254
666                        RegisterClass vdataClassCopy=vdataClass> {
667  dag ret =
668    !if(!eq(addrKind, BUFAddrKind.Offset),
669            getMUBUFAtomicInsDA<vdataClassCopy, vdata_in>.ret,
670    !if(!eq(addrKind, BUFAddrKind.OffEn),
671            getMUBUFAtomicInsDA<vdataClassCopy, vdata_in, [VGPR_32]>.ret,
672    !if(!eq(addrKind, BUFAddrKind.IdxEn),
673            getMUBUFAtomicInsDA<vdataClassCopy, vdata_in, [VGPR_32]>.ret,
674    !if(!eq(addrKind, BUFAddrKind.BothEn),
675            getMUBUFAtomicInsDA<vdataClassCopy, vdata_in, [VReg_64]>.ret,
676    !if(!eq(addrKind, BUFAddrKind.Addr64),
677            getMUBUFAtomicInsDA<vdataClassCopy, vdata_in, [VReg_64]>.ret,
678    (ins))))));
679}
680
681class MUBUF_Atomic_Pseudo<string opName,
682                          int addrKind,
683                          dag outs,
684                          dag ins,
685                          string asmOps,
686                          list<dag> pattern=[],
687                          // Workaround bug bz30254
688                          int addrKindCopy = addrKind>
689  : MUBUF_Pseudo<opName, outs, ins, asmOps, pattern>,
690    MUBUF_SetupAddr<addrKindCopy> {
691  let mayStore = 1;
692  let mayLoad = 1;
693  let hasPostISelHook = 1;
694  let hasSideEffects = 1;
695  let DisableWQM = 1;
696  let has_glc = 0;
697  let has_dlc = 0;
698  let has_tfe = 0;
699  let has_sccb = 1;
700  let maybeAtomic = 1;
701  let AsmMatchConverter = "cvtMubufAtomic";
702}
703
704class MUBUF_AtomicNoRet_Pseudo<string opName, int addrKind,
705                               RegisterClass vdataClass,
706                               list<dag> pattern=[],
707                               // Workaround bug bz30254
708                               int addrKindCopy = addrKind,
709                               RegisterClass vdataClassCopy = vdataClass>
710  : MUBUF_Atomic_Pseudo<opName, addrKindCopy,
711                        (outs),
712                        getMUBUFAtomicIns<addrKindCopy, vdataClassCopy, 0>.ret,
713                        " $vdata, " # getMUBUFAsmOps<addrKindCopy>.ret # "$cpol",
714                        pattern>,
715    AtomicNoRet<opName # "_" # getAddrName<addrKindCopy>.ret, 0> {
716  let PseudoInstr = opName # "_" # getAddrName<addrKindCopy>.ret;
717  let glc_value = 0;
718  let dlc_value = 0;
719  let sccb_value = 0;
720  let IsAtomicNoRet = 1;
721}
722
723class MUBUF_AtomicRet_Pseudo<string opName, int addrKind,
724                             RegisterClass vdataClass,
725                             list<dag> pattern=[],
726                             // Workaround bug bz30254
727                             int addrKindCopy = addrKind,
728                             RegisterClass vdataClassCopy = vdataClass,
729                             RegisterOperand vdata_op = getLdStRegisterOperand<vdataClass>.ret>
730  : MUBUF_Atomic_Pseudo<opName, addrKindCopy,
731                        (outs vdata_op:$vdata),
732                        getMUBUFAtomicIns<addrKindCopy, vdataClassCopy, 1>.ret,
733                        " $vdata, " # getMUBUFAsmOps<addrKindCopy>.ret # "$cpol",
734                        pattern>,
735    AtomicNoRet<opName # "_" # getAddrName<addrKindCopy>.ret, 1> {
736  let PseudoInstr = opName # "_rtn_" # getAddrName<addrKindCopy>.ret;
737  let glc_value = 1;
738  let dlc_value = 0;
739  let sccb_value = 0;
740  let IsAtomicRet = 1;
741  let Constraints = "$vdata = $vdata_in";
742  let DisableEncoding = "$vdata_in";
743}
744
745multiclass MUBUF_Pseudo_Atomics_NO_RTN <string opName,
746                                        RegisterClass vdataClass,
747                                        ValueType vdataType,
748                                        SDPatternOperator atomic,
749                                        bit isFP = isFloatType<vdataType>.ret> {
750  let FPAtomic = isFP in
751  def _OFFSET : MUBUF_AtomicNoRet_Pseudo <opName, BUFAddrKind.Offset, vdataClass>,
752                MUBUFAddr64Table <0, NAME>;
753
754  let FPAtomic = isFP in
755  def _ADDR64 : MUBUF_AtomicNoRet_Pseudo <opName, BUFAddrKind.Addr64, vdataClass>,
756                MUBUFAddr64Table <1, NAME>;
757
758  let FPAtomic = isFP in
759  def _OFFEN  : MUBUF_AtomicNoRet_Pseudo <opName, BUFAddrKind.OffEn,  vdataClass>;
760
761  let FPAtomic = isFP in
762
763  def _IDXEN  : MUBUF_AtomicNoRet_Pseudo <opName, BUFAddrKind.IdxEn,  vdataClass>;
764
765  let FPAtomic = isFP in
766  def _BOTHEN : MUBUF_AtomicNoRet_Pseudo <opName, BUFAddrKind.BothEn, vdataClass>;
767}
768
769multiclass MUBUF_Pseudo_Atomics_RTN <string opName,
770                                     RegisterClass vdataClass,
771                                     ValueType vdataType,
772                                     SDPatternOperator atomic,
773                                     bit isFP = isFloatType<vdataType>.ret> {
774  let FPAtomic = isFP in
775  def _OFFSET_RTN : MUBUF_AtomicRet_Pseudo <opName, BUFAddrKind.Offset, vdataClass,
776    [(set vdataType:$vdata,
777     (atomic (MUBUFOffset v4i32:$srsrc, i32:$soffset, i16:$offset),
778             vdataType:$vdata_in))]>,
779    MUBUFAddr64Table <0, NAME # "_RTN">;
780
781  let FPAtomic = isFP in
782  def _ADDR64_RTN : MUBUF_AtomicRet_Pseudo <opName, BUFAddrKind.Addr64, vdataClass,
783    [(set vdataType:$vdata,
784     (atomic (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i32:$soffset, i16:$offset),
785              vdataType:$vdata_in))]>,
786    MUBUFAddr64Table <1, NAME # "_RTN">;
787
788  let FPAtomic = isFP in
789  def _OFFEN_RTN  : MUBUF_AtomicRet_Pseudo <opName, BUFAddrKind.OffEn,  vdataClass>;
790
791  let FPAtomic = isFP in
792  def _IDXEN_RTN  : MUBUF_AtomicRet_Pseudo <opName, BUFAddrKind.IdxEn,  vdataClass>;
793
794  let FPAtomic = isFP in
795  def _BOTHEN_RTN : MUBUF_AtomicRet_Pseudo <opName, BUFAddrKind.BothEn, vdataClass>;
796}
797
798multiclass MUBUF_Pseudo_Atomics <string opName,
799                                 RegisterClass vdataClass,
800                                 ValueType vdataType,
801                                 SDPatternOperator atomic> :
802  MUBUF_Pseudo_Atomics_NO_RTN<opName, vdataClass, vdataType, atomic>,
803  MUBUF_Pseudo_Atomics_RTN<opName, vdataClass, vdataType, atomic>;
804
805
806//===----------------------------------------------------------------------===//
807// MUBUF Instructions
808//===----------------------------------------------------------------------===//
809
810defm BUFFER_LOAD_FORMAT_X : MUBUF_Pseudo_Loads_Lds <
811  "buffer_load_format_x", f32
812>;
813defm BUFFER_LOAD_FORMAT_XY : MUBUF_Pseudo_Loads <
814  "buffer_load_format_xy", v2f32
815>;
816defm BUFFER_LOAD_FORMAT_XYZ : MUBUF_Pseudo_Loads <
817  "buffer_load_format_xyz", v3f32
818>;
819defm BUFFER_LOAD_FORMAT_XYZW : MUBUF_Pseudo_Loads <
820  "buffer_load_format_xyzw", v4f32
821>;
822defm BUFFER_STORE_FORMAT_X : MUBUF_Pseudo_Stores <
823  "buffer_store_format_x", f32
824>;
825defm BUFFER_STORE_FORMAT_XY : MUBUF_Pseudo_Stores <
826  "buffer_store_format_xy", v2f32
827>;
828defm BUFFER_STORE_FORMAT_XYZ : MUBUF_Pseudo_Stores <
829  "buffer_store_format_xyz", v3f32
830>;
831defm BUFFER_STORE_FORMAT_XYZW : MUBUF_Pseudo_Stores <
832  "buffer_store_format_xyzw", v4f32
833>;
834
835let SubtargetPredicate = HasUnpackedD16VMem, D16Buf = 1 in {
836  defm BUFFER_LOAD_FORMAT_D16_X_gfx80 : MUBUF_Pseudo_Loads <
837    "buffer_load_format_d16_x", i32
838  >;
839  defm BUFFER_LOAD_FORMAT_D16_XY_gfx80 : MUBUF_Pseudo_Loads <
840    "buffer_load_format_d16_xy", v2i32
841  >;
842  defm BUFFER_LOAD_FORMAT_D16_XYZ_gfx80 : MUBUF_Pseudo_Loads <
843    "buffer_load_format_d16_xyz", v3i32
844  >;
845  defm BUFFER_LOAD_FORMAT_D16_XYZW_gfx80 : MUBUF_Pseudo_Loads <
846   "buffer_load_format_d16_xyzw", v4i32
847  >;
848  defm BUFFER_STORE_FORMAT_D16_X_gfx80 : MUBUF_Pseudo_Stores <
849    "buffer_store_format_d16_x", i32
850  >;
851  defm BUFFER_STORE_FORMAT_D16_XY_gfx80 : MUBUF_Pseudo_Stores <
852    "buffer_store_format_d16_xy", v2i32
853  >;
854  defm BUFFER_STORE_FORMAT_D16_XYZ_gfx80 : MUBUF_Pseudo_Stores <
855    "buffer_store_format_d16_xyz", v3i32
856  >;
857  defm BUFFER_STORE_FORMAT_D16_XYZW_gfx80 : MUBUF_Pseudo_Stores <
858    "buffer_store_format_d16_xyzw", v4i32
859  >;
860} // End HasUnpackedD16VMem.
861
862let SubtargetPredicate = HasPackedD16VMem, D16Buf = 1 in {
863  defm BUFFER_LOAD_FORMAT_D16_X : MUBUF_Pseudo_Loads <
864    "buffer_load_format_d16_x", f16
865  >;
866  defm BUFFER_LOAD_FORMAT_D16_XY : MUBUF_Pseudo_Loads <
867    "buffer_load_format_d16_xy", v2f16
868  >;
869  defm BUFFER_LOAD_FORMAT_D16_XYZ : MUBUF_Pseudo_Loads <
870    "buffer_load_format_d16_xyz", v3f16
871  >;
872  defm BUFFER_LOAD_FORMAT_D16_XYZW : MUBUF_Pseudo_Loads <
873    "buffer_load_format_d16_xyzw", v4f16
874  >;
875  defm BUFFER_STORE_FORMAT_D16_X : MUBUF_Pseudo_Stores <
876    "buffer_store_format_d16_x", f16
877  >;
878  defm BUFFER_STORE_FORMAT_D16_XY : MUBUF_Pseudo_Stores <
879    "buffer_store_format_d16_xy", v2f16
880  >;
881  defm BUFFER_STORE_FORMAT_D16_XYZ : MUBUF_Pseudo_Stores <
882    "buffer_store_format_d16_xyz", v3f16
883  >;
884  defm BUFFER_STORE_FORMAT_D16_XYZW : MUBUF_Pseudo_Stores <
885    "buffer_store_format_d16_xyzw", v4f16
886  >;
887} // End HasPackedD16VMem.
888
889defm BUFFER_LOAD_UBYTE : MUBUF_Pseudo_Loads_Lds <
890  "buffer_load_ubyte", i32
891>;
892defm BUFFER_LOAD_SBYTE : MUBUF_Pseudo_Loads_Lds <
893  "buffer_load_sbyte", i32
894>;
895defm BUFFER_LOAD_USHORT : MUBUF_Pseudo_Loads_Lds <
896  "buffer_load_ushort", i32
897>;
898defm BUFFER_LOAD_SSHORT : MUBUF_Pseudo_Loads_Lds <
899  "buffer_load_sshort", i32
900>;
901defm BUFFER_LOAD_DWORD : MUBUF_Pseudo_Loads_Lds <
902  "buffer_load_dword", i32
903>;
904defm BUFFER_LOAD_DWORDX2 : MUBUF_Pseudo_Loads <
905  "buffer_load_dwordx2", v2i32
906>;
907defm BUFFER_LOAD_DWORDX3 : MUBUF_Pseudo_Loads <
908  "buffer_load_dwordx3", v3i32
909>;
910defm BUFFER_LOAD_DWORDX4 : MUBUF_Pseudo_Loads <
911  "buffer_load_dwordx4", v4i32
912>;
913
914defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_UBYTE", i32, extloadi8_global>;
915defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_UBYTE", i32, zextloadi8_global>;
916defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_SBYTE", i32, sextloadi8_global>;
917defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_USHORT", i32, extloadi16_global>;
918defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_USHORT", i32, zextloadi16_global>;
919defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_SSHORT", i32, sextloadi16_global>;
920defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_DWORD", i32, load_global>;
921defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_DWORDX2", v2i32, load_global>;
922defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_DWORDX3", v3i32, load_global>;
923defm : MUBUF_Pseudo_Load_Pats<"BUFFER_LOAD_DWORDX4", v4i32, load_global>;
924
925// This is not described in AMD documentation,
926// but 'lds' versions of these opcodes are available
927// in at least GFX8+ chips. See Bug 37653.
928let SubtargetPredicate = isGFX8GFX9 in {
929defm BUFFER_LOAD_DWORDX2_LDS : MUBUF_Pseudo_Loads <
930  "buffer_load_dwordx2", v2i32, null_frag, 0, 1
931>;
932defm BUFFER_LOAD_DWORDX3_LDS : MUBUF_Pseudo_Loads <
933  "buffer_load_dwordx3", v3i32, null_frag, 0, 1
934>;
935defm BUFFER_LOAD_DWORDX4_LDS : MUBUF_Pseudo_Loads <
936  "buffer_load_dwordx4", v4i32, null_frag, 0, 1
937>;
938}
939
940defm BUFFER_STORE_BYTE : MUBUF_Pseudo_Stores <
941  "buffer_store_byte", i32, truncstorei8_global
942>;
943defm BUFFER_STORE_SHORT : MUBUF_Pseudo_Stores <
944  "buffer_store_short", i32, truncstorei16_global
945>;
946defm BUFFER_STORE_DWORD : MUBUF_Pseudo_Stores <
947  "buffer_store_dword", i32, store_global
948>;
949defm BUFFER_STORE_DWORDX2 : MUBUF_Pseudo_Stores <
950  "buffer_store_dwordx2", v2i32, store_global
951>;
952defm BUFFER_STORE_DWORDX3 : MUBUF_Pseudo_Stores <
953  "buffer_store_dwordx3", v3i32, store_global
954>;
955defm BUFFER_STORE_DWORDX4 : MUBUF_Pseudo_Stores <
956  "buffer_store_dwordx4", v4i32, store_global
957>;
958defm BUFFER_ATOMIC_SWAP : MUBUF_Pseudo_Atomics <
959  "buffer_atomic_swap", VGPR_32, i32, atomic_swap_global_32
960>;
961defm BUFFER_ATOMIC_CMPSWAP : MUBUF_Pseudo_Atomics <
962  "buffer_atomic_cmpswap", VReg_64, v2i32, null_frag
963>;
964defm BUFFER_ATOMIC_ADD : MUBUF_Pseudo_Atomics <
965  "buffer_atomic_add", VGPR_32, i32, atomic_load_add_global_32
966>;
967defm BUFFER_ATOMIC_SUB : MUBUF_Pseudo_Atomics <
968  "buffer_atomic_sub", VGPR_32, i32, atomic_load_sub_global_32
969>;
970defm BUFFER_ATOMIC_SMIN : MUBUF_Pseudo_Atomics <
971  "buffer_atomic_smin", VGPR_32, i32, atomic_load_min_global_32
972>;
973defm BUFFER_ATOMIC_UMIN : MUBUF_Pseudo_Atomics <
974  "buffer_atomic_umin", VGPR_32, i32, atomic_load_umin_global_32
975>;
976defm BUFFER_ATOMIC_SMAX : MUBUF_Pseudo_Atomics <
977  "buffer_atomic_smax", VGPR_32, i32, atomic_load_max_global_32
978>;
979defm BUFFER_ATOMIC_UMAX : MUBUF_Pseudo_Atomics <
980  "buffer_atomic_umax", VGPR_32, i32, atomic_load_umax_global_32
981>;
982defm BUFFER_ATOMIC_AND : MUBUF_Pseudo_Atomics <
983  "buffer_atomic_and", VGPR_32, i32, atomic_load_and_global_32
984>;
985defm BUFFER_ATOMIC_OR : MUBUF_Pseudo_Atomics <
986  "buffer_atomic_or", VGPR_32, i32, atomic_load_or_global_32
987>;
988defm BUFFER_ATOMIC_XOR : MUBUF_Pseudo_Atomics <
989  "buffer_atomic_xor", VGPR_32, i32, atomic_load_xor_global_32
990>;
991defm BUFFER_ATOMIC_INC : MUBUF_Pseudo_Atomics <
992  "buffer_atomic_inc", VGPR_32, i32, atomic_inc_global_32
993>;
994defm BUFFER_ATOMIC_DEC : MUBUF_Pseudo_Atomics <
995  "buffer_atomic_dec", VGPR_32, i32, atomic_dec_global_32
996>;
997defm BUFFER_ATOMIC_SWAP_X2 : MUBUF_Pseudo_Atomics <
998  "buffer_atomic_swap_x2", VReg_64, i64, atomic_swap_global_64
999>;
1000defm BUFFER_ATOMIC_CMPSWAP_X2 : MUBUF_Pseudo_Atomics <
1001  "buffer_atomic_cmpswap_x2", VReg_128, v2i64, null_frag
1002>;
1003defm BUFFER_ATOMIC_ADD_X2 : MUBUF_Pseudo_Atomics <
1004  "buffer_atomic_add_x2", VReg_64, i64, atomic_load_add_global_64
1005>;
1006defm BUFFER_ATOMIC_SUB_X2 : MUBUF_Pseudo_Atomics <
1007  "buffer_atomic_sub_x2", VReg_64, i64, atomic_load_sub_global_64
1008>;
1009defm BUFFER_ATOMIC_SMIN_X2 : MUBUF_Pseudo_Atomics <
1010  "buffer_atomic_smin_x2", VReg_64, i64, atomic_load_min_global_64
1011>;
1012defm BUFFER_ATOMIC_UMIN_X2 : MUBUF_Pseudo_Atomics <
1013  "buffer_atomic_umin_x2", VReg_64, i64, atomic_load_umin_global_64
1014>;
1015defm BUFFER_ATOMIC_SMAX_X2 : MUBUF_Pseudo_Atomics <
1016  "buffer_atomic_smax_x2", VReg_64, i64, atomic_load_max_global_64
1017>;
1018defm BUFFER_ATOMIC_UMAX_X2 : MUBUF_Pseudo_Atomics <
1019  "buffer_atomic_umax_x2", VReg_64, i64, atomic_load_umax_global_64
1020>;
1021defm BUFFER_ATOMIC_AND_X2 : MUBUF_Pseudo_Atomics <
1022  "buffer_atomic_and_x2", VReg_64, i64, atomic_load_and_global_64
1023>;
1024defm BUFFER_ATOMIC_OR_X2 : MUBUF_Pseudo_Atomics <
1025  "buffer_atomic_or_x2", VReg_64, i64, atomic_load_or_global_64
1026>;
1027defm BUFFER_ATOMIC_XOR_X2 : MUBUF_Pseudo_Atomics <
1028  "buffer_atomic_xor_x2", VReg_64, i64, atomic_load_xor_global_64
1029>;
1030defm BUFFER_ATOMIC_INC_X2 : MUBUF_Pseudo_Atomics <
1031  "buffer_atomic_inc_x2", VReg_64, i64, atomic_inc_global_64
1032>;
1033defm BUFFER_ATOMIC_DEC_X2 : MUBUF_Pseudo_Atomics <
1034  "buffer_atomic_dec_x2", VReg_64, i64, atomic_dec_global_64
1035>;
1036
1037let SubtargetPredicate = HasGFX10_BEncoding in
1038defm BUFFER_ATOMIC_CSUB : MUBUF_Pseudo_Atomics_RTN <
1039  "buffer_atomic_csub", VGPR_32, i32, int_amdgcn_global_atomic_csub
1040>;
1041
1042let SubtargetPredicate = isGFX8GFX9 in {
1043def BUFFER_STORE_LDS_DWORD : MUBUF_Pseudo_Store_Lds <"buffer_store_lds_dword">;
1044}
1045
1046let SubtargetPredicate = isGFX6 in { // isn't on CI & VI
1047/*
1048defm BUFFER_ATOMIC_RSUB        : MUBUF_Pseudo_Atomics <"buffer_atomic_rsub">;
1049defm BUFFER_ATOMIC_RSUB_X2     : MUBUF_Pseudo_Atomics <"buffer_atomic_rsub_x2">;
1050*/
1051
1052def BUFFER_WBINVL1_SC : MUBUF_Invalidate <"buffer_wbinvl1_sc",
1053                                          int_amdgcn_buffer_wbinvl1_sc>;
1054}
1055
1056let SubtargetPredicate = isGFX6GFX7GFX10 in {
1057
1058defm BUFFER_ATOMIC_FCMPSWAP : MUBUF_Pseudo_Atomics <
1059  "buffer_atomic_fcmpswap", VReg_64, v2f32, null_frag
1060>;
1061defm BUFFER_ATOMIC_FMIN : MUBUF_Pseudo_Atomics <
1062  "buffer_atomic_fmin", VGPR_32, f32, null_frag
1063>;
1064defm BUFFER_ATOMIC_FMAX : MUBUF_Pseudo_Atomics <
1065  "buffer_atomic_fmax", VGPR_32, f32, null_frag
1066>;
1067defm BUFFER_ATOMIC_FCMPSWAP_X2 : MUBUF_Pseudo_Atomics <
1068  "buffer_atomic_fcmpswap_x2", VReg_128, v2f64, null_frag
1069>;
1070defm BUFFER_ATOMIC_FMIN_X2 : MUBUF_Pseudo_Atomics <
1071  "buffer_atomic_fmin_x2", VReg_64, f64, null_frag
1072>;
1073defm BUFFER_ATOMIC_FMAX_X2 : MUBUF_Pseudo_Atomics <
1074  "buffer_atomic_fmax_x2", VReg_64, f64, null_frag
1075>;
1076
1077}
1078
1079let SubtargetPredicate = HasD16LoadStore in {
1080
1081defm BUFFER_LOAD_UBYTE_D16 : MUBUF_Pseudo_Loads <
1082  "buffer_load_ubyte_d16", i32, null_frag, 1
1083>;
1084
1085defm BUFFER_LOAD_UBYTE_D16_HI : MUBUF_Pseudo_Loads <
1086  "buffer_load_ubyte_d16_hi", i32, null_frag, 1
1087>;
1088
1089defm BUFFER_LOAD_SBYTE_D16 : MUBUF_Pseudo_Loads <
1090  "buffer_load_sbyte_d16", i32, null_frag, 1
1091>;
1092
1093defm BUFFER_LOAD_SBYTE_D16_HI : MUBUF_Pseudo_Loads <
1094  "buffer_load_sbyte_d16_hi", i32, null_frag, 1
1095>;
1096
1097defm BUFFER_LOAD_SHORT_D16 : MUBUF_Pseudo_Loads <
1098  "buffer_load_short_d16", i32, null_frag, 1
1099>;
1100
1101defm BUFFER_LOAD_SHORT_D16_HI : MUBUF_Pseudo_Loads <
1102  "buffer_load_short_d16_hi", i32, null_frag, 1
1103>;
1104
1105defm BUFFER_STORE_BYTE_D16_HI : MUBUF_Pseudo_Stores <
1106  "buffer_store_byte_d16_hi", i32
1107>;
1108
1109defm BUFFER_STORE_SHORT_D16_HI : MUBUF_Pseudo_Stores <
1110  "buffer_store_short_d16_hi", i32
1111>;
1112
1113defm BUFFER_LOAD_FORMAT_D16_HI_X : MUBUF_Pseudo_Loads <
1114  "buffer_load_format_d16_hi_x", i32
1115>;
1116defm BUFFER_STORE_FORMAT_D16_HI_X : MUBUF_Pseudo_Stores <
1117  "buffer_store_format_d16_hi_x", i32
1118>;
1119
1120} // End HasD16LoadStore
1121
1122def BUFFER_WBINVL1 : MUBUF_Invalidate <"buffer_wbinvl1",
1123                                       int_amdgcn_buffer_wbinvl1>;
1124
1125let SubtargetPredicate = HasAtomicFaddInsts in {
1126defm BUFFER_ATOMIC_ADD_F32 : MUBUF_Pseudo_Atomics_NO_RTN <
1127  "buffer_atomic_add_f32", VGPR_32, f32, atomic_load_fadd_global_noret_32
1128>;
1129defm BUFFER_ATOMIC_PK_ADD_F16 : MUBUF_Pseudo_Atomics_NO_RTN <
1130  "buffer_atomic_pk_add_f16", VGPR_32, v2f16, atomic_load_fadd_v2f16_global_noret_32
1131>;
1132
1133let OtherPredicates = [isGFX90APlus] in {
1134defm BUFFER_ATOMIC_ADD_F32 : MUBUF_Pseudo_Atomics_RTN <
1135  "buffer_atomic_add_f32", VGPR_32, f32, atomic_load_fadd_global_32
1136>;
1137defm BUFFER_ATOMIC_PK_ADD_F16 : MUBUF_Pseudo_Atomics_RTN <
1138  "buffer_atomic_pk_add_f16", VGPR_32, v2f16, atomic_load_fadd_v2f16_global_32
1139>;
1140}
1141} // End SubtargetPredicate = HasAtomicFaddInsts
1142
1143//===----------------------------------------------------------------------===//
1144// MTBUF Instructions
1145//===----------------------------------------------------------------------===//
1146
1147defm TBUFFER_LOAD_FORMAT_X     : MTBUF_Pseudo_Loads  <"tbuffer_load_format_x",     VGPR_32,  1>;
1148defm TBUFFER_LOAD_FORMAT_XY    : MTBUF_Pseudo_Loads  <"tbuffer_load_format_xy",    VReg_64,  2>;
1149defm TBUFFER_LOAD_FORMAT_XYZ   : MTBUF_Pseudo_Loads  <"tbuffer_load_format_xyz",   VReg_96,  3>;
1150defm TBUFFER_LOAD_FORMAT_XYZW  : MTBUF_Pseudo_Loads  <"tbuffer_load_format_xyzw",  VReg_128, 4>;
1151defm TBUFFER_STORE_FORMAT_X    : MTBUF_Pseudo_Stores <"tbuffer_store_format_x",    VGPR_32,  1>;
1152defm TBUFFER_STORE_FORMAT_XY   : MTBUF_Pseudo_Stores <"tbuffer_store_format_xy",   VReg_64,  2>;
1153defm TBUFFER_STORE_FORMAT_XYZ  : MTBUF_Pseudo_Stores <"tbuffer_store_format_xyz",  VReg_96,  3>;
1154defm TBUFFER_STORE_FORMAT_XYZW : MTBUF_Pseudo_Stores <"tbuffer_store_format_xyzw", VReg_128, 4>;
1155
1156let SubtargetPredicate = HasUnpackedD16VMem, D16Buf = 1 in {
1157  defm TBUFFER_LOAD_FORMAT_D16_X_gfx80     : MTBUF_Pseudo_Loads  <"tbuffer_load_format_d16_x",     VGPR_32,  1>;
1158  defm TBUFFER_LOAD_FORMAT_D16_XY_gfx80    : MTBUF_Pseudo_Loads  <"tbuffer_load_format_d16_xy",    VReg_64,  2>;
1159  defm TBUFFER_LOAD_FORMAT_D16_XYZ_gfx80   : MTBUF_Pseudo_Loads  <"tbuffer_load_format_d16_xyz",   VReg_96,  3>;
1160  defm TBUFFER_LOAD_FORMAT_D16_XYZW_gfx80  : MTBUF_Pseudo_Loads  <"tbuffer_load_format_d16_xyzw",  VReg_128, 4>;
1161  defm TBUFFER_STORE_FORMAT_D16_X_gfx80    : MTBUF_Pseudo_Stores <"tbuffer_store_format_d16_x",    VGPR_32,  1>;
1162  defm TBUFFER_STORE_FORMAT_D16_XY_gfx80   : MTBUF_Pseudo_Stores <"tbuffer_store_format_d16_xy",   VReg_64,  2>;
1163  defm TBUFFER_STORE_FORMAT_D16_XYZ_gfx80  : MTBUF_Pseudo_Stores <"tbuffer_store_format_d16_xyz",  VReg_96,  3>;
1164  defm TBUFFER_STORE_FORMAT_D16_XYZW_gfx80 : MTBUF_Pseudo_Stores <"tbuffer_store_format_d16_xyzw", VReg_128, 4>;
1165} // End HasUnpackedD16VMem.
1166
1167let SubtargetPredicate = HasPackedD16VMem, D16Buf = 1 in {
1168  defm TBUFFER_LOAD_FORMAT_D16_X     : MTBUF_Pseudo_Loads  <"tbuffer_load_format_d16_x",     VGPR_32, 1>;
1169  defm TBUFFER_LOAD_FORMAT_D16_XY    : MTBUF_Pseudo_Loads  <"tbuffer_load_format_d16_xy",    VGPR_32, 2>;
1170  defm TBUFFER_LOAD_FORMAT_D16_XYZ   : MTBUF_Pseudo_Loads  <"tbuffer_load_format_d16_xyz",   VReg_64, 3>;
1171  defm TBUFFER_LOAD_FORMAT_D16_XYZW  : MTBUF_Pseudo_Loads  <"tbuffer_load_format_d16_xyzw",  VReg_64, 4>;
1172  defm TBUFFER_STORE_FORMAT_D16_X    : MTBUF_Pseudo_Stores <"tbuffer_store_format_d16_x",    VGPR_32, 1>;
1173  defm TBUFFER_STORE_FORMAT_D16_XY   : MTBUF_Pseudo_Stores <"tbuffer_store_format_d16_xy",   VGPR_32, 2>;
1174  defm TBUFFER_STORE_FORMAT_D16_XYZ  : MTBUF_Pseudo_Stores <"tbuffer_store_format_d16_xyz",  VReg_64, 3>;
1175  defm TBUFFER_STORE_FORMAT_D16_XYZW : MTBUF_Pseudo_Stores <"tbuffer_store_format_d16_xyzw", VReg_64, 4>;
1176} // End HasPackedD16VMem.
1177
1178let SubtargetPredicate = isGFX7Plus in {
1179
1180//===----------------------------------------------------------------------===//
1181// Instruction definitions for CI and newer.
1182//===----------------------------------------------------------------------===//
1183
1184def BUFFER_WBINVL1_VOL : MUBUF_Invalidate <"buffer_wbinvl1_vol",
1185                                           int_amdgcn_buffer_wbinvl1_vol>;
1186
1187} // End let SubtargetPredicate = isGFX7Plus
1188
1189let SubtargetPredicate = isGFX90APlus in {
1190  def BUFFER_WBL2  : MUBUF_Invalidate<"buffer_wbl2"> {
1191  }
1192  def BUFFER_INVL2 : MUBUF_Invalidate<"buffer_invl2"> {
1193  }
1194
1195  defm BUFFER_ATOMIC_ADD_F64 : MUBUF_Pseudo_Atomics<"buffer_atomic_add_f64", VReg_64, f64, int_amdgcn_global_atomic_fadd>;
1196  defm BUFFER_ATOMIC_MIN_F64 : MUBUF_Pseudo_Atomics<"buffer_atomic_min_f64", VReg_64, f64, int_amdgcn_global_atomic_fmin>;
1197  defm BUFFER_ATOMIC_MAX_F64 : MUBUF_Pseudo_Atomics<"buffer_atomic_max_f64", VReg_64, f64, int_amdgcn_global_atomic_fmax>;
1198} // End SubtargetPredicate = isGFX90APlus
1199
1200let SubtargetPredicate = isGFX10Plus in {
1201  def BUFFER_GL0_INV : MUBUF_Invalidate<"buffer_gl0_inv">;
1202  def BUFFER_GL1_INV : MUBUF_Invalidate<"buffer_gl1_inv">;
1203} // End SubtargetPredicate = isGFX10Plus
1204
1205//===----------------------------------------------------------------------===//
1206// MUBUF Patterns
1207//===----------------------------------------------------------------------===//
1208
1209//===----------------------------------------------------------------------===//
1210// buffer_load/store_format patterns
1211//===----------------------------------------------------------------------===//
1212
1213multiclass MUBUF_LoadIntrinsicPat<SDPatternOperator name, ValueType vt,
1214                                  string opcode, ValueType memoryVt = vt> {
1215  defvar st = !if(!eq(!cast<string>(memoryVt), !cast<string>(vt)), name, mubuf_intrinsic_load<name, memoryVt>);
1216
1217  def : GCNPat<
1218    (vt (st v4i32:$rsrc, 0, 0, i32:$soffset, timm:$offset,
1219              timm:$auxiliary, 0)),
1220    (!cast<MUBUF_Pseudo>(opcode # _OFFSET) SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1221      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1222  >;
1223
1224  def : GCNPat<
1225    (vt (st v4i32:$rsrc, 0, i32:$voffset, i32:$soffset, timm:$offset,
1226              timm:$auxiliary, 0)),
1227    (!cast<MUBUF_Pseudo>(opcode # _OFFEN) VGPR_32:$voffset, SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1228      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1229  >;
1230
1231  def : GCNPat<
1232    (vt (st v4i32:$rsrc, i32:$vindex, 0, i32:$soffset, timm:$offset,
1233              timm:$auxiliary, timm)),
1234    (!cast<MUBUF_Pseudo>(opcode # _IDXEN) VGPR_32:$vindex, SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1235      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1236  >;
1237
1238  def : GCNPat<
1239    (vt (st v4i32:$rsrc, i32:$vindex, i32:$voffset, i32:$soffset, timm:$offset,
1240              timm:$auxiliary, timm)),
1241    (!cast<MUBUF_Pseudo>(opcode # _BOTHEN)
1242      (REG_SEQUENCE VReg_64, VGPR_32:$vindex, sub0, VGPR_32:$voffset, sub1),
1243      SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1244      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1245  >;
1246}
1247
1248defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format, f32, "BUFFER_LOAD_FORMAT_X">;
1249defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format, i32, "BUFFER_LOAD_FORMAT_X">;
1250defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format, v2f32, "BUFFER_LOAD_FORMAT_XY">;
1251defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format, v2i32, "BUFFER_LOAD_FORMAT_XY">;
1252defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format, v3f32, "BUFFER_LOAD_FORMAT_XYZ">;
1253defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format, v3i32, "BUFFER_LOAD_FORMAT_XYZ">;
1254defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format, v4f32, "BUFFER_LOAD_FORMAT_XYZW">;
1255defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format, v4i32, "BUFFER_LOAD_FORMAT_XYZW">;
1256
1257let SubtargetPredicate = HasUnpackedD16VMem in {
1258  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, f16, "BUFFER_LOAD_FORMAT_D16_X_gfx80">;
1259  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, i16, "BUFFER_LOAD_FORMAT_D16_X_gfx80">;
1260  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, i32, "BUFFER_LOAD_FORMAT_D16_X_gfx80">;
1261  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v2i32, "BUFFER_LOAD_FORMAT_D16_XY_gfx80">;
1262  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v3i32, "BUFFER_LOAD_FORMAT_D16_XYZ_gfx80">;
1263  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v4i32, "BUFFER_LOAD_FORMAT_D16_XYZW_gfx80">;
1264} // End HasUnpackedD16VMem.
1265
1266let SubtargetPredicate = HasPackedD16VMem in {
1267  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, f16, "BUFFER_LOAD_FORMAT_D16_X">;
1268  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, i16, "BUFFER_LOAD_FORMAT_D16_X">;
1269  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, i32, "BUFFER_LOAD_FORMAT_D16_X">;
1270  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v2f16, "BUFFER_LOAD_FORMAT_D16_XY">;
1271  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v2i16, "BUFFER_LOAD_FORMAT_D16_XY">;
1272  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v4f16, "BUFFER_LOAD_FORMAT_D16_XYZ", v3f16>;
1273  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v4i16, "BUFFER_LOAD_FORMAT_D16_XYZ", v3i16>;
1274  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v4f16, "BUFFER_LOAD_FORMAT_D16_XYZW">;
1275  defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_format_d16, v4i16, "BUFFER_LOAD_FORMAT_D16_XYZW">;
1276} // End HasPackedD16VMem.
1277
1278defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, f32, "BUFFER_LOAD_DWORD">;
1279defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, i32, "BUFFER_LOAD_DWORD">;
1280defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v2i16, "BUFFER_LOAD_DWORD">;
1281defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v2f16, "BUFFER_LOAD_DWORD">;
1282defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v2f32, "BUFFER_LOAD_DWORDX2">;
1283defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v2i32, "BUFFER_LOAD_DWORDX2">;
1284defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v4i16, "BUFFER_LOAD_DWORDX2">;
1285defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v4f16, "BUFFER_LOAD_DWORDX2">;
1286defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v3f32, "BUFFER_LOAD_DWORDX3">;
1287defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v3i32, "BUFFER_LOAD_DWORDX3">;
1288defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v4f32, "BUFFER_LOAD_DWORDX4">;
1289defm : MUBUF_LoadIntrinsicPat<SIbuffer_load, v4i32, "BUFFER_LOAD_DWORDX4">;
1290defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_byte, i32, "BUFFER_LOAD_SBYTE">;
1291defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_short, i32, "BUFFER_LOAD_SSHORT">;
1292defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_ubyte, i32, "BUFFER_LOAD_UBYTE">;
1293defm : MUBUF_LoadIntrinsicPat<SIbuffer_load_ushort,  i32, "BUFFER_LOAD_USHORT">;
1294
1295multiclass MUBUF_StoreIntrinsicPat<SDPatternOperator name, ValueType vt,
1296                                   string opcode, ValueType memoryVt = vt> {
1297  defvar st = !if(!eq(!cast<string>(memoryVt), !cast<string>(vt)), name, mubuf_intrinsic_store<name, memoryVt>);
1298
1299  def : GCNPat<
1300    (st vt:$vdata, v4i32:$rsrc, 0, 0, i32:$soffset, timm:$offset,
1301              timm:$auxiliary, 0),
1302    (!cast<MUBUF_Pseudo>(opcode # _OFFSET_exact) getVregSrcForVT<vt>.ret:$vdata, SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1303      (extract_cpol $auxiliary), 0,  (extract_swz $auxiliary))
1304  >;
1305
1306  def : GCNPat<
1307    (st vt:$vdata, v4i32:$rsrc, 0, i32:$voffset, i32:$soffset, timm:$offset,
1308              timm:$auxiliary, 0),
1309    (!cast<MUBUF_Pseudo>(opcode # _OFFEN_exact) getVregSrcForVT<vt>.ret:$vdata, VGPR_32:$voffset, SReg_128:$rsrc, SCSrc_b32:$soffset,
1310      (as_i16timm $offset), (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1311  >;
1312
1313  def : GCNPat<
1314    (st vt:$vdata, v4i32:$rsrc, i32:$vindex, 0, i32:$soffset, timm:$offset,
1315              timm:$auxiliary, timm),
1316    (!cast<MUBUF_Pseudo>(opcode # _IDXEN_exact) getVregSrcForVT<vt>.ret:$vdata, VGPR_32:$vindex, SReg_128:$rsrc, SCSrc_b32:$soffset,
1317      (as_i16timm $offset), (extract_cpol $auxiliary), 0,  (extract_swz $auxiliary))
1318  >;
1319
1320  def : GCNPat<
1321    (st vt:$vdata, v4i32:$rsrc, i32:$vindex, i32:$voffset, i32:$soffset, timm:$offset,
1322              timm:$auxiliary, timm),
1323    (!cast<MUBUF_Pseudo>(opcode # _BOTHEN_exact)
1324      getVregSrcForVT<vt>.ret:$vdata,
1325      (REG_SEQUENCE VReg_64, VGPR_32:$vindex, sub0, VGPR_32:$voffset, sub1),
1326      SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset), (extract_cpol $auxiliary),
1327      0,  (extract_swz $auxiliary))
1328  >;
1329}
1330
1331defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format, f32, "BUFFER_STORE_FORMAT_X">;
1332defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format, i32, "BUFFER_STORE_FORMAT_X">;
1333defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format, v2f32, "BUFFER_STORE_FORMAT_XY">;
1334defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format, v2i32, "BUFFER_STORE_FORMAT_XY">;
1335defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format, v3f32, "BUFFER_STORE_FORMAT_XYZ">;
1336defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format, v3i32, "BUFFER_STORE_FORMAT_XYZ">;
1337defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format, v4f32, "BUFFER_STORE_FORMAT_XYZW">;
1338defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format, v4i32, "BUFFER_STORE_FORMAT_XYZW">;
1339
1340let SubtargetPredicate = HasUnpackedD16VMem in {
1341  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, f16, "BUFFER_STORE_FORMAT_D16_X_gfx80">;
1342  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, i16, "BUFFER_STORE_FORMAT_D16_X_gfx80">;
1343  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, i32, "BUFFER_STORE_FORMAT_D16_X_gfx80">;
1344  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v2i32, "BUFFER_STORE_FORMAT_D16_XY_gfx80">;
1345  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v3i32, "BUFFER_STORE_FORMAT_D16_XYZ_gfx80">;
1346  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v4i32, "BUFFER_STORE_FORMAT_D16_XYZW_gfx80">;
1347} // End HasUnpackedD16VMem.
1348
1349let SubtargetPredicate = HasPackedD16VMem in {
1350  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, f16, "BUFFER_STORE_FORMAT_D16_X">;
1351  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, i16, "BUFFER_STORE_FORMAT_D16_X">;
1352  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, i32, "BUFFER_STORE_FORMAT_D16_X">;
1353  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v2f16, "BUFFER_STORE_FORMAT_D16_XY">;
1354  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v2i16, "BUFFER_STORE_FORMAT_D16_XY">;
1355  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v4f16, "BUFFER_STORE_FORMAT_D16_XYZ", v3f16>;
1356  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v4i16, "BUFFER_STORE_FORMAT_D16_XYZ", v3i16>;
1357  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v4f16, "BUFFER_STORE_FORMAT_D16_XYZW">;
1358  defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_format_d16, v4i16, "BUFFER_STORE_FORMAT_D16_XYZW">;
1359} // End HasPackedD16VMem.
1360
1361defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, f32, "BUFFER_STORE_DWORD">;
1362defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, i32, "BUFFER_STORE_DWORD">;
1363defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v2i16, "BUFFER_STORE_DWORD">;
1364defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v2f16, "BUFFER_STORE_DWORD">;
1365defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v2f32, "BUFFER_STORE_DWORDX2">;
1366defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v2i32, "BUFFER_STORE_DWORDX2">;
1367defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v4i16, "BUFFER_STORE_DWORDX2">;
1368defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v4f16, "BUFFER_STORE_DWORDX2">;
1369defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v3f32, "BUFFER_STORE_DWORDX3">;
1370defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v3i32, "BUFFER_STORE_DWORDX3">;
1371defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v4f32, "BUFFER_STORE_DWORDX4">;
1372defm : MUBUF_StoreIntrinsicPat<SIbuffer_store, v4i32, "BUFFER_STORE_DWORDX4">;
1373defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_byte, i32, "BUFFER_STORE_BYTE">;
1374defm : MUBUF_StoreIntrinsicPat<SIbuffer_store_short, i32, "BUFFER_STORE_SHORT">;
1375
1376//===----------------------------------------------------------------------===//
1377// buffer_atomic patterns
1378//===----------------------------------------------------------------------===//
1379
1380multiclass BufferAtomicPatterns<SDPatternOperator name, ValueType vt,
1381                                string opcode> {
1382  def : GCNPat<
1383    (vt (name vt:$vdata_in, v4i32:$rsrc, 0, 0, i32:$soffset,
1384              timm:$offset, timm:$cachepolicy, 0)),
1385    (!cast<MUBUF_Pseudo>(opcode # _OFFSET_RTN)
1386      getVregSrcForVT<vt>.ret:$vdata_in, SReg_128:$rsrc, SCSrc_b32:$soffset,
1387      (as_i16timm $offset), (set_glc $cachepolicy))
1388  >;
1389
1390  def : GCNPat<
1391    (vt (name vt:$vdata_in, v4i32:$rsrc, i32:$vindex, 0, i32:$soffset,
1392              timm:$offset, timm:$cachepolicy, timm)),
1393    (!cast<MUBUF_Pseudo>(opcode # _IDXEN_RTN) getVregSrcForVT<vt>.ret:$vdata_in,
1394      VGPR_32:$vindex, SReg_128:$rsrc, SCSrc_b32:$soffset,
1395      (as_i16timm $offset), (set_glc $cachepolicy))
1396  >;
1397
1398  def : GCNPat<
1399    (vt (name vt:$vdata_in, v4i32:$rsrc, 0, i32:$voffset,
1400              i32:$soffset, timm:$offset, timm:$cachepolicy, 0)),
1401    (!cast<MUBUF_Pseudo>(opcode # _OFFEN_RTN) getVregSrcForVT<vt>.ret:$vdata_in,
1402      VGPR_32:$voffset, SReg_128:$rsrc, SCSrc_b32:$soffset,
1403      (as_i16timm $offset), (set_glc $cachepolicy))
1404  >;
1405
1406  def : GCNPat<
1407    (vt (name vt:$vdata_in, v4i32:$rsrc, i32:$vindex, i32:$voffset,
1408              i32:$soffset, timm:$offset, timm:$cachepolicy, timm)),
1409    (!cast<MUBUF_Pseudo>(opcode # _BOTHEN_RTN)
1410      getVregSrcForVT<vt>.ret:$vdata_in,
1411      (REG_SEQUENCE VReg_64, VGPR_32:$vindex, sub0, VGPR_32:$voffset, sub1),
1412        SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1413        (set_glc $cachepolicy))
1414  >;
1415}
1416
1417defm : BufferAtomicPatterns<SIbuffer_atomic_swap, i32, "BUFFER_ATOMIC_SWAP">;
1418defm : BufferAtomicPatterns<SIbuffer_atomic_swap, f32, "BUFFER_ATOMIC_SWAP">;
1419defm : BufferAtomicPatterns<SIbuffer_atomic_add, i32, "BUFFER_ATOMIC_ADD">;
1420defm : BufferAtomicPatterns<SIbuffer_atomic_sub, i32, "BUFFER_ATOMIC_SUB">;
1421defm : BufferAtomicPatterns<SIbuffer_atomic_smin, i32, "BUFFER_ATOMIC_SMIN">;
1422defm : BufferAtomicPatterns<SIbuffer_atomic_umin, i32, "BUFFER_ATOMIC_UMIN">;
1423defm : BufferAtomicPatterns<SIbuffer_atomic_smax, i32, "BUFFER_ATOMIC_SMAX">;
1424defm : BufferAtomicPatterns<SIbuffer_atomic_umax, i32, "BUFFER_ATOMIC_UMAX">;
1425defm : BufferAtomicPatterns<SIbuffer_atomic_and, i32, "BUFFER_ATOMIC_AND">;
1426defm : BufferAtomicPatterns<SIbuffer_atomic_or, i32, "BUFFER_ATOMIC_OR">;
1427defm : BufferAtomicPatterns<SIbuffer_atomic_xor, i32, "BUFFER_ATOMIC_XOR">;
1428defm : BufferAtomicPatterns<SIbuffer_atomic_inc, i32, "BUFFER_ATOMIC_INC">;
1429defm : BufferAtomicPatterns<SIbuffer_atomic_dec, i32, "BUFFER_ATOMIC_DEC">;
1430defm : BufferAtomicPatterns<SIbuffer_atomic_csub, i32, "BUFFER_ATOMIC_CSUB">;
1431defm : BufferAtomicPatterns<SIbuffer_atomic_swap, i64, "BUFFER_ATOMIC_SWAP_X2">;
1432defm : BufferAtomicPatterns<SIbuffer_atomic_add, i64,  "BUFFER_ATOMIC_ADD_X2">;
1433defm : BufferAtomicPatterns<SIbuffer_atomic_sub, i64, "BUFFER_ATOMIC_SUB_X2">;
1434defm : BufferAtomicPatterns<SIbuffer_atomic_smin, i64, "BUFFER_ATOMIC_SMIN_X2">;
1435defm : BufferAtomicPatterns<SIbuffer_atomic_umin, i64, "BUFFER_ATOMIC_UMIN_X2">;
1436defm : BufferAtomicPatterns<SIbuffer_atomic_smax, i64, "BUFFER_ATOMIC_SMAX_X2">;
1437defm : BufferAtomicPatterns<SIbuffer_atomic_umax, i64, "BUFFER_ATOMIC_UMAX_X2">;
1438defm : BufferAtomicPatterns<SIbuffer_atomic_and, i64, "BUFFER_ATOMIC_AND_X2">;
1439defm : BufferAtomicPatterns<SIbuffer_atomic_or, i64, "BUFFER_ATOMIC_OR_X2">;
1440defm : BufferAtomicPatterns<SIbuffer_atomic_xor, i64, "BUFFER_ATOMIC_XOR_X2">;
1441defm : BufferAtomicPatterns<SIbuffer_atomic_inc, i64, "BUFFER_ATOMIC_INC_X2">;
1442defm : BufferAtomicPatterns<SIbuffer_atomic_dec, i64, "BUFFER_ATOMIC_DEC_X2">;
1443
1444class NoUseBufferAtomic<SDPatternOperator Op, ValueType vt> : PatFrag <
1445  (ops node:$src0, node:$src1, node:$src2, node:$src3, node:$src4, node:$src5, node:$src6, node:$src7),
1446  (vt (Op $src0, $src1, $src2, $src3, $src4, $src5, $src6, $src7)),
1447  [{ return SDValue(N, 0).use_empty(); }]> {
1448
1449  let GISelPredicateCode = [{
1450    return MRI.use_nodbg_empty(MI.getOperand(0).getReg());
1451  }];
1452}
1453
1454multiclass BufferAtomicPatterns_NO_RTN<SDPatternOperator name, ValueType vt,
1455                                       string opcode> {
1456  def : GCNPat<
1457    (NoUseBufferAtomic<name, vt> vt:$vdata_in, v4i32:$rsrc, 0,
1458                                 0, i32:$soffset, timm:$offset,
1459                                 timm:$cachepolicy, 0),
1460    (!cast<MUBUF_Pseudo>(opcode # _OFFSET) getVregSrcForVT<vt>.ret:$vdata_in, SReg_128:$rsrc, SCSrc_b32:$soffset,
1461                                          (as_i16timm $offset), $cachepolicy)
1462  >;
1463
1464  def : GCNPat<
1465    (NoUseBufferAtomic<name, vt> vt:$vdata_in, v4i32:$rsrc, i32:$vindex,
1466                                 0, i32:$soffset, timm:$offset,
1467                                 timm:$cachepolicy, timm),
1468    (!cast<MUBUF_Pseudo>(opcode # _IDXEN) getVregSrcForVT<vt>.ret:$vdata_in, VGPR_32:$vindex, SReg_128:$rsrc, SCSrc_b32:$soffset,
1469                                          (as_i16timm $offset), $cachepolicy)
1470  >;
1471
1472  def : GCNPat<
1473    (NoUseBufferAtomic<name, vt> vt:$vdata_in, v4i32:$rsrc, 0,
1474                                 i32:$voffset, i32:$soffset, timm:$offset,
1475                                 timm:$cachepolicy, 0),
1476    (!cast<MUBUF_Pseudo>(opcode # _OFFEN) getVregSrcForVT<vt>.ret:$vdata_in, VGPR_32:$voffset, SReg_128:$rsrc, SCSrc_b32:$soffset,
1477                                          (as_i16timm $offset), $cachepolicy)
1478  >;
1479
1480  def : GCNPat<
1481    (NoUseBufferAtomic<name, vt> vt:$vdata_in, v4i32:$rsrc, i32:$vindex,
1482                                 i32:$voffset, i32:$soffset, timm:$offset,
1483                                 timm:$cachepolicy, timm),
1484    (!cast<MUBUF_Pseudo>(opcode # _BOTHEN)
1485      getVregSrcForVT<vt>.ret:$vdata_in,
1486      (REG_SEQUENCE VReg_64, VGPR_32:$vindex, sub0, VGPR_32:$voffset, sub1),
1487      SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset), $cachepolicy)
1488  >;
1489}
1490
1491let SubtargetPredicate = HasAtomicFaddInsts in {
1492defm : BufferAtomicPatterns_NO_RTN<SIbuffer_atomic_fadd, f32, "BUFFER_ATOMIC_ADD_F32">;
1493defm : BufferAtomicPatterns_NO_RTN<SIbuffer_atomic_fadd, v2f16, "BUFFER_ATOMIC_PK_ADD_F16">;
1494}
1495
1496let SubtargetPredicate = isGFX90APlus in {
1497  defm : BufferAtomicPatterns<SIbuffer_atomic_fadd, f32,   "BUFFER_ATOMIC_ADD_F32">;
1498  defm : BufferAtomicPatterns<SIbuffer_atomic_fadd, v2f16, "BUFFER_ATOMIC_PK_ADD_F16">;
1499
1500  defm : BufferAtomicPatterns<SIbuffer_atomic_fadd, f64, "BUFFER_ATOMIC_ADD_F64">;
1501  defm : BufferAtomicPatterns<SIbuffer_atomic_fmin, f64, "BUFFER_ATOMIC_MIN_F64">;
1502  defm : BufferAtomicPatterns<SIbuffer_atomic_fmax, f64, "BUFFER_ATOMIC_MAX_F64">;
1503} // End SubtargetPredicate = isGFX90APlus
1504
1505def : GCNPat<
1506  (SIbuffer_atomic_cmpswap
1507      i32:$data, i32:$cmp, v4i32:$rsrc, 0, 0, i32:$soffset,
1508      timm:$offset, timm:$cachepolicy, 0),
1509  (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS
1510    (BUFFER_ATOMIC_CMPSWAP_OFFSET_RTN
1511      (REG_SEQUENCE VReg_64, VGPR_32:$data, sub0, VGPR_32:$cmp, sub1),
1512        SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1513        (set_glc $cachepolicy)), VReg_64)), sub0)
1514>;
1515
1516def : GCNPat<
1517  (SIbuffer_atomic_cmpswap
1518      i32:$data, i32:$cmp, v4i32:$rsrc, i32:$vindex,
1519      0, i32:$soffset, timm:$offset,
1520      timm:$cachepolicy, timm),
1521  (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS
1522    (BUFFER_ATOMIC_CMPSWAP_IDXEN_RTN
1523      (REG_SEQUENCE VReg_64, VGPR_32:$data, sub0, VGPR_32:$cmp, sub1),
1524      VGPR_32:$vindex, SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1525      (set_glc $cachepolicy)), VReg_64)),
1526    sub0)
1527>;
1528
1529def : GCNPat<
1530  (SIbuffer_atomic_cmpswap
1531      i32:$data, i32:$cmp, v4i32:$rsrc, 0,
1532      i32:$voffset, i32:$soffset, timm:$offset,
1533      timm:$cachepolicy, 0),
1534  (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS
1535    (BUFFER_ATOMIC_CMPSWAP_OFFEN_RTN
1536      (REG_SEQUENCE VReg_64, VGPR_32:$data, sub0, VGPR_32:$cmp, sub1),
1537      VGPR_32:$voffset, SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1538      (set_glc $cachepolicy)), VReg_64)),
1539    sub0)
1540>;
1541
1542def : GCNPat<
1543  (SIbuffer_atomic_cmpswap
1544      i32:$data, i32:$cmp, v4i32:$rsrc, i32:$vindex,
1545      i32:$voffset, i32:$soffset, timm:$offset,
1546      timm:$cachepolicy, timm),
1547  (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS
1548    (BUFFER_ATOMIC_CMPSWAP_BOTHEN_RTN
1549      (REG_SEQUENCE VReg_64, VGPR_32:$data, sub0, VGPR_32:$cmp, sub1),
1550      (REG_SEQUENCE VReg_64, VGPR_32:$vindex, sub0, VGPR_32:$voffset, sub1),
1551      SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1552      (set_glc $cachepolicy)), VReg_64)),
1553    sub0)
1554>;
1555
1556class MUBUFLoad_PatternADDR64 <MUBUF_Pseudo Instr_ADDR64, ValueType vt,
1557                              PatFrag constant_ld> : GCNPat <
1558     (vt (constant_ld (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i32:$soffset,
1559                                   i16:$offset))),
1560     (Instr_ADDR64 $vaddr, $srsrc, $soffset, $offset)
1561  >;
1562
1563multiclass MUBUFLoad_Atomic_Pattern <MUBUF_Pseudo Instr_ADDR64, MUBUF_Pseudo Instr_OFFSET,
1564                                     ValueType vt, PatFrag atomic_ld> {
1565  def : GCNPat <
1566     (vt (atomic_ld (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i32:$soffset, i16:$offset))),
1567     (Instr_ADDR64 $vaddr, $srsrc, $soffset, $offset)
1568  >;
1569
1570  def : GCNPat <
1571    (vt (atomic_ld (MUBUFOffset v4i32:$rsrc, i32:$soffset, i16:$offset))),
1572    (Instr_OFFSET $rsrc, $soffset, (as_i16imm $offset))
1573  >;
1574}
1575
1576let SubtargetPredicate = isGFX6GFX7 in {
1577def : MUBUFLoad_PatternADDR64 <BUFFER_LOAD_SBYTE_ADDR64, i32, sextloadi8_constant>;
1578def : MUBUFLoad_PatternADDR64 <BUFFER_LOAD_UBYTE_ADDR64, i32, extloadi8_constant>;
1579def : MUBUFLoad_PatternADDR64 <BUFFER_LOAD_UBYTE_ADDR64, i32, zextloadi8_constant>;
1580def : MUBUFLoad_PatternADDR64 <BUFFER_LOAD_SSHORT_ADDR64, i32, sextloadi16_constant>;
1581def : MUBUFLoad_PatternADDR64 <BUFFER_LOAD_USHORT_ADDR64, i32, extloadi16_constant>;
1582def : MUBUFLoad_PatternADDR64 <BUFFER_LOAD_USHORT_ADDR64, i32, zextloadi16_constant>;
1583
1584defm : MUBUFLoad_Atomic_Pattern <BUFFER_LOAD_DWORD_ADDR64, BUFFER_LOAD_DWORD_OFFSET, i32, atomic_load_32_global>;
1585defm : MUBUFLoad_Atomic_Pattern <BUFFER_LOAD_DWORDX2_ADDR64, BUFFER_LOAD_DWORDX2_OFFSET, i64, atomic_load_64_global>;
1586} // End SubtargetPredicate = isGFX6GFX7
1587
1588multiclass MUBUFLoad_Pattern <MUBUF_Pseudo Instr_OFFSET, ValueType vt,
1589                               PatFrag ld> {
1590
1591  def : GCNPat <
1592    (vt (ld (MUBUFOffset v4i32:$srsrc, i32:$soffset, i16:$offset))),
1593    (Instr_OFFSET $srsrc, $soffset, $offset)
1594  >;
1595}
1596
1597let OtherPredicates = [Has16BitInsts] in {
1598
1599defm : MUBUFLoad_Pattern <BUFFER_LOAD_SBYTE_OFFSET, i16, sextloadi8_constant>;
1600defm : MUBUFLoad_Pattern <BUFFER_LOAD_UBYTE_OFFSET, i16, extloadi8_constant>;
1601defm : MUBUFLoad_Pattern <BUFFER_LOAD_UBYTE_OFFSET, i16, zextloadi8_constant>;
1602defm : MUBUFLoad_Pattern <BUFFER_LOAD_SBYTE_OFFSET, i16, sextloadi8_global>;
1603defm : MUBUFLoad_Pattern <BUFFER_LOAD_UBYTE_OFFSET, i16, extloadi8_global>;
1604defm : MUBUFLoad_Pattern <BUFFER_LOAD_UBYTE_OFFSET, i16, zextloadi8_global>;
1605
1606defm : MUBUFLoad_Pattern <BUFFER_LOAD_USHORT_OFFSET, i16, load_global>;
1607
1608} // End OtherPredicates = [Has16BitInsts]
1609
1610multiclass MUBUFScratchLoadPat <MUBUF_Pseudo InstrOffen,
1611                                MUBUF_Pseudo InstrOffset,
1612                                ValueType vt, PatFrag ld> {
1613  def : GCNPat <
1614    (vt (ld (MUBUFScratchOffen v4i32:$srsrc, i32:$vaddr,
1615                               i32:$soffset, u16imm:$offset))),
1616    (InstrOffen $vaddr, $srsrc, $soffset, $offset, 0, 0, 0)
1617  >;
1618
1619  def : GCNPat <
1620    (vt (ld (MUBUFScratchOffset v4i32:$srsrc, i32:$soffset, u16imm:$offset))),
1621    (InstrOffset $srsrc, $soffset, $offset, 0, 0, 0)
1622  >;
1623}
1624
1625// XXX - Is it possible to have a complex pattern in a PatFrag?
1626multiclass MUBUFScratchLoadPat_D16 <MUBUF_Pseudo InstrOffen,
1627                                MUBUF_Pseudo InstrOffset,
1628                                ValueType vt, PatFrag ld_frag> {
1629  def : GCNPat <
1630    (ld_frag (MUBUFScratchOffen v4i32:$srsrc, i32:$vaddr, i32:$soffset, u16imm:$offset), vt:$in),
1631    (InstrOffen $vaddr, $srsrc, $soffset, $offset, $in)
1632  >;
1633
1634  def : GCNPat <
1635    (ld_frag (MUBUFScratchOffset v4i32:$srsrc, i32:$soffset, u16imm:$offset), vt:$in),
1636    (InstrOffset $srsrc, $soffset, $offset, $in)
1637  >;
1638}
1639
1640let OtherPredicates = [DisableFlatScratch] in {
1641defm : MUBUFScratchLoadPat <BUFFER_LOAD_SBYTE_OFFEN, BUFFER_LOAD_SBYTE_OFFSET, i32, sextloadi8_private>;
1642defm : MUBUFScratchLoadPat <BUFFER_LOAD_UBYTE_OFFEN, BUFFER_LOAD_UBYTE_OFFSET, i32, extloadi8_private>;
1643defm : MUBUFScratchLoadPat <BUFFER_LOAD_UBYTE_OFFEN, BUFFER_LOAD_UBYTE_OFFSET, i32, zextloadi8_private>;
1644defm : MUBUFScratchLoadPat <BUFFER_LOAD_SBYTE_OFFEN, BUFFER_LOAD_SBYTE_OFFSET, i16, sextloadi8_private>;
1645defm : MUBUFScratchLoadPat <BUFFER_LOAD_UBYTE_OFFEN, BUFFER_LOAD_UBYTE_OFFSET, i16, extloadi8_private>;
1646defm : MUBUFScratchLoadPat <BUFFER_LOAD_UBYTE_OFFEN, BUFFER_LOAD_UBYTE_OFFSET, i16, zextloadi8_private>;
1647defm : MUBUFScratchLoadPat <BUFFER_LOAD_SSHORT_OFFEN, BUFFER_LOAD_SSHORT_OFFSET, i32, sextloadi16_private>;
1648defm : MUBUFScratchLoadPat <BUFFER_LOAD_USHORT_OFFEN, BUFFER_LOAD_USHORT_OFFSET, i32, extloadi16_private>;
1649defm : MUBUFScratchLoadPat <BUFFER_LOAD_USHORT_OFFEN, BUFFER_LOAD_USHORT_OFFSET, i32, zextloadi16_private>;
1650defm : MUBUFScratchLoadPat <BUFFER_LOAD_USHORT_OFFEN, BUFFER_LOAD_USHORT_OFFSET, i16, load_private>;
1651
1652foreach vt = Reg32Types.types in {
1653defm : MUBUFScratchLoadPat <BUFFER_LOAD_DWORD_OFFEN, BUFFER_LOAD_DWORD_OFFSET, vt, load_private>;
1654}
1655defm : MUBUFScratchLoadPat <BUFFER_LOAD_DWORDX2_OFFEN, BUFFER_LOAD_DWORDX2_OFFSET, v2i32, load_private>;
1656defm : MUBUFScratchLoadPat <BUFFER_LOAD_DWORDX3_OFFEN, BUFFER_LOAD_DWORDX3_OFFSET, v3i32, load_private>;
1657defm : MUBUFScratchLoadPat <BUFFER_LOAD_DWORDX4_OFFEN, BUFFER_LOAD_DWORDX4_OFFSET, v4i32, load_private>;
1658
1659let OtherPredicates = [D16PreservesUnusedBits, DisableFlatScratch] in {
1660defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_SHORT_D16_HI_OFFEN, BUFFER_LOAD_SHORT_D16_HI_OFFSET, v2i16, load_d16_hi_private>;
1661defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_UBYTE_D16_HI_OFFEN, BUFFER_LOAD_UBYTE_D16_HI_OFFSET, v2i16, az_extloadi8_d16_hi_private>;
1662defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_SBYTE_D16_HI_OFFEN, BUFFER_LOAD_SBYTE_D16_HI_OFFSET, v2i16, sextloadi8_d16_hi_private>;
1663defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_SHORT_D16_HI_OFFEN, BUFFER_LOAD_SHORT_D16_HI_OFFSET, v2f16, load_d16_hi_private>;
1664defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_UBYTE_D16_HI_OFFEN, BUFFER_LOAD_UBYTE_D16_HI_OFFSET, v2f16, az_extloadi8_d16_hi_private>;
1665defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_SBYTE_D16_HI_OFFEN, BUFFER_LOAD_SBYTE_D16_HI_OFFSET, v2f16, sextloadi8_d16_hi_private>;
1666
1667defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_SHORT_D16_OFFEN, BUFFER_LOAD_SHORT_D16_OFFSET, v2i16, load_d16_lo_private>;
1668defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_UBYTE_D16_OFFEN, BUFFER_LOAD_UBYTE_D16_OFFSET, v2i16, az_extloadi8_d16_lo_private>;
1669defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_SBYTE_D16_OFFEN, BUFFER_LOAD_SBYTE_D16_OFFSET, v2i16, sextloadi8_d16_lo_private>;
1670defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_SHORT_D16_OFFEN, BUFFER_LOAD_SHORT_D16_OFFSET, v2f16, load_d16_lo_private>;
1671defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_UBYTE_D16_OFFEN, BUFFER_LOAD_UBYTE_D16_OFFSET, v2f16, az_extloadi8_d16_lo_private>;
1672defm : MUBUFScratchLoadPat_D16<BUFFER_LOAD_SBYTE_D16_OFFEN, BUFFER_LOAD_SBYTE_D16_OFFSET, v2f16, sextloadi8_d16_lo_private>;
1673}
1674
1675} // End OtherPredicates = [DisableFlatScratch]
1676
1677multiclass MUBUFStore_Atomic_Pattern <MUBUF_Pseudo Instr_ADDR64, MUBUF_Pseudo Instr_OFFSET,
1678                                      ValueType vt, PatFrag atomic_st> {
1679  // Store follows atomic op convention so address is first
1680  def : GCNPat <
1681     (atomic_st (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i32:$soffset, i16:$offset), vt:$val),
1682     (Instr_ADDR64 $val, $vaddr, $srsrc, $soffset, $offset)
1683  >;
1684
1685  def : GCNPat <
1686    (atomic_st (MUBUFOffset v4i32:$rsrc, i32:$soffset, i16:$offset), vt:$val),
1687    (Instr_OFFSET $val, $rsrc, $soffset, (as_i16imm $offset))
1688  >;
1689}
1690let SubtargetPredicate = isGFX6GFX7 in {
1691defm : MUBUFStore_Atomic_Pattern <BUFFER_STORE_DWORD_ADDR64, BUFFER_STORE_DWORD_OFFSET, i32, atomic_store_global_32>;
1692defm : MUBUFStore_Atomic_Pattern <BUFFER_STORE_DWORDX2_ADDR64, BUFFER_STORE_DWORDX2_OFFSET, i64, atomic_store_global_64>;
1693} // End Predicates = isGFX6GFX7
1694
1695
1696multiclass MUBUFStore_Pattern <MUBUF_Pseudo Instr_OFFSET, ValueType vt,
1697                               PatFrag st> {
1698
1699  def : GCNPat <
1700    (st vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset, i16:$offset)),
1701    (Instr_OFFSET $vdata, $srsrc, $soffset, $offset)
1702  >;
1703}
1704
1705defm : MUBUFStore_Pattern <BUFFER_STORE_BYTE_OFFSET, i16, truncstorei8_global>;
1706defm : MUBUFStore_Pattern <BUFFER_STORE_SHORT_OFFSET, i16, store_global>;
1707
1708multiclass MUBUFScratchStorePat <MUBUF_Pseudo InstrOffen,
1709                                 MUBUF_Pseudo InstrOffset,
1710                                 ValueType vt, PatFrag st,
1711                                 RegisterClass rc = VGPR_32> {
1712  def : GCNPat <
1713    (st vt:$value, (MUBUFScratchOffen v4i32:$srsrc, i32:$vaddr,
1714                                      i32:$soffset, u16imm:$offset)),
1715    (InstrOffen rc:$value, $vaddr, $srsrc, $soffset, $offset, 0, 0, 0)
1716  >;
1717
1718  def : GCNPat <
1719    (st vt:$value, (MUBUFScratchOffset v4i32:$srsrc, i32:$soffset,
1720                                       u16imm:$offset)),
1721    (InstrOffset rc:$value, $srsrc, $soffset, $offset, 0, 0, 0)
1722  >;
1723}
1724
1725let OtherPredicates = [DisableFlatScratch] in {
1726defm : MUBUFScratchStorePat <BUFFER_STORE_BYTE_OFFEN, BUFFER_STORE_BYTE_OFFSET, i32, truncstorei8_private>;
1727defm : MUBUFScratchStorePat <BUFFER_STORE_SHORT_OFFEN, BUFFER_STORE_SHORT_OFFSET, i32, truncstorei16_private>;
1728defm : MUBUFScratchStorePat <BUFFER_STORE_BYTE_OFFEN, BUFFER_STORE_BYTE_OFFSET, i16, truncstorei8_private>;
1729defm : MUBUFScratchStorePat <BUFFER_STORE_SHORT_OFFEN, BUFFER_STORE_SHORT_OFFSET, i16, store_private>;
1730
1731foreach vt = Reg32Types.types in {
1732defm : MUBUFScratchStorePat <BUFFER_STORE_DWORD_OFFEN, BUFFER_STORE_DWORD_OFFSET, vt, store_private>;
1733}
1734
1735defm : MUBUFScratchStorePat <BUFFER_STORE_DWORDX2_OFFEN, BUFFER_STORE_DWORDX2_OFFSET, v2i32, store_private, VReg_64>;
1736defm : MUBUFScratchStorePat <BUFFER_STORE_DWORDX3_OFFEN, BUFFER_STORE_DWORDX3_OFFSET, v3i32, store_private, VReg_96>;
1737defm : MUBUFScratchStorePat <BUFFER_STORE_DWORDX4_OFFEN, BUFFER_STORE_DWORDX4_OFFSET, v4i32, store_private, VReg_128>;
1738
1739
1740let OtherPredicates = [D16PreservesUnusedBits, DisableFlatScratch] in {
1741 // Hiding the extract high pattern in the PatFrag seems to not
1742 // automatically increase the complexity.
1743let AddedComplexity = 1 in {
1744defm : MUBUFScratchStorePat <BUFFER_STORE_SHORT_D16_HI_OFFEN, BUFFER_STORE_SHORT_D16_HI_OFFSET, i32, store_hi16_private>;
1745defm : MUBUFScratchStorePat <BUFFER_STORE_BYTE_D16_HI_OFFEN, BUFFER_STORE_BYTE_D16_HI_OFFSET, i32, truncstorei8_hi16_private>;
1746}
1747}
1748} // End OtherPredicates = [DisableFlatScratch]
1749
1750//===----------------------------------------------------------------------===//
1751// MTBUF Patterns
1752//===----------------------------------------------------------------------===//
1753
1754//===----------------------------------------------------------------------===//
1755// tbuffer_load/store_format patterns
1756//===----------------------------------------------------------------------===//
1757
1758multiclass MTBUF_LoadIntrinsicPat<SDPatternOperator name, ValueType vt,
1759                                  string opcode, ValueType memoryVt = vt> {
1760  defvar st = !if(!eq(!cast<string>(memoryVt), !cast<string>(vt)), name, mtbuf_intrinsic_load<name, memoryVt>);
1761
1762  def : GCNPat<
1763    (vt (st v4i32:$rsrc, 0, 0, i32:$soffset, timm:$offset,
1764              timm:$format, timm:$auxiliary, 0)),
1765    (!cast<MTBUF_Pseudo>(opcode # _OFFSET) SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1766      (as_i8timm $format),
1767      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1768  >;
1769
1770  def : GCNPat<
1771    (vt (st v4i32:$rsrc, i32:$vindex, 0, i32:$soffset, timm:$offset,
1772              timm:$format, timm:$auxiliary, timm)),
1773    (!cast<MTBUF_Pseudo>(opcode # _IDXEN) VGPR_32:$vindex, SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1774      (as_i8timm $format),
1775      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1776  >;
1777
1778  def : GCNPat<
1779    (vt (st v4i32:$rsrc, 0, i32:$voffset, i32:$soffset, timm:$offset,
1780              timm:$format, timm:$auxiliary, 0)),
1781    (!cast<MTBUF_Pseudo>(opcode # _OFFEN) VGPR_32:$voffset, SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1782      (as_i8timm $format),
1783      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1784  >;
1785
1786  def : GCNPat<
1787    (vt (st v4i32:$rsrc, i32:$vindex, i32:$voffset, i32:$soffset, timm:$offset,
1788              timm:$format, timm:$auxiliary, timm)),
1789    (!cast<MTBUF_Pseudo>(opcode # _BOTHEN)
1790      (REG_SEQUENCE VReg_64, VGPR_32:$vindex, sub0, VGPR_32:$voffset, sub1),
1791      SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset),
1792      (as_i8timm $format),
1793      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1794  >;
1795}
1796
1797defm : MTBUF_LoadIntrinsicPat<SItbuffer_load, i32,   "TBUFFER_LOAD_FORMAT_X">;
1798defm : MTBUF_LoadIntrinsicPat<SItbuffer_load, v2i32, "TBUFFER_LOAD_FORMAT_XY">;
1799defm : MTBUF_LoadIntrinsicPat<SItbuffer_load, v3i32, "TBUFFER_LOAD_FORMAT_XYZ">;
1800defm : MTBUF_LoadIntrinsicPat<SItbuffer_load, v4i32, "TBUFFER_LOAD_FORMAT_XYZW">;
1801defm : MTBUF_LoadIntrinsicPat<SItbuffer_load, f32,   "TBUFFER_LOAD_FORMAT_X">;
1802defm : MTBUF_LoadIntrinsicPat<SItbuffer_load, v2f32, "TBUFFER_LOAD_FORMAT_XY">;
1803defm : MTBUF_LoadIntrinsicPat<SItbuffer_load, v3f32, "TBUFFER_LOAD_FORMAT_XYZ">;
1804defm : MTBUF_LoadIntrinsicPat<SItbuffer_load, v4f32, "TBUFFER_LOAD_FORMAT_XYZW">;
1805
1806let SubtargetPredicate = HasUnpackedD16VMem in {
1807  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, f16,   "TBUFFER_LOAD_FORMAT_D16_X_gfx80">;
1808  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, i32,   "TBUFFER_LOAD_FORMAT_D16_X_gfx80">;
1809  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, v2i32, "TBUFFER_LOAD_FORMAT_D16_XY_gfx80">;
1810  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, v3i32, "TBUFFER_LOAD_FORMAT_D16_XYZ_gfx80">;
1811  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, v4i32, "TBUFFER_LOAD_FORMAT_D16_XYZW_gfx80">;
1812} // End HasUnpackedD16VMem.
1813
1814let SubtargetPredicate = HasPackedD16VMem in {
1815  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, f16,   "TBUFFER_LOAD_FORMAT_D16_X">;
1816  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, i32,   "TBUFFER_LOAD_FORMAT_D16_X">;
1817  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, v2f16, "TBUFFER_LOAD_FORMAT_D16_XY">;
1818  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, v4f16, "TBUFFER_LOAD_FORMAT_D16_XYZ", v3f16>;
1819  defm : MTBUF_LoadIntrinsicPat<SItbuffer_load_d16, v4f16, "TBUFFER_LOAD_FORMAT_D16_XYZW">;
1820} // End HasPackedD16VMem.
1821
1822multiclass MTBUF_StoreIntrinsicPat<SDPatternOperator name, ValueType vt,
1823                                        string opcode, ValueType memoryVt = vt> {
1824  defvar st = !if(!eq(!cast<string>(memoryVt), !cast<string>(vt)), name, mtbuf_intrinsic_store<name, memoryVt>);
1825
1826  def : GCNPat<
1827    (st vt:$vdata, v4i32:$rsrc, 0, 0, i32:$soffset, timm:$offset,
1828          timm:$format, timm:$auxiliary, 0),
1829    (!cast<MTBUF_Pseudo>(opcode # _OFFSET_exact) getVregSrcForVT<vt>.ret:$vdata, SReg_128:$rsrc, SCSrc_b32:$soffset,
1830      (as_i16timm $offset), (as_i8timm $format),
1831      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1832  >;
1833
1834  def : GCNPat<
1835    (st vt:$vdata, v4i32:$rsrc, i32:$vindex, 0, i32:$soffset, timm:$offset,
1836          timm:$format, timm:$auxiliary, timm),
1837    (!cast<MTBUF_Pseudo>(opcode # _IDXEN_exact) getVregSrcForVT<vt>.ret:$vdata, VGPR_32:$vindex, SReg_128:$rsrc, SCSrc_b32:$soffset,
1838      (as_i16timm $offset), (as_i8timm $format),
1839      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1840  >;
1841
1842  def : GCNPat<
1843    (st vt:$vdata, v4i32:$rsrc, 0, i32:$voffset, i32:$soffset, timm:$offset,
1844          timm:$format, timm:$auxiliary, 0),
1845    (!cast<MTBUF_Pseudo>(opcode # _OFFEN_exact) getVregSrcForVT<vt>.ret:$vdata, VGPR_32:$voffset, SReg_128:$rsrc, SCSrc_b32:$soffset,
1846      (as_i16timm $offset), (as_i8timm $format),
1847      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1848  >;
1849
1850  def : GCNPat<
1851    (st vt:$vdata, v4i32:$rsrc, i32:$vindex, i32:$voffset, i32:$soffset,
1852          timm:$offset, timm:$format, timm:$auxiliary, timm),
1853    (!cast<MTBUF_Pseudo>(opcode # _BOTHEN_exact)
1854      getVregSrcForVT<vt>.ret:$vdata,
1855      (REG_SEQUENCE VReg_64, VGPR_32:$vindex, sub0, VGPR_32:$voffset, sub1),
1856      SReg_128:$rsrc, SCSrc_b32:$soffset, (as_i16timm $offset), (as_i8timm $format),
1857      (extract_cpol $auxiliary), 0, (extract_swz $auxiliary))
1858  >;
1859}
1860
1861defm : MTBUF_StoreIntrinsicPat<SItbuffer_store, i32,   "TBUFFER_STORE_FORMAT_X">;
1862defm : MTBUF_StoreIntrinsicPat<SItbuffer_store, v2i32, "TBUFFER_STORE_FORMAT_XY">;
1863defm : MTBUF_StoreIntrinsicPat<SItbuffer_store, v3i32, "TBUFFER_STORE_FORMAT_XYZ">;
1864defm : MTBUF_StoreIntrinsicPat<SItbuffer_store, v4i32, "TBUFFER_STORE_FORMAT_XYZW">;
1865defm : MTBUF_StoreIntrinsicPat<SItbuffer_store, f32,   "TBUFFER_STORE_FORMAT_X">;
1866defm : MTBUF_StoreIntrinsicPat<SItbuffer_store, v2f32, "TBUFFER_STORE_FORMAT_XY">;
1867defm : MTBUF_StoreIntrinsicPat<SItbuffer_store, v3f32, "TBUFFER_STORE_FORMAT_XYZ">;
1868defm : MTBUF_StoreIntrinsicPat<SItbuffer_store, v4f32, "TBUFFER_STORE_FORMAT_XYZW">;
1869
1870let SubtargetPredicate = HasUnpackedD16VMem in {
1871  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, f16,   "TBUFFER_STORE_FORMAT_D16_X_gfx80">;
1872  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, i32,   "TBUFFER_STORE_FORMAT_D16_X_gfx80">;
1873  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, v2i32, "TBUFFER_STORE_FORMAT_D16_XY_gfx80">;
1874  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, v3i32, "TBUFFER_STORE_FORMAT_D16_XYZ_gfx80">;
1875  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, v4i32, "TBUFFER_STORE_FORMAT_D16_XYZW_gfx80">;
1876} // End HasUnpackedD16VMem.
1877
1878let SubtargetPredicate = HasPackedD16VMem in {
1879  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, f16,   "TBUFFER_STORE_FORMAT_D16_X">;
1880  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, i32,   "TBUFFER_STORE_FORMAT_D16_X">;
1881  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, v2f16, "TBUFFER_STORE_FORMAT_D16_XY">;
1882  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, v4f16, "TBUFFER_STORE_FORMAT_D16_XYZ", v3f16>;
1883  defm : MTBUF_StoreIntrinsicPat<SItbuffer_store_d16, v4f16, "TBUFFER_STORE_FORMAT_D16_XYZW">;
1884} // End HasPackedD16VMem.
1885
1886//===----------------------------------------------------------------------===//
1887// Target-specific instruction encodings.
1888//===----------------------------------------------------------------------===//
1889
1890//===----------------------------------------------------------------------===//
1891// Base ENC_MUBUF for GFX6, GFX7, GFX10.
1892//===----------------------------------------------------------------------===//
1893
1894class Base_MUBUF_Real_gfx6_gfx7_gfx10<bits<7> op, MUBUF_Pseudo ps, int ef> :
1895    MUBUF_Real<ps>, Enc64, SIMCInstr<ps.PseudoInstr, ef> {
1896  let Inst{11-0}  = !if(ps.has_offset, offset, ?);
1897  let Inst{12}    = ps.offen;
1898  let Inst{13}    = ps.idxen;
1899  let Inst{14}    = !if(ps.has_glc, cpol{CPolBit.GLC}, ps.glc_value);
1900  let Inst{16}    = ps.lds;
1901  let Inst{24-18} = op;
1902  let Inst{31-26} = 0x38;
1903  let Inst{39-32} = !if(ps.has_vaddr, vaddr, ?);
1904  let Inst{47-40} = !if(ps.has_vdata, vdata{7-0}, ?);
1905  let Inst{52-48} = !if(ps.has_srsrc, srsrc{6-2}, ?);
1906  let Inst{54}    = !if(ps.has_slc, cpol{CPolBit.SLC}, ?);
1907  let Inst{55}    = !if(ps.has_tfe, tfe, ?);
1908  let Inst{63-56} = !if(ps.has_soffset, soffset, ?);
1909}
1910
1911class MUBUF_Real_gfx10<bits<8> op, MUBUF_Pseudo ps> :
1912    Base_MUBUF_Real_gfx6_gfx7_gfx10<op{6-0}, ps, SIEncodingFamily.GFX10> {
1913  let Inst{15} = !if(ps.has_dlc, cpol{CPolBit.DLC}, ps.dlc_value);
1914  let Inst{25} = op{7};
1915}
1916
1917class MUBUF_Real_gfx6_gfx7<bits<8> op, MUBUF_Pseudo ps> :
1918    Base_MUBUF_Real_gfx6_gfx7_gfx10<op{6-0}, ps, SIEncodingFamily.SI> {
1919  let Inst{15} = ps.addr64;
1920}
1921
1922//===----------------------------------------------------------------------===//
1923// MUBUF - GFX10.
1924//===----------------------------------------------------------------------===//
1925
1926let AssemblerPredicate = isGFX10Plus, DecoderNamespace = "GFX10" in {
1927  multiclass MUBUF_Real_gfx10_with_name<bits<8> op, string opName,
1928                                        string asmName> {
1929    def _gfx10 : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(opName)> {
1930      MUBUF_Pseudo ps = !cast<MUBUF_Pseudo>(opName);
1931      let AsmString = asmName # ps.AsmOperands;
1932    }
1933  }
1934  multiclass MUBUF_Real_AllAddr_gfx10<bits<8> op> {
1935    def _BOTHEN_gfx10 :
1936      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>;
1937    def _IDXEN_gfx10 :
1938      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>;
1939    def _OFFEN_gfx10 :
1940      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>;
1941    def _OFFSET_gfx10 :
1942      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>;
1943  }
1944  multiclass MUBUF_Real_AllAddr_Lds_gfx10<bits<8> op> {
1945    def _OFFSET_gfx10 : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>,
1946                        MUBUFLdsTable<0, NAME # "_OFFSET_gfx10">;
1947    def _OFFEN_gfx10  : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>,
1948                        MUBUFLdsTable<0, NAME # "_OFFEN_gfx10">;
1949    def _IDXEN_gfx10  : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>,
1950                        MUBUFLdsTable<0, NAME # "_IDXEN_gfx10">;
1951    def _BOTHEN_gfx10 : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>,
1952                        MUBUFLdsTable<0, NAME # "_BOTHEN_gfx10">;
1953
1954    def _LDS_OFFSET_gfx10 : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_OFFSET")>,
1955                            MUBUFLdsTable<1, NAME # "_OFFSET_gfx10">;
1956    def _LDS_OFFEN_gfx10  : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_OFFEN")>,
1957                            MUBUFLdsTable<1, NAME # "_OFFEN_gfx10">;
1958    def _LDS_IDXEN_gfx10  : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_IDXEN")>,
1959                            MUBUFLdsTable<1, NAME # "_IDXEN_gfx10">;
1960    def _LDS_BOTHEN_gfx10 : MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_BOTHEN")>,
1961                            MUBUFLdsTable<1, NAME # "_BOTHEN_gfx10">;
1962  }
1963  multiclass MUBUF_Real_Atomics_RTN_gfx10<bits<8> op> {
1964    def _BOTHEN_RTN_gfx10 :
1965      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN_RTN")>,
1966      AtomicNoRet<NAME # "_BOTHEN_gfx10", 1>;
1967    def _IDXEN_RTN_gfx10 :
1968      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN_RTN")>,
1969      AtomicNoRet<NAME # "_IDXEN_gfx10", 1>;
1970    def _OFFEN_RTN_gfx10 :
1971      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN_RTN")>,
1972      AtomicNoRet<NAME # "_OFFEN_gfx10", 1>;
1973    def _OFFSET_RTN_gfx10 :
1974      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET_RTN")>,
1975      AtomicNoRet<NAME # "_OFFSET_gfx10", 1>;
1976  }
1977  multiclass MUBUF_Real_Atomics_gfx10<bits<8> op> :
1978      MUBUF_Real_Atomics_RTN_gfx10<op> {
1979    def _BOTHEN_gfx10 :
1980      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>,
1981      AtomicNoRet<NAME # "_BOTHEN_gfx10", 0>;
1982    def _IDXEN_gfx10 :
1983      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>,
1984      AtomicNoRet<NAME # "_IDXEN_gfx10", 0>;
1985    def _OFFEN_gfx10 :
1986      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>,
1987      AtomicNoRet<NAME # "_OFFEN_gfx10", 0>;
1988    def _OFFSET_gfx10 :
1989      MUBUF_Real_gfx10<op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>,
1990      AtomicNoRet<NAME # "_OFFSET_gfx10", 0>;
1991  }
1992} // End AssemblerPredicate = isGFX10Plus, DecoderNamespace = "GFX10"
1993
1994defm BUFFER_STORE_BYTE_D16_HI     : MUBUF_Real_AllAddr_gfx10<0x019>;
1995defm BUFFER_STORE_SHORT_D16_HI    : MUBUF_Real_AllAddr_gfx10<0x01b>;
1996defm BUFFER_LOAD_UBYTE_D16        : MUBUF_Real_AllAddr_gfx10<0x020>;
1997defm BUFFER_LOAD_UBYTE_D16_HI     : MUBUF_Real_AllAddr_gfx10<0x021>;
1998defm BUFFER_LOAD_SBYTE_D16        : MUBUF_Real_AllAddr_gfx10<0x022>;
1999defm BUFFER_LOAD_SBYTE_D16_HI     : MUBUF_Real_AllAddr_gfx10<0x023>;
2000defm BUFFER_LOAD_SHORT_D16        : MUBUF_Real_AllAddr_gfx10<0x024>;
2001defm BUFFER_LOAD_SHORT_D16_HI     : MUBUF_Real_AllAddr_gfx10<0x025>;
2002// FIXME-GFX10: Add following instructions:
2003//defm BUFFER_LOAD_FORMAT_D16_HI_X  : MUBUF_Real_AllAddr_gfx10<0x026>;
2004//defm BUFFER_STORE_FORMAT_D16_HI_X : MUBUF_Real_AllAddr_gfx10<0x027>;
2005defm BUFFER_LOAD_FORMAT_D16_X     : MUBUF_Real_AllAddr_gfx10<0x080>;
2006defm BUFFER_LOAD_FORMAT_D16_XY    : MUBUF_Real_AllAddr_gfx10<0x081>;
2007defm BUFFER_LOAD_FORMAT_D16_XYZ   : MUBUF_Real_AllAddr_gfx10<0x082>;
2008defm BUFFER_LOAD_FORMAT_D16_XYZW  : MUBUF_Real_AllAddr_gfx10<0x083>;
2009defm BUFFER_STORE_FORMAT_D16_X    : MUBUF_Real_AllAddr_gfx10<0x084>;
2010defm BUFFER_STORE_FORMAT_D16_XY   : MUBUF_Real_AllAddr_gfx10<0x085>;
2011defm BUFFER_STORE_FORMAT_D16_XYZ  : MUBUF_Real_AllAddr_gfx10<0x086>;
2012defm BUFFER_STORE_FORMAT_D16_XYZW : MUBUF_Real_AllAddr_gfx10<0x087>;
2013
2014def BUFFER_GL0_INV_gfx10 :
2015  MUBUF_Real_gfx10<0x071, BUFFER_GL0_INV>;
2016def BUFFER_GL1_INV_gfx10 :
2017  MUBUF_Real_gfx10<0x072, BUFFER_GL1_INV>;
2018
2019//===----------------------------------------------------------------------===//
2020// MUBUF - GFX6, GFX7, GFX10.
2021//===----------------------------------------------------------------------===//
2022
2023let AssemblerPredicate = isGFX6, DecoderNamespace = "GFX6" in {
2024  multiclass MUBUF_Real_gfx6<bits<8> op> {
2025    def _gfx6 : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME)>;
2026  }
2027} // End AssemblerPredicate = isGFX6, DecoderNamespace = "GFX6"
2028
2029let AssemblerPredicate = isGFX7Only, DecoderNamespace = "GFX7" in {
2030  multiclass MUBUF_Real_gfx7<bits<8> op> {
2031    def _gfx7 : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME)>;
2032  }
2033} // End AssemblerPredicate = isGFX7Only, DecoderNamespace = "GFX7"
2034
2035let AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" in {
2036  multiclass MUBUF_Real_AllAddr_gfx6_gfx7<bits<8> op> {
2037    def _ADDR64_gfx6_gfx7 :
2038      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_ADDR64")>;
2039    def _BOTHEN_gfx6_gfx7 :
2040      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>;
2041    def _IDXEN_gfx6_gfx7 :
2042      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>;
2043    def _OFFEN_gfx6_gfx7 :
2044      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>;
2045    def _OFFSET_gfx6_gfx7 :
2046      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>;
2047  }
2048  multiclass MUBUF_Real_AllAddr_Lds_gfx6_gfx7<bits<8> op> {
2049    def _OFFSET_gfx6_gfx7 : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>,
2050                            MUBUFLdsTable<0, NAME # "_OFFSET_gfx6_gfx7">;
2051    def _ADDR64_gfx6_gfx7 : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_ADDR64")>,
2052                            MUBUFLdsTable<0, NAME # "_ADDR64_gfx6_gfx7">;
2053    def _OFFEN_gfx6_gfx7  : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>,
2054                            MUBUFLdsTable<0, NAME # "_OFFEN_gfx6_gfx7">;
2055    def _IDXEN_gfx6_gfx7  : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>,
2056                            MUBUFLdsTable<0, NAME # "_IDXEN_gfx6_gfx7">;
2057    def _BOTHEN_gfx6_gfx7 : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>,
2058                            MUBUFLdsTable<0, NAME # "_BOTHEN_gfx6_gfx7">;
2059
2060    def _LDS_OFFSET_gfx6_gfx7 : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_OFFSET")>,
2061                                MUBUFLdsTable<1, NAME # "_OFFSET_gfx6_gfx7">;
2062    def _LDS_ADDR64_gfx6_gfx7 : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_ADDR64")>,
2063                                MUBUFLdsTable<1, NAME # "_ADDR64_gfx6_gfx7">;
2064    def _LDS_OFFEN_gfx6_gfx7  : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_OFFEN")>,
2065                                MUBUFLdsTable<1, NAME # "_OFFEN_gfx6_gfx7">;
2066    def _LDS_IDXEN_gfx6_gfx7  : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_IDXEN")>,
2067                                MUBUFLdsTable<1, NAME # "_IDXEN_gfx6_gfx7">;
2068    def _LDS_BOTHEN_gfx6_gfx7 : MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_LDS_BOTHEN")>,
2069                                MUBUFLdsTable<1, NAME # "_BOTHEN_gfx6_gfx7">;
2070  }
2071  multiclass MUBUF_Real_Atomics_gfx6_gfx7<bits<8> op> {
2072    def _ADDR64_gfx6_gfx7 :
2073      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_ADDR64")>,
2074      AtomicNoRet<NAME # "_ADDR64_gfx6_gfx7", 0>;
2075    def _BOTHEN_gfx6_gfx7 :
2076      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>,
2077      AtomicNoRet<NAME # "_BOTHEN_gfx6_gfx7", 0>;
2078    def _IDXEN_gfx6_gfx7 :
2079      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>,
2080      AtomicNoRet<NAME # "_IDXEN_gfx6_gfx7", 0>;
2081    def _OFFEN_gfx6_gfx7 :
2082      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>,
2083      AtomicNoRet<NAME # "_OFFEN_gfx6_gfx7", 0>;
2084    def _OFFSET_gfx6_gfx7 :
2085      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>,
2086      AtomicNoRet<NAME # "_OFFSET_gfx6_gfx7", 0>;
2087
2088    def _ADDR64_RTN_gfx6_gfx7 :
2089      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_ADDR64_RTN")>,
2090      AtomicNoRet<NAME # "_ADDR64_gfx6_gfx7", 1>;
2091    def _BOTHEN_RTN_gfx6_gfx7 :
2092      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN_RTN")>,
2093      AtomicNoRet<NAME # "_BOTHEN_gfx6_gfx7", 1>;
2094    def _IDXEN_RTN_gfx6_gfx7 :
2095      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN_RTN")>,
2096      AtomicNoRet<NAME # "_IDXEN_gfx6_gfx7", 1>;
2097    def _OFFEN_RTN_gfx6_gfx7 :
2098      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN_RTN")>,
2099      AtomicNoRet<NAME # "_OFFEN_gfx6_gfx7", 1>;
2100    def _OFFSET_RTN_gfx6_gfx7 :
2101      MUBUF_Real_gfx6_gfx7<op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET_RTN")>,
2102      AtomicNoRet<NAME # "_OFFSET_gfx6_gfx7", 1>;
2103  }
2104} // End AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7"
2105
2106multiclass MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<bits<8> op> :
2107  MUBUF_Real_AllAddr_gfx6_gfx7<op>, MUBUF_Real_AllAddr_gfx10<op>;
2108
2109multiclass MUBUF_Real_AllAddr_Lds_gfx6_gfx7_gfx10<bits<8> op> :
2110  MUBUF_Real_AllAddr_Lds_gfx6_gfx7<op>, MUBUF_Real_AllAddr_Lds_gfx10<op>;
2111
2112multiclass MUBUF_Real_Atomics_gfx6_gfx7_gfx10<bits<8> op> :
2113  MUBUF_Real_Atomics_gfx6_gfx7<op>, MUBUF_Real_Atomics_gfx10<op>;
2114
2115// FIXME-GFX6: Following instructions are available only on GFX6.
2116//defm BUFFER_ATOMIC_RSUB         : MUBUF_Real_Atomics_gfx6 <0x034>;
2117//defm BUFFER_ATOMIC_RSUB_X2      : MUBUF_Real_Atomics_gfx6 <0x054>;
2118
2119defm BUFFER_LOAD_FORMAT_X     : MUBUF_Real_AllAddr_Lds_gfx6_gfx7_gfx10<0x000>;
2120defm BUFFER_LOAD_FORMAT_XY    : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x001>;
2121defm BUFFER_LOAD_FORMAT_XYZ   : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x002>;
2122defm BUFFER_LOAD_FORMAT_XYZW  : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x003>;
2123defm BUFFER_STORE_FORMAT_X    : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x004>;
2124defm BUFFER_STORE_FORMAT_XY   : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x005>;
2125defm BUFFER_STORE_FORMAT_XYZ  : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x006>;
2126defm BUFFER_STORE_FORMAT_XYZW : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x007>;
2127defm BUFFER_LOAD_UBYTE        : MUBUF_Real_AllAddr_Lds_gfx6_gfx7_gfx10<0x008>;
2128defm BUFFER_LOAD_SBYTE        : MUBUF_Real_AllAddr_Lds_gfx6_gfx7_gfx10<0x009>;
2129defm BUFFER_LOAD_USHORT       : MUBUF_Real_AllAddr_Lds_gfx6_gfx7_gfx10<0x00a>;
2130defm BUFFER_LOAD_SSHORT       : MUBUF_Real_AllAddr_Lds_gfx6_gfx7_gfx10<0x00b>;
2131defm BUFFER_LOAD_DWORD        : MUBUF_Real_AllAddr_Lds_gfx6_gfx7_gfx10<0x00c>;
2132defm BUFFER_LOAD_DWORDX2      : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x00d>;
2133defm BUFFER_LOAD_DWORDX4      : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x00e>;
2134defm BUFFER_LOAD_DWORDX3      : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x00f>;
2135defm BUFFER_STORE_BYTE        : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x018>;
2136defm BUFFER_STORE_SHORT       : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x01a>;
2137defm BUFFER_STORE_DWORD       : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x01c>;
2138defm BUFFER_STORE_DWORDX2     : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x01d>;
2139defm BUFFER_STORE_DWORDX4     : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x01e>;
2140defm BUFFER_STORE_DWORDX3     : MUBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x01f>;
2141
2142defm BUFFER_ATOMIC_SWAP        : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x030>;
2143defm BUFFER_ATOMIC_CMPSWAP     : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x031>;
2144defm BUFFER_ATOMIC_ADD         : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x032>;
2145defm BUFFER_ATOMIC_SUB         : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x033>;
2146defm BUFFER_ATOMIC_SMIN        : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x035>;
2147defm BUFFER_ATOMIC_UMIN        : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x036>;
2148defm BUFFER_ATOMIC_SMAX        : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x037>;
2149defm BUFFER_ATOMIC_UMAX        : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x038>;
2150defm BUFFER_ATOMIC_AND         : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x039>;
2151defm BUFFER_ATOMIC_OR          : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x03a>;
2152defm BUFFER_ATOMIC_XOR         : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x03b>;
2153defm BUFFER_ATOMIC_INC         : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x03c>;
2154defm BUFFER_ATOMIC_DEC         : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x03d>;
2155defm BUFFER_ATOMIC_FCMPSWAP    : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x03e>;
2156defm BUFFER_ATOMIC_FMIN        : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x03f>;
2157defm BUFFER_ATOMIC_FMAX        : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x040>;
2158defm BUFFER_ATOMIC_SWAP_X2     : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x050>;
2159defm BUFFER_ATOMIC_CMPSWAP_X2  : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x051>;
2160defm BUFFER_ATOMIC_ADD_X2      : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x052>;
2161defm BUFFER_ATOMIC_SUB_X2      : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x053>;
2162defm BUFFER_ATOMIC_SMIN_X2     : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x055>;
2163defm BUFFER_ATOMIC_UMIN_X2     : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x056>;
2164defm BUFFER_ATOMIC_SMAX_X2     : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x057>;
2165defm BUFFER_ATOMIC_UMAX_X2     : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x058>;
2166defm BUFFER_ATOMIC_AND_X2      : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x059>;
2167defm BUFFER_ATOMIC_OR_X2       : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x05a>;
2168defm BUFFER_ATOMIC_XOR_X2      : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x05b>;
2169defm BUFFER_ATOMIC_INC_X2      : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x05c>;
2170defm BUFFER_ATOMIC_DEC_X2      : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x05d>;
2171// FIXME-GFX7: Need to handle hazard for BUFFER_ATOMIC_FCMPSWAP_X2 on GFX7.
2172defm BUFFER_ATOMIC_FCMPSWAP_X2 : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x05e>;
2173defm BUFFER_ATOMIC_FMIN_X2     : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x05f>;
2174defm BUFFER_ATOMIC_FMAX_X2     : MUBUF_Real_Atomics_gfx6_gfx7_gfx10<0x060>;
2175
2176defm BUFFER_ATOMIC_CSUB       : MUBUF_Real_Atomics_RTN_gfx10<0x034>;
2177
2178defm BUFFER_WBINVL1_SC        : MUBUF_Real_gfx6<0x070>;
2179defm BUFFER_WBINVL1_VOL       : MUBUF_Real_gfx7<0x070>;
2180def  BUFFER_WBINVL1_gfx6_gfx7 : MUBUF_Real_gfx6_gfx7<0x071, BUFFER_WBINVL1>;
2181
2182//===----------------------------------------------------------------------===//
2183// Base ENC_MTBUF for GFX6, GFX7, GFX10.
2184//===----------------------------------------------------------------------===//
2185
2186class Base_MTBUF_Real_gfx6_gfx7_gfx10<bits<3> op, MTBUF_Pseudo ps, int ef> :
2187    MTBUF_Real<ps>, Enc64, SIMCInstr<ps.PseudoInstr, ef> {
2188  let Inst{11-0}  = !if(ps.has_offset, offset, ?);
2189  let Inst{12}    = ps.offen;
2190  let Inst{13}    = ps.idxen;
2191  let Inst{14}    = !if(ps.has_glc, cpol{CPolBit.GLC}, ps.glc_value);
2192  let Inst{18-16} = op;
2193  let Inst{31-26} = 0x3a; //encoding
2194  let Inst{39-32} = !if(ps.has_vaddr, vaddr, ?);
2195  let Inst{47-40} = !if(ps.has_vdata, vdata{7-0}, ?);
2196  let Inst{52-48} = !if(ps.has_srsrc, srsrc{6-2}, ?);
2197  let Inst{54}    = !if(ps.has_slc, cpol{CPolBit.SLC}, ?);
2198  let Inst{55}    = !if(ps.has_tfe, tfe, ?);
2199  let Inst{63-56} = !if(ps.has_soffset, soffset, ?);
2200}
2201
2202//===----------------------------------------------------------------------===//
2203// MTBUF - GFX10.
2204//===----------------------------------------------------------------------===//
2205
2206class MTBUF_Real_gfx10<bits<4> op, MTBUF_Pseudo ps> :
2207    Base_MTBUF_Real_gfx6_gfx7_gfx10<op{2-0}, ps, SIEncodingFamily.GFX10> {
2208  let Inst{15} = !if(ps.has_dlc, cpol{CPolBit.DLC}, ps.dlc_value);
2209  let Inst{25-19} = format;
2210  let Inst{53} = op{3};
2211}
2212
2213let AssemblerPredicate = isGFX10Plus, DecoderNamespace = "GFX10" in {
2214  multiclass MTBUF_Real_AllAddr_gfx10<bits<4> op> {
2215    def _BOTHEN_gfx10 :
2216      MTBUF_Real_gfx10<op, !cast<MTBUF_Pseudo>(NAME#"_BOTHEN")>;
2217    def _IDXEN_gfx10 :
2218      MTBUF_Real_gfx10<op, !cast<MTBUF_Pseudo>(NAME#"_IDXEN")>;
2219    def _OFFEN_gfx10 :
2220      MTBUF_Real_gfx10<op, !cast<MTBUF_Pseudo>(NAME#"_OFFEN")>;
2221    def _OFFSET_gfx10 :
2222      MTBUF_Real_gfx10<op, !cast<MTBUF_Pseudo>(NAME#"_OFFSET")>;
2223  }
2224} // End AssemblerPredicate = isGFX10Plus, DecoderNamespace = "GFX10"
2225
2226defm TBUFFER_LOAD_FORMAT_D16_X     : MTBUF_Real_AllAddr_gfx10<0x008>;
2227defm TBUFFER_LOAD_FORMAT_D16_XY    : MTBUF_Real_AllAddr_gfx10<0x009>;
2228defm TBUFFER_LOAD_FORMAT_D16_XYZ   : MTBUF_Real_AllAddr_gfx10<0x00a>;
2229defm TBUFFER_LOAD_FORMAT_D16_XYZW  : MTBUF_Real_AllAddr_gfx10<0x00b>;
2230defm TBUFFER_STORE_FORMAT_D16_X    : MTBUF_Real_AllAddr_gfx10<0x00c>;
2231defm TBUFFER_STORE_FORMAT_D16_XY   : MTBUF_Real_AllAddr_gfx10<0x00d>;
2232defm TBUFFER_STORE_FORMAT_D16_XYZ  : MTBUF_Real_AllAddr_gfx10<0x00e>;
2233defm TBUFFER_STORE_FORMAT_D16_XYZW : MTBUF_Real_AllAddr_gfx10<0x00f>;
2234
2235//===----------------------------------------------------------------------===//
2236// MTBUF - GFX6, GFX7, GFX10.
2237//===----------------------------------------------------------------------===//
2238
2239class MTBUF_Real_gfx6_gfx7<bits<4> op, MTBUF_Pseudo ps> :
2240    Base_MTBUF_Real_gfx6_gfx7_gfx10<op{2-0}, ps, SIEncodingFamily.SI> {
2241  let Inst{15} = ps.addr64;
2242  let Inst{22-19} = dfmt;
2243  let Inst{25-23} = nfmt;
2244}
2245
2246let AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" in {
2247  multiclass MTBUF_Real_AllAddr_gfx6_gfx7<bits<4> op> {
2248    def _ADDR64_gfx6_gfx7 :
2249      MTBUF_Real_gfx6_gfx7<op, !cast<MTBUF_Pseudo>(NAME#"_ADDR64")>;
2250    def _BOTHEN_gfx6_gfx7 :
2251      MTBUF_Real_gfx6_gfx7<op, !cast<MTBUF_Pseudo>(NAME#"_BOTHEN")>;
2252    def _IDXEN_gfx6_gfx7 :
2253      MTBUF_Real_gfx6_gfx7<op, !cast<MTBUF_Pseudo>(NAME#"_IDXEN")>;
2254    def _OFFEN_gfx6_gfx7 :
2255      MTBUF_Real_gfx6_gfx7<op, !cast<MTBUF_Pseudo>(NAME#"_OFFEN")>;
2256    def _OFFSET_gfx6_gfx7 :
2257      MTBUF_Real_gfx6_gfx7<op, !cast<MTBUF_Pseudo>(NAME#"_OFFSET")>;
2258  }
2259} // End AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7"
2260
2261multiclass MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<bits<4> op> :
2262  MTBUF_Real_AllAddr_gfx6_gfx7<op>, MTBUF_Real_AllAddr_gfx10<op>;
2263
2264defm TBUFFER_LOAD_FORMAT_X     : MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x000>;
2265defm TBUFFER_LOAD_FORMAT_XY    : MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x001>;
2266defm TBUFFER_LOAD_FORMAT_XYZ   : MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x002>;
2267defm TBUFFER_LOAD_FORMAT_XYZW  : MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x003>;
2268defm TBUFFER_STORE_FORMAT_X    : MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x004>;
2269defm TBUFFER_STORE_FORMAT_XY   : MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x005>;
2270defm TBUFFER_STORE_FORMAT_XYZ  : MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x006>;
2271defm TBUFFER_STORE_FORMAT_XYZW : MTBUF_Real_AllAddr_gfx6_gfx7_gfx10<0x007>;
2272
2273//===----------------------------------------------------------------------===//
2274// GFX8, GFX9 (VI).
2275//===----------------------------------------------------------------------===//
2276
2277class MUBUF_Real_Base_vi <bits<7> op, MUBUF_Pseudo ps, int Enc,
2278                          bit has_sccb = ps.has_sccb> :
2279  MUBUF_Real<ps>,
2280  Enc64,
2281  SIMCInstr<ps.PseudoInstr, Enc>,
2282  AtomicNoRet<!subst("_RTN","",NAME), !if(ps.IsAtomicNoRet, 0,
2283                                        !if(ps.IsAtomicRet, 1, ?))> {
2284
2285  let Inst{11-0}  = !if(ps.has_offset, offset, ?);
2286  let Inst{12}    = ps.offen;
2287  let Inst{13}    = ps.idxen;
2288  let Inst{14}    = !if(ps.has_glc, cpol{CPolBit.GLC}, ps.glc_value);
2289  let Inst{15}    = !if(has_sccb, cpol{CPolBit.SCC}, ps.sccb_value);
2290  let Inst{16}    = ps.lds;
2291  let Inst{17}    = !if(ps.has_slc, cpol{CPolBit.SLC}, ?);
2292  let Inst{24-18} = op;
2293  let Inst{31-26} = 0x38; //encoding
2294  let Inst{39-32} = !if(ps.has_vaddr, vaddr, ?);
2295  let Inst{47-40} = !if(ps.has_vdata, vdata{7-0}, ?);
2296  let Inst{52-48} = !if(ps.has_srsrc, srsrc{6-2}, ?);
2297  let Inst{63-56} = !if(ps.has_soffset, soffset, ?);
2298}
2299
2300class MUBUF_Real_vi <bits<7> op, MUBUF_Pseudo ps, bit has_sccb = ps.has_sccb> :
2301  MUBUF_Real_Base_vi<op, ps, SIEncodingFamily.VI, has_sccb> {
2302  let AssemblerPredicate = isGFX8GFX9NotGFX90A;
2303  let DecoderNamespace = "GFX8";
2304
2305  let Inst{55}    = !if(ps.has_tfe, tfe, ?);
2306}
2307
2308class MUBUF_Real_gfx90a <bits<7> op, MUBUF_Pseudo ps,
2309                         bit has_sccb = ps.has_sccb> :
2310  MUBUF_Real_Base_vi<op, ps, SIEncodingFamily.GFX90A, has_sccb> {
2311  let AssemblerPredicate = isGFX90APlus;
2312  let DecoderNamespace = "GFX90A";
2313  let AsmString = ps.Mnemonic # !subst("$sccb", !if(has_sccb, "$sccb",""),
2314                                !subst("$tfe", "", ps.AsmOperands));
2315
2316  let Inst{55}    = acc;
2317}
2318
2319multiclass MUBUF_Real_vi_gfx90a<bits<7> op, MUBUF_Pseudo ps> {
2320  def _vi :     MUBUF_Real_vi<op, ps>;
2321  def _gfx90a : MUBUF_Real_gfx90a<op, ps, !and(ps.has_sccb,!not(ps.FPAtomic))>;
2322}
2323
2324multiclass MUBUF_Real_AllAddr_vi<bits<7> op> {
2325  defm _OFFSET : MUBUF_Real_vi_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>;
2326  defm _OFFEN  : MUBUF_Real_vi_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>;
2327  defm _IDXEN  : MUBUF_Real_vi_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>;
2328  defm _BOTHEN : MUBUF_Real_vi_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>;
2329}
2330
2331multiclass MUBUF_Real_AllAddr_Lds_vi<bits<7> op> {
2332
2333  def _OFFSET_vi : MUBUF_Real_vi <op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>,
2334                   MUBUFLdsTable<0, NAME # "_OFFSET_vi">;
2335  def _OFFEN_vi  : MUBUF_Real_vi <op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>,
2336                   MUBUFLdsTable<0, NAME # "_OFFEN_vi">;
2337  def _IDXEN_vi  : MUBUF_Real_vi <op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>,
2338                   MUBUFLdsTable<0, NAME # "_IDXEN_vi">;
2339  def _BOTHEN_vi : MUBUF_Real_vi <op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>,
2340                   MUBUFLdsTable<0, NAME # "_BOTHEN_vi">;
2341
2342  def _LDS_OFFSET_vi : MUBUF_Real_vi <op, !cast<MUBUF_Pseudo>(NAME#"_LDS_OFFSET")>,
2343                       MUBUFLdsTable<1, NAME # "_OFFSET_vi">;
2344  def _LDS_OFFEN_vi  : MUBUF_Real_vi <op, !cast<MUBUF_Pseudo>(NAME#"_LDS_OFFEN")>,
2345                       MUBUFLdsTable<1, NAME # "_OFFEN_vi">;
2346  def _LDS_IDXEN_vi  : MUBUF_Real_vi <op, !cast<MUBUF_Pseudo>(NAME#"_LDS_IDXEN")>,
2347                       MUBUFLdsTable<1, NAME # "_IDXEN_vi">;
2348  def _LDS_BOTHEN_vi : MUBUF_Real_vi <op, !cast<MUBUF_Pseudo>(NAME#"_LDS_BOTHEN")>,
2349                       MUBUFLdsTable<1, NAME # "_BOTHEN_vi">;
2350
2351  def _OFFSET_gfx90a : MUBUF_Real_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>,
2352                   MUBUFLdsTable<0, NAME # "_OFFSET_gfx90a">;
2353  def _OFFEN_gfx90a  : MUBUF_Real_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>,
2354                   MUBUFLdsTable<0, NAME # "_OFFEN_gfx90a">;
2355  def _IDXEN_gfx90a  : MUBUF_Real_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>,
2356                   MUBUFLdsTable<0, NAME # "_IDXEN_gfx90a">;
2357  def _BOTHEN_gfx90a : MUBUF_Real_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>,
2358                   MUBUFLdsTable<0, NAME # "_BOTHEN_gfx90a">;
2359
2360  def _LDS_OFFSET_gfx90a : MUBUF_Real_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_LDS_OFFSET")>,
2361                       MUBUFLdsTable<1, NAME # "_OFFSET_gfx90a">;
2362  def _LDS_OFFEN_gfx90a  : MUBUF_Real_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_LDS_OFFEN")>,
2363                       MUBUFLdsTable<1, NAME # "_OFFEN_gfx90a">;
2364  def _LDS_IDXEN_gfx90a  : MUBUF_Real_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_LDS_IDXEN")>,
2365                       MUBUFLdsTable<1, NAME # "_IDXEN_gfx90a">;
2366  def _LDS_BOTHEN_gfx90a : MUBUF_Real_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_LDS_BOTHEN")>,
2367                       MUBUFLdsTable<1, NAME # "_BOTHEN_gfx90a">;
2368}
2369
2370class MUBUF_Real_gfx80 <bits<7> op, MUBUF_Pseudo ps> :
2371  MUBUF_Real<ps>,
2372  Enc64,
2373  SIMCInstr<ps.PseudoInstr, SIEncodingFamily.GFX80> {
2374  let AssemblerPredicate=HasUnpackedD16VMem;
2375  let DecoderNamespace="GFX80_UNPACKED";
2376
2377  let Inst{11-0}  = !if(ps.has_offset, offset, ?);
2378  let Inst{12}    = ps.offen;
2379  let Inst{13}    = ps.idxen;
2380  let Inst{14}    = !if(ps.has_glc, cpol{CPolBit.GLC}, ps.glc_value);
2381  let Inst{16}    = ps.lds;
2382  let Inst{17}    = !if(ps.has_slc, cpol{CPolBit.SLC}, ?);
2383  let Inst{24-18} = op;
2384  let Inst{31-26} = 0x38; //encoding
2385  let Inst{39-32} = !if(ps.has_vaddr, vaddr, ?);
2386  let Inst{47-40} = !if(ps.has_vdata, vdata{7-0}, ?);
2387  let Inst{52-48} = !if(ps.has_srsrc, srsrc{6-2}, ?);
2388  let Inst{55}    = !if(ps.has_tfe, tfe, ?);
2389  let Inst{63-56} = !if(ps.has_soffset, soffset, ?);
2390}
2391
2392multiclass MUBUF_Real_AllAddr_gfx80<bits<7> op> {
2393  def _OFFSET_gfx80 : MUBUF_Real_gfx80 <op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET")>;
2394  def _OFFEN_gfx80  : MUBUF_Real_gfx80 <op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN")>;
2395  def _IDXEN_gfx80  : MUBUF_Real_gfx80 <op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN")>;
2396  def _BOTHEN_gfx80 : MUBUF_Real_gfx80 <op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN")>;
2397}
2398
2399multiclass MUBUF_Real_Atomic_vi<bits<7> op> :
2400  MUBUF_Real_AllAddr_vi<op> {
2401  defm _OFFSET_RTN : MUBUF_Real_vi_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_OFFSET_RTN")>;
2402  defm _OFFEN_RTN  : MUBUF_Real_vi_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_OFFEN_RTN")>;
2403  defm _IDXEN_RTN  : MUBUF_Real_vi_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_IDXEN_RTN")>;
2404  defm _BOTHEN_RTN : MUBUF_Real_vi_gfx90a <op, !cast<MUBUF_Pseudo>(NAME#"_BOTHEN_RTN")>;
2405}
2406
2407defm BUFFER_LOAD_FORMAT_X       : MUBUF_Real_AllAddr_Lds_vi <0x00>;
2408defm BUFFER_LOAD_FORMAT_XY      : MUBUF_Real_AllAddr_vi <0x01>;
2409defm BUFFER_LOAD_FORMAT_XYZ     : MUBUF_Real_AllAddr_vi <0x02>;
2410defm BUFFER_LOAD_FORMAT_XYZW    : MUBUF_Real_AllAddr_vi <0x03>;
2411defm BUFFER_STORE_FORMAT_X      : MUBUF_Real_AllAddr_vi <0x04>;
2412defm BUFFER_STORE_FORMAT_XY     : MUBUF_Real_AllAddr_vi <0x05>;
2413defm BUFFER_STORE_FORMAT_XYZ    : MUBUF_Real_AllAddr_vi <0x06>;
2414defm BUFFER_STORE_FORMAT_XYZW   : MUBUF_Real_AllAddr_vi <0x07>;
2415let SubtargetPredicate = HasUnpackedD16VMem in {
2416  defm BUFFER_LOAD_FORMAT_D16_X_gfx80       : MUBUF_Real_AllAddr_gfx80 <0x08>;
2417  defm BUFFER_LOAD_FORMAT_D16_XY_gfx80      : MUBUF_Real_AllAddr_gfx80 <0x09>;
2418  defm BUFFER_LOAD_FORMAT_D16_XYZ_gfx80     : MUBUF_Real_AllAddr_gfx80 <0x0a>;
2419  defm BUFFER_LOAD_FORMAT_D16_XYZW_gfx80    : MUBUF_Real_AllAddr_gfx80 <0x0b>;
2420  defm BUFFER_STORE_FORMAT_D16_X_gfx80      : MUBUF_Real_AllAddr_gfx80 <0x0c>;
2421  defm BUFFER_STORE_FORMAT_D16_XY_gfx80     : MUBUF_Real_AllAddr_gfx80 <0x0d>;
2422  defm BUFFER_STORE_FORMAT_D16_XYZ_gfx80    : MUBUF_Real_AllAddr_gfx80 <0x0e>;
2423  defm BUFFER_STORE_FORMAT_D16_XYZW_gfx80   : MUBUF_Real_AllAddr_gfx80 <0x0f>;
2424} // End HasUnpackedD16VMem.
2425let SubtargetPredicate = HasPackedD16VMem in {
2426  defm BUFFER_LOAD_FORMAT_D16_X       : MUBUF_Real_AllAddr_vi <0x08>;
2427  defm BUFFER_LOAD_FORMAT_D16_XY      : MUBUF_Real_AllAddr_vi <0x09>;
2428  defm BUFFER_LOAD_FORMAT_D16_XYZ     : MUBUF_Real_AllAddr_vi <0x0a>;
2429  defm BUFFER_LOAD_FORMAT_D16_XYZW    : MUBUF_Real_AllAddr_vi <0x0b>;
2430  defm BUFFER_STORE_FORMAT_D16_X      : MUBUF_Real_AllAddr_vi <0x0c>;
2431  defm BUFFER_STORE_FORMAT_D16_XY     : MUBUF_Real_AllAddr_vi <0x0d>;
2432  defm BUFFER_STORE_FORMAT_D16_XYZ    : MUBUF_Real_AllAddr_vi <0x0e>;
2433  defm BUFFER_STORE_FORMAT_D16_XYZW   : MUBUF_Real_AllAddr_vi <0x0f>;
2434} // End HasPackedD16VMem.
2435defm BUFFER_LOAD_UBYTE          : MUBUF_Real_AllAddr_Lds_vi <0x10>;
2436defm BUFFER_LOAD_SBYTE          : MUBUF_Real_AllAddr_Lds_vi <0x11>;
2437defm BUFFER_LOAD_USHORT         : MUBUF_Real_AllAddr_Lds_vi <0x12>;
2438defm BUFFER_LOAD_SSHORT         : MUBUF_Real_AllAddr_Lds_vi <0x13>;
2439defm BUFFER_LOAD_DWORD          : MUBUF_Real_AllAddr_Lds_vi <0x14>;
2440defm BUFFER_LOAD_DWORDX2        : MUBUF_Real_AllAddr_Lds_vi <0x15>;
2441defm BUFFER_LOAD_DWORDX3        : MUBUF_Real_AllAddr_Lds_vi <0x16>;
2442defm BUFFER_LOAD_DWORDX4        : MUBUF_Real_AllAddr_Lds_vi <0x17>;
2443defm BUFFER_STORE_BYTE          : MUBUF_Real_AllAddr_vi <0x18>;
2444defm BUFFER_STORE_BYTE_D16_HI   : MUBUF_Real_AllAddr_vi <0x19>;
2445defm BUFFER_STORE_SHORT         : MUBUF_Real_AllAddr_vi <0x1a>;
2446defm BUFFER_STORE_SHORT_D16_HI  : MUBUF_Real_AllAddr_vi <0x1b>;
2447defm BUFFER_STORE_DWORD         : MUBUF_Real_AllAddr_vi <0x1c>;
2448defm BUFFER_STORE_DWORDX2       : MUBUF_Real_AllAddr_vi <0x1d>;
2449defm BUFFER_STORE_DWORDX3       : MUBUF_Real_AllAddr_vi <0x1e>;
2450defm BUFFER_STORE_DWORDX4       : MUBUF_Real_AllAddr_vi <0x1f>;
2451
2452defm BUFFER_LOAD_UBYTE_D16      : MUBUF_Real_AllAddr_vi <0x20>;
2453defm BUFFER_LOAD_UBYTE_D16_HI   : MUBUF_Real_AllAddr_vi <0x21>;
2454defm BUFFER_LOAD_SBYTE_D16      : MUBUF_Real_AllAddr_vi <0x22>;
2455defm BUFFER_LOAD_SBYTE_D16_HI   : MUBUF_Real_AllAddr_vi <0x23>;
2456defm BUFFER_LOAD_SHORT_D16      : MUBUF_Real_AllAddr_vi <0x24>;
2457defm BUFFER_LOAD_SHORT_D16_HI   : MUBUF_Real_AllAddr_vi <0x25>;
2458
2459defm BUFFER_LOAD_FORMAT_D16_HI_X  : MUBUF_Real_AllAddr_vi <0x26>;
2460defm BUFFER_STORE_FORMAT_D16_HI_X : MUBUF_Real_AllAddr_vi <0x27>;
2461
2462defm BUFFER_ATOMIC_SWAP         : MUBUF_Real_Atomic_vi <0x40>;
2463defm BUFFER_ATOMIC_CMPSWAP      : MUBUF_Real_Atomic_vi <0x41>;
2464defm BUFFER_ATOMIC_ADD          : MUBUF_Real_Atomic_vi <0x42>;
2465defm BUFFER_ATOMIC_SUB          : MUBUF_Real_Atomic_vi <0x43>;
2466defm BUFFER_ATOMIC_SMIN         : MUBUF_Real_Atomic_vi <0x44>;
2467defm BUFFER_ATOMIC_UMIN         : MUBUF_Real_Atomic_vi <0x45>;
2468defm BUFFER_ATOMIC_SMAX         : MUBUF_Real_Atomic_vi <0x46>;
2469defm BUFFER_ATOMIC_UMAX         : MUBUF_Real_Atomic_vi <0x47>;
2470defm BUFFER_ATOMIC_AND          : MUBUF_Real_Atomic_vi <0x48>;
2471defm BUFFER_ATOMIC_OR           : MUBUF_Real_Atomic_vi <0x49>;
2472defm BUFFER_ATOMIC_XOR          : MUBUF_Real_Atomic_vi <0x4a>;
2473defm BUFFER_ATOMIC_INC          : MUBUF_Real_Atomic_vi <0x4b>;
2474defm BUFFER_ATOMIC_DEC          : MUBUF_Real_Atomic_vi <0x4c>;
2475
2476defm BUFFER_ATOMIC_SWAP_X2      : MUBUF_Real_Atomic_vi <0x60>;
2477defm BUFFER_ATOMIC_CMPSWAP_X2   : MUBUF_Real_Atomic_vi <0x61>;
2478defm BUFFER_ATOMIC_ADD_X2       : MUBUF_Real_Atomic_vi <0x62>;
2479defm BUFFER_ATOMIC_SUB_X2       : MUBUF_Real_Atomic_vi <0x63>;
2480defm BUFFER_ATOMIC_SMIN_X2      : MUBUF_Real_Atomic_vi <0x64>;
2481defm BUFFER_ATOMIC_UMIN_X2      : MUBUF_Real_Atomic_vi <0x65>;
2482defm BUFFER_ATOMIC_SMAX_X2      : MUBUF_Real_Atomic_vi <0x66>;
2483defm BUFFER_ATOMIC_UMAX_X2      : MUBUF_Real_Atomic_vi <0x67>;
2484defm BUFFER_ATOMIC_AND_X2       : MUBUF_Real_Atomic_vi <0x68>;
2485defm BUFFER_ATOMIC_OR_X2        : MUBUF_Real_Atomic_vi <0x69>;
2486defm BUFFER_ATOMIC_XOR_X2       : MUBUF_Real_Atomic_vi <0x6a>;
2487defm BUFFER_ATOMIC_INC_X2       : MUBUF_Real_Atomic_vi <0x6b>;
2488defm BUFFER_ATOMIC_DEC_X2       : MUBUF_Real_Atomic_vi <0x6c>;
2489
2490defm BUFFER_STORE_LDS_DWORD     : MUBUF_Real_vi_gfx90a <0x3d, BUFFER_STORE_LDS_DWORD>;
2491
2492let AssemblerPredicate = isGFX8GFX9 in {
2493def BUFFER_WBINVL1_vi           : MUBUF_Real_vi <0x3e, BUFFER_WBINVL1>;
2494def BUFFER_WBINVL1_VOL_vi       : MUBUF_Real_vi <0x3f, BUFFER_WBINVL1_VOL>;
2495} // End AssemblerPredicate = isGFX8GFX9
2496
2497let SubtargetPredicate = HasAtomicFaddInsts in {
2498
2499defm BUFFER_ATOMIC_ADD_F32    : MUBUF_Real_Atomic_vi <0x4d>;
2500defm BUFFER_ATOMIC_PK_ADD_F16 : MUBUF_Real_Atomic_vi <0x4e>;
2501
2502} // End SubtargetPredicate = HasAtomicFaddInsts
2503
2504let SubtargetPredicate = isGFX90APlus in {
2505  defm BUFFER_ATOMIC_ADD_F64 : MUBUF_Real_Atomic_vi<0x4f>;
2506  defm BUFFER_ATOMIC_MIN_F64 : MUBUF_Real_Atomic_vi<0x50>;
2507  defm BUFFER_ATOMIC_MAX_F64 : MUBUF_Real_Atomic_vi<0x51>;
2508} // End SubtargetPredicate = isGFX90APlus, AssemblerPredicate = isGFX90APlus
2509
2510def BUFFER_WBL2_gfx90a  : MUBUF_Real_gfx90a<0x28, BUFFER_WBL2> {
2511}
2512def BUFFER_INVL2_gfx90a : MUBUF_Real_gfx90a<0x29, BUFFER_INVL2>;
2513
2514class MTBUF_Real_Base_vi <bits<4> op, MTBUF_Pseudo ps, int Enc> :
2515  MTBUF_Real<ps>,
2516  Enc64,
2517  SIMCInstr<ps.PseudoInstr, Enc> {
2518
2519  let Inst{11-0}  = !if(ps.has_offset, offset, ?);
2520  let Inst{12}    = ps.offen;
2521  let Inst{13}    = ps.idxen;
2522  let Inst{14}    = !if(ps.has_glc, cpol{CPolBit.GLC}, ps.glc_value);
2523  let Inst{18-15} = op;
2524  let Inst{22-19} = dfmt;
2525  let Inst{25-23} = nfmt;
2526  let Inst{31-26} = 0x3a; //encoding
2527  let Inst{39-32} = !if(ps.has_vaddr, vaddr, ?);
2528  let Inst{47-40} = !if(ps.has_vdata, vdata{7-0}, ?);
2529  let Inst{52-48} = !if(ps.has_srsrc, srsrc{6-2}, ?);
2530  let Inst{53}    = !if(ps.has_sccb, cpol{CPolBit.SCC}, ps.sccb_value);
2531  let Inst{54}    = !if(ps.has_slc, cpol{CPolBit.SLC}, ?);
2532  let Inst{55}    = !if(ps.has_tfe, tfe, ?);
2533  let Inst{63-56} = !if(ps.has_soffset, soffset, ?);
2534}
2535
2536class MTBUF_Real_vi <bits<4> op, MTBUF_Pseudo ps> :
2537  MTBUF_Real_Base_vi <op, ps, SIEncodingFamily.VI> {
2538  let AssemblerPredicate = isGFX8GFX9NotGFX90A;
2539  let DecoderNamespace = "GFX8";
2540
2541  let Inst{55}    = !if(ps.has_tfe, tfe, ?);
2542}
2543
2544class MTBUF_Real_gfx90a <bits<4> op, MTBUF_Pseudo ps> :
2545  MTBUF_Real_Base_vi <op, ps, SIEncodingFamily.GFX90A> {
2546  let AssemblerPredicate = isGFX90APlus;
2547  let DecoderNamespace = "GFX90A";
2548  let AsmString = ps.Mnemonic # !subst("$tfe", "", ps.AsmOperands);
2549
2550  let Inst{55}    = acc;
2551}
2552
2553multiclass MTBUF_Real_vi_gfx90a<bits<4> op, MTBUF_Pseudo ps> {
2554  def _vi :     MTBUF_Real_vi<op, ps>;
2555  def _gfx90a : MTBUF_Real_gfx90a<op, ps>;
2556}
2557
2558multiclass MTBUF_Real_AllAddr_vi<bits<4> op> {
2559  defm _OFFSET : MTBUF_Real_vi_gfx90a <op, !cast<MTBUF_Pseudo>(NAME#"_OFFSET")>;
2560  defm _OFFEN  : MTBUF_Real_vi_gfx90a <op, !cast<MTBUF_Pseudo>(NAME#"_OFFEN")>;
2561  defm _IDXEN  : MTBUF_Real_vi_gfx90a <op, !cast<MTBUF_Pseudo>(NAME#"_IDXEN")>;
2562  defm _BOTHEN : MTBUF_Real_vi_gfx90a <op, !cast<MTBUF_Pseudo>(NAME#"_BOTHEN")>;
2563}
2564
2565class MTBUF_Real_gfx80 <bits<4> op, MTBUF_Pseudo ps> :
2566  MTBUF_Real<ps>,
2567  Enc64,
2568  SIMCInstr<ps.PseudoInstr, SIEncodingFamily.GFX80> {
2569  let AssemblerPredicate=HasUnpackedD16VMem;
2570  let DecoderNamespace="GFX80_UNPACKED";
2571
2572  let Inst{11-0}  = !if(ps.has_offset, offset, ?);
2573  let Inst{12}    = ps.offen;
2574  let Inst{13}    = ps.idxen;
2575  let Inst{14}    = !if(ps.has_glc, cpol{CPolBit.GLC}, ps.glc_value);
2576  let Inst{18-15} = op;
2577  let Inst{22-19} = dfmt;
2578  let Inst{25-23} = nfmt;
2579  let Inst{31-26} = 0x3a; //encoding
2580  let Inst{39-32} = !if(ps.has_vaddr, vaddr, ?);
2581  let Inst{47-40} = !if(ps.has_vdata, vdata{7-0}, ?);
2582  let Inst{52-48} = !if(ps.has_srsrc, srsrc{6-2}, ?);
2583  let Inst{54}    = !if(ps.has_slc, cpol{CPolBit.SLC}, ?);
2584  let Inst{55}    = !if(ps.has_tfe, tfe, ?);
2585  let Inst{63-56} = !if(ps.has_soffset, soffset, ?);
2586}
2587
2588multiclass MTBUF_Real_AllAddr_gfx80<bits<4> op> {
2589  def _OFFSET_gfx80 : MTBUF_Real_gfx80 <op, !cast<MTBUF_Pseudo>(NAME#"_OFFSET")>;
2590  def _OFFEN_gfx80  : MTBUF_Real_gfx80 <op, !cast<MTBUF_Pseudo>(NAME#"_OFFEN")>;
2591  def _IDXEN_gfx80  : MTBUF_Real_gfx80 <op, !cast<MTBUF_Pseudo>(NAME#"_IDXEN")>;
2592  def _BOTHEN_gfx80 : MTBUF_Real_gfx80 <op, !cast<MTBUF_Pseudo>(NAME#"_BOTHEN")>;
2593}
2594
2595defm TBUFFER_LOAD_FORMAT_X     : MTBUF_Real_AllAddr_vi <0x00>;
2596defm TBUFFER_LOAD_FORMAT_XY    : MTBUF_Real_AllAddr_vi <0x01>;
2597defm TBUFFER_LOAD_FORMAT_XYZ   : MTBUF_Real_AllAddr_vi <0x02>;
2598defm TBUFFER_LOAD_FORMAT_XYZW  : MTBUF_Real_AllAddr_vi <0x03>;
2599defm TBUFFER_STORE_FORMAT_X    : MTBUF_Real_AllAddr_vi <0x04>;
2600defm TBUFFER_STORE_FORMAT_XY   : MTBUF_Real_AllAddr_vi <0x05>;
2601defm TBUFFER_STORE_FORMAT_XYZ  : MTBUF_Real_AllAddr_vi <0x06>;
2602defm TBUFFER_STORE_FORMAT_XYZW : MTBUF_Real_AllAddr_vi <0x07>;
2603let SubtargetPredicate = HasUnpackedD16VMem in {
2604  defm TBUFFER_LOAD_FORMAT_D16_X_gfx80     : MTBUF_Real_AllAddr_gfx80 <0x08>;
2605  defm TBUFFER_LOAD_FORMAT_D16_XY_gfx80    : MTBUF_Real_AllAddr_gfx80 <0x09>;
2606  defm TBUFFER_LOAD_FORMAT_D16_XYZ_gfx80   : MTBUF_Real_AllAddr_gfx80 <0x0a>;
2607  defm TBUFFER_LOAD_FORMAT_D16_XYZW_gfx80  : MTBUF_Real_AllAddr_gfx80 <0x0b>;
2608  defm TBUFFER_STORE_FORMAT_D16_X_gfx80    : MTBUF_Real_AllAddr_gfx80 <0x0c>;
2609  defm TBUFFER_STORE_FORMAT_D16_XY_gfx80   : MTBUF_Real_AllAddr_gfx80 <0x0d>;
2610  defm TBUFFER_STORE_FORMAT_D16_XYZ_gfx80  : MTBUF_Real_AllAddr_gfx80 <0x0e>;
2611  defm TBUFFER_STORE_FORMAT_D16_XYZW_gfx80 : MTBUF_Real_AllAddr_gfx80 <0x0f>;
2612} // End HasUnpackedD16VMem.
2613let SubtargetPredicate = HasPackedD16VMem in {
2614  defm TBUFFER_LOAD_FORMAT_D16_X     : MTBUF_Real_AllAddr_vi <0x08>;
2615  defm TBUFFER_LOAD_FORMAT_D16_XY    : MTBUF_Real_AllAddr_vi <0x09>;
2616  defm TBUFFER_LOAD_FORMAT_D16_XYZ   : MTBUF_Real_AllAddr_vi <0x0a>;
2617  defm TBUFFER_LOAD_FORMAT_D16_XYZW  : MTBUF_Real_AllAddr_vi <0x0b>;
2618  defm TBUFFER_STORE_FORMAT_D16_X    : MTBUF_Real_AllAddr_vi <0x0c>;
2619  defm TBUFFER_STORE_FORMAT_D16_XY   : MTBUF_Real_AllAddr_vi <0x0d>;
2620  defm TBUFFER_STORE_FORMAT_D16_XYZ  : MTBUF_Real_AllAddr_vi <0x0e>;
2621  defm TBUFFER_STORE_FORMAT_D16_XYZW : MTBUF_Real_AllAddr_vi <0x0f>;
2622} // End HasUnpackedD16VMem.
2623
2624def MUBUFInfoTable : GenericTable {
2625  let FilterClass = "MUBUF_Pseudo";
2626  let CppTypeName = "MUBUFInfo";
2627  let Fields = [
2628    "Opcode", "BaseOpcode", "elements", "has_vaddr", "has_srsrc", "has_soffset",
2629    "IsBufferInv"
2630  ];
2631
2632  let PrimaryKey = ["Opcode"];
2633  let PrimaryKeyName = "getMUBUFOpcodeHelper";
2634}
2635
2636def getMUBUFInfoFromOpcode : SearchIndex {
2637  let Table = MUBUFInfoTable;
2638  let Key = ["Opcode"];
2639}
2640
2641def getMUBUFInfoFromBaseOpcodeAndElements : SearchIndex {
2642  let Table = MUBUFInfoTable;
2643  let Key = ["BaseOpcode", "elements"];
2644}
2645
2646def MTBUFInfoTable : GenericTable {
2647  let FilterClass = "MTBUF_Pseudo";
2648  let CppTypeName = "MTBUFInfo";
2649  let Fields = ["Opcode", "BaseOpcode", "elements", "has_vaddr", "has_srsrc", "has_soffset"];
2650
2651  let PrimaryKey = ["Opcode"];
2652  let PrimaryKeyName = "getMTBUFOpcodeHelper";
2653}
2654
2655def getMTBUFInfoFromOpcode : SearchIndex {
2656  let Table = MTBUFInfoTable;
2657  let Key = ["Opcode"];
2658}
2659
2660def getMTBUFInfoFromBaseOpcodeAndElements : SearchIndex {
2661  let Table = MTBUFInfoTable;
2662  let Key = ["BaseOpcode", "elements"];
2663}
2664