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