1//===-- DSInstructions.td - DS 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
9class DS_Pseudo <string opName, dag outs, dag ins, string asmOps, list<dag> pattern=[]> :
10  InstSI <outs, ins, "", pattern>,
11  SIMCInstr <opName, SIEncodingFamily.NONE> {
12
13  let LGKM_CNT = 1;
14  let DS = 1;
15  let Size = 8;
16  let UseNamedOperandTable = 1;
17
18  // Most instruction load and store data, so set this as the default.
19  let mayLoad = 1;
20  let mayStore = 1;
21  let maybeAtomic = 1;
22
23  let hasSideEffects = 0;
24  let SchedRW = [WriteLDS];
25
26  let isPseudo = 1;
27  let isCodeGenOnly = 1;
28
29  let AsmMatchConverter = "cvtDS";
30
31  string Mnemonic = opName;
32  string AsmOperands = asmOps;
33
34  // Well these bits a kind of hack because it would be more natural
35  // to test "outs" and "ins" dags for the presence of particular operands
36  bits<1> has_vdst = 1;
37  bits<1> has_addr = 1;
38  bits<1> has_data0 = 1;
39  bits<1> has_data1 = 1;
40
41  bits<1> has_gws_data0 = 0; // data0 is encoded as addr
42
43  bits<1> has_offset  = 1; // has "offset" that should be split to offset0,1
44  bits<1> has_offset0 = 1;
45  bits<1> has_offset1 = 1;
46
47  bits<1> has_gds = 1;
48  bits<1> gdsValue = 0; // if has_gds == 0 set gds to this value
49
50  bits<1> has_m0_read = 1;
51
52  let Uses = !if(has_m0_read, [M0, EXEC], [EXEC]);
53}
54
55class DS_Real <DS_Pseudo ds> :
56  InstSI <ds.OutOperandList, ds.InOperandList, ds.Mnemonic # ds.AsmOperands, []>,
57  Enc64 {
58
59  let isPseudo = 0;
60  let isCodeGenOnly = 0;
61  let DS = 1;
62  let UseNamedOperandTable = 1;
63
64  // copy relevant pseudo op flags
65  let SubtargetPredicate = ds.SubtargetPredicate;
66  let OtherPredicates = ds.OtherPredicates;
67  let AsmMatchConverter  = ds.AsmMatchConverter;
68
69  // encoding fields
70  bits<10> vdst;
71  bits<1> gds;
72  bits<8> addr;
73  bits<10> data0;
74  bits<10> data1;
75  bits<8> offset0;
76  bits<8> offset1;
77
78  bits<16> offset;
79  let offset0 = !if(ds.has_offset, offset{7-0}, ?);
80  let offset1 = !if(ds.has_offset, offset{15-8}, ?);
81
82  bits<1> acc = !if(ds.has_vdst, vdst{9},
83                    !if(!or(ds.has_data0, ds.has_gws_data0), data0{9}, 0));
84}
85
86
87// DS Pseudo instructions
88
89class DS_0A1D_NORET<string opName, RegisterClass rc = VGPR_32>
90: DS_Pseudo<opName,
91  (outs),
92  (ins getLdStRegisterOperand<rc>.ret:$data0, offset:$offset, gds:$gds),
93  " $data0$offset$gds"> {
94
95  let has_addr = 0;
96  let has_data1 = 0;
97  let has_vdst = 0;
98}
99
100class DS_1A1D_NORET<string opName, RegisterClass rc = VGPR_32>
101: DS_Pseudo<opName,
102  (outs),
103  (ins VGPR_32:$addr, getLdStRegisterOperand<rc>.ret:$data0, offset:$offset, gds:$gds),
104  " $addr, $data0$offset$gds"> {
105
106  let has_data1 = 0;
107  let has_vdst = 0;
108  let IsAtomicNoRet = 1;
109}
110
111multiclass DS_1A1D_NORET_mc<string opName, RegisterClass rc = VGPR_32> {
112  def "" : DS_1A1D_NORET<opName, rc>,
113           AtomicNoRet<opName, 0>;
114
115  let has_m0_read = 0 in {
116    def _gfx9 : DS_1A1D_NORET<opName, rc>,
117                AtomicNoRet<opName#"_gfx9", 0>;
118  }
119}
120
121multiclass DS_1A1D_NORET_mc_gfx9<string opName, RegisterClass rc = VGPR_32> {
122  let has_m0_read = 0 in {
123    def "" : DS_1A1D_NORET<opName, rc>,
124                AtomicNoRet<opName, 0>;
125  }
126}
127
128class DS_1A2D_NORET<string opName, RegisterClass rc = VGPR_32,
129                    RegisterOperand data_op = getLdStRegisterOperand<rc>.ret>
130: DS_Pseudo<opName,
131  (outs),
132  (ins VGPR_32:$addr, data_op:$data0, data_op:$data1, offset:$offset, gds:$gds),
133  " $addr, $data0, $data1$offset$gds"> {
134
135  let has_vdst = 0;
136  let IsAtomicNoRet = 1;
137}
138
139multiclass DS_1A2D_NORET_mc<string opName, RegisterClass rc = VGPR_32> {
140  def "" : DS_1A2D_NORET<opName, rc>,
141           AtomicNoRet<opName, 0>;
142
143  let has_m0_read = 0 in {
144    def _gfx9 : DS_1A2D_NORET<opName, rc>,
145                AtomicNoRet<opName#"_gfx9", 0>;
146  }
147}
148
149class DS_1A2D_Off8_NORET <string opName, RegisterClass rc = VGPR_32,
150                          RegisterOperand data_op = getLdStRegisterOperand<rc>.ret>
151: DS_Pseudo<opName,
152  (outs),
153  (ins VGPR_32:$addr, data_op:$data0, data_op:$data1,
154       offset0:$offset0, offset1:$offset1, gds:$gds),
155  " $addr, $data0, $data1$offset0$offset1$gds"> {
156
157  let has_vdst = 0;
158  let has_offset = 0;
159  let AsmMatchConverter = "cvtDSOffset01";
160}
161
162multiclass DS_1A2D_Off8_NORET_mc <string opName, RegisterClass rc = VGPR_32> {
163  def "" : DS_1A2D_Off8_NORET<opName, rc>;
164
165  let has_m0_read = 0 in {
166    def _gfx9 : DS_1A2D_Off8_NORET<opName, rc>;
167  }
168}
169
170class DS_1A1D_RET <string opName, RegisterClass rc = VGPR_32,
171                  RegisterOperand data_op = getLdStRegisterOperand<rc>.ret>
172: DS_Pseudo<opName,
173  (outs data_op:$vdst),
174  (ins VGPR_32:$addr, data_op:$data0, offset:$offset, gds:$gds),
175  " $vdst, $addr, $data0$offset$gds"> {
176
177  let hasPostISelHook = 1;
178  let has_data1 = 0;
179  let IsAtomicRet = 1;
180}
181
182multiclass DS_1A1D_RET_mc <string opName, RegisterClass rc = VGPR_32,
183                           string NoRetOp = ""> {
184  def "" : DS_1A1D_RET<opName, rc>,
185    AtomicNoRet<NoRetOp, !ne(NoRetOp, "")>;
186
187  let has_m0_read = 0 in {
188    def _gfx9 : DS_1A1D_RET<opName, rc>,
189      AtomicNoRet<!if(!eq(NoRetOp, ""), "", NoRetOp#"_gfx9"),
190                  !ne(NoRetOp, "")>;
191  }
192}
193
194multiclass DS_1A1D_RET_mc_gfx9 <string opName, RegisterClass rc = VGPR_32,
195                                string NoRetOp = ""> {
196  let has_m0_read = 0 in {
197    def "" : DS_1A1D_RET<opName, rc>,
198      AtomicNoRet<!if(!eq(NoRetOp, ""), "", NoRetOp),
199                  !if(!eq(NoRetOp, ""), 0, 1)>;
200  }
201}
202
203class DS_1A2D_RET<string opName,
204                  RegisterClass rc = VGPR_32,
205                  RegisterClass src = rc,
206                  RegisterOperand dst_op = getLdStRegisterOperand<rc>.ret,
207                  RegisterOperand src_op = getLdStRegisterOperand<src>.ret>
208: DS_Pseudo<opName,
209  (outs dst_op:$vdst),
210  (ins VGPR_32:$addr, src_op:$data0, src_op:$data1, offset:$offset, gds:$gds),
211  " $vdst, $addr, $data0, $data1$offset$gds"> {
212
213  let hasPostISelHook = 1;
214  let IsAtomicRet = 1;
215}
216
217multiclass DS_1A2D_RET_mc<string opName,
218                          RegisterClass rc = VGPR_32,
219                          string NoRetOp = "",
220                          RegisterClass src = rc> {
221  def "" : DS_1A2D_RET<opName, rc, src>,
222    AtomicNoRet<NoRetOp, !ne(NoRetOp, "")>;
223
224  let has_m0_read = 0 in {
225    def _gfx9 : DS_1A2D_RET<opName, rc, src>,
226      AtomicNoRet<NoRetOp#"_gfx9", !ne(NoRetOp, "")>;
227  }
228}
229
230class DS_1A2D_Off8_RET<string opName,
231                       RegisterClass rc = VGPR_32,
232                       RegisterClass src = rc,
233                       RegisterOperand dst_op = getLdStRegisterOperand<rc>.ret,
234                       RegisterOperand src_op = getLdStRegisterOperand<src>.ret>
235: DS_Pseudo<opName,
236  (outs dst_op:$vdst),
237  (ins VGPR_32:$addr, src_op:$data0, src_op:$data1, offset0:$offset0, offset1:$offset1, gds:$gds),
238  " $vdst, $addr, $data0, $data1$offset0$offset1$gds"> {
239
240  let has_offset = 0;
241  let AsmMatchConverter = "cvtDSOffset01";
242
243  let hasPostISelHook = 1;
244}
245
246multiclass DS_1A2D_Off8_RET_mc<string opName,
247                               RegisterClass rc = VGPR_32,
248                               RegisterClass src = rc> {
249  def "" : DS_1A2D_Off8_RET<opName, rc, src>;
250
251  let has_m0_read = 0 in {
252    def _gfx9 : DS_1A2D_Off8_RET<opName, rc, src>;
253  }
254}
255
256
257class DS_1A_RET<string opName, RegisterClass rc = VGPR_32, bit HasTiedOutput = 0, Operand ofs = offset,
258                RegisterOperand data_op = getLdStRegisterOperand<rc>.ret>
259: DS_Pseudo<opName,
260  (outs data_op:$vdst),
261  !if(HasTiedOutput,
262    (ins VGPR_32:$addr, ofs:$offset, gds:$gds, data_op:$vdst_in),
263    (ins VGPR_32:$addr, ofs:$offset, gds:$gds)),
264  " $vdst, $addr$offset$gds"> {
265  let Constraints = !if(HasTiedOutput, "$vdst = $vdst_in", "");
266  let DisableEncoding = !if(HasTiedOutput, "$vdst_in", "");
267  let has_data0 = 0;
268  let has_data1 = 0;
269}
270
271multiclass DS_1A_RET_mc<string opName, RegisterClass rc = VGPR_32, bit HasTiedOutput = 0, Operand ofs = offset> {
272  def "" : DS_1A_RET<opName, rc, HasTiedOutput, ofs>;
273
274  let has_m0_read = 0 in {
275    def _gfx9 : DS_1A_RET<opName, rc, HasTiedOutput, ofs>;
276  }
277}
278
279class DS_1A_RET_Tied<string opName, RegisterClass rc = VGPR_32> :
280  DS_1A_RET<opName, rc, 1>;
281
282class DS_1A_Off8_RET <string opName, RegisterClass rc = VGPR_32>
283: DS_Pseudo<opName,
284  (outs getLdStRegisterOperand<rc>.ret:$vdst),
285  (ins VGPR_32:$addr, offset0:$offset0, offset1:$offset1, gds:$gds),
286  " $vdst, $addr$offset0$offset1$gds"> {
287
288  let has_offset = 0;
289  let has_data0 = 0;
290  let has_data1 = 0;
291  let AsmMatchConverter = "cvtDSOffset01";
292}
293
294multiclass DS_1A_Off8_RET_mc <string opName, RegisterClass rc = VGPR_32> {
295  def "" : DS_1A_Off8_RET<opName, rc>;
296
297  let has_m0_read = 0 in {
298    def _gfx9 : DS_1A_Off8_RET<opName, rc>;
299  }
300}
301
302class DS_1A_RET_GDS <string opName> : DS_Pseudo<opName,
303  (outs getLdStRegisterOperand<VGPR_32>.ret:$vdst),
304  (ins VGPR_32:$addr, offset:$offset),
305  " $vdst, $addr$offset gds"> {
306
307  let has_data0 = 0;
308  let has_data1 = 0;
309  let has_gds = 0;
310  let gdsValue = 1;
311  let AsmMatchConverter = "cvtDSGds";
312}
313
314class DS_0A_RET <string opName> : DS_Pseudo<opName,
315  (outs getLdStRegisterOperand<VGPR_32>.ret:$vdst),
316  (ins offset:$offset, gds:$gds),
317  " $vdst$offset$gds"> {
318
319  let mayLoad = 1;
320  let mayStore = 1;
321
322  let has_addr = 0;
323  let has_data0 = 0;
324  let has_data1 = 0;
325}
326
327class DS_1A <string opName> : DS_Pseudo<opName,
328  (outs),
329  (ins VGPR_32:$addr, offset:$offset, gds:$gds),
330  " $addr$offset$gds"> {
331
332  let mayLoad = 1;
333  let mayStore = 1;
334
335  let has_vdst = 0;
336  let has_data0 = 0;
337  let has_data1 = 0;
338}
339
340multiclass DS_1A_mc <string opName> {
341  def "" : DS_1A<opName>;
342
343  let has_m0_read = 0 in {
344    def _gfx9 : DS_1A<opName>;
345  }
346}
347
348
349class DS_GWS <string opName, dag ins, string asmOps>
350: DS_Pseudo<opName, (outs), ins, asmOps> {
351
352  let has_vdst  = 0;
353  let has_addr  = 0;
354  let has_data0 = 0;
355  let has_data1 = 0;
356
357  let has_gds   = 0;
358  let gdsValue  = 1;
359  let AsmMatchConverter = "cvtDSGds";
360}
361
362class DS_GWS_0D <string opName>
363: DS_GWS<opName,
364  (ins offset:$offset), "$offset gds"> {
365  let hasSideEffects = 1;
366}
367
368class DS_GWS_1D <string opName>
369: DS_GWS<opName,
370  (ins getLdStRegisterOperand<VGPR_32>.ret:$data0, offset:$offset),
371  " $data0$offset gds"> {
372
373  let has_gws_data0 = 1;
374  let hasSideEffects = 1;
375}
376
377class DS_VOID <string opName> : DS_Pseudo<opName,
378  (outs), (ins), ""> {
379  let mayLoad = 0;
380  let mayStore = 0;
381  let hasSideEffects = 1;
382  let UseNamedOperandTable = 0;
383  let AsmMatchConverter = "";
384
385  let has_vdst = 0;
386  let has_addr = 0;
387  let has_data0 = 0;
388  let has_data1 = 0;
389  let has_offset = 0;
390  let has_offset0 = 0;
391  let has_offset1 = 0;
392  let has_gds = 0;
393}
394
395class DS_1A1D_PERMUTE <string opName, SDPatternOperator node = null_frag,
396                       RegisterOperand data_op = getLdStRegisterOperand<VGPR_32>.ret>
397: DS_Pseudo<opName,
398  (outs data_op:$vdst),
399  (ins VGPR_32:$addr, data_op:$data0, offset:$offset),
400  " $vdst, $addr, $data0$offset",
401  [(set i32:$vdst,
402   (node (DS1Addr1Offset i32:$addr, i16:$offset), i32:$data0))] > {
403
404  let mayLoad = 0;
405  let mayStore = 0;
406  let isConvergent = 1;
407
408  let has_data1 = 0;
409  let has_gds = 0;
410}
411
412defm DS_ADD_U32       : DS_1A1D_NORET_mc<"ds_add_u32">;
413defm DS_SUB_U32       : DS_1A1D_NORET_mc<"ds_sub_u32">;
414defm DS_RSUB_U32      : DS_1A1D_NORET_mc<"ds_rsub_u32">;
415defm DS_INC_U32       : DS_1A1D_NORET_mc<"ds_inc_u32">;
416defm DS_DEC_U32       : DS_1A1D_NORET_mc<"ds_dec_u32">;
417defm DS_MIN_I32       : DS_1A1D_NORET_mc<"ds_min_i32">;
418defm DS_MAX_I32       : DS_1A1D_NORET_mc<"ds_max_i32">;
419defm DS_MIN_U32       : DS_1A1D_NORET_mc<"ds_min_u32">;
420defm DS_MAX_U32       : DS_1A1D_NORET_mc<"ds_max_u32">;
421defm DS_AND_B32       : DS_1A1D_NORET_mc<"ds_and_b32">;
422defm DS_OR_B32        : DS_1A1D_NORET_mc<"ds_or_b32">;
423defm DS_XOR_B32       : DS_1A1D_NORET_mc<"ds_xor_b32">;
424
425let SubtargetPredicate = HasLDSFPAtomics in {
426defm DS_ADD_F32       : DS_1A1D_NORET_mc<"ds_add_f32">;
427}
428
429// FIXME: Are these really present pre-gfx8?
430defm DS_MIN_F32       : DS_1A1D_NORET_mc<"ds_min_f32">;
431defm DS_MAX_F32       : DS_1A1D_NORET_mc<"ds_max_f32">;
432
433let mayLoad = 0 in {
434defm DS_WRITE_B8      : DS_1A1D_NORET_mc<"ds_write_b8">;
435defm DS_WRITE_B16     : DS_1A1D_NORET_mc<"ds_write_b16">;
436defm DS_WRITE_B32     : DS_1A1D_NORET_mc<"ds_write_b32">;
437defm DS_WRITE2_B32    : DS_1A2D_Off8_NORET_mc<"ds_write2_b32">;
438defm DS_WRITE2ST64_B32: DS_1A2D_Off8_NORET_mc<"ds_write2st64_b32">;
439
440
441let has_m0_read = 0 in {
442
443let SubtargetPredicate = HasD16LoadStore in {
444def DS_WRITE_B8_D16_HI  : DS_1A1D_NORET<"ds_write_b8_d16_hi">;
445def DS_WRITE_B16_D16_HI : DS_1A1D_NORET<"ds_write_b16_d16_hi">;
446}
447
448} // End has_m0_read = 0
449
450let SubtargetPredicate = HasDSAddTid in {
451def DS_WRITE_ADDTID_B32 : DS_0A1D_NORET<"ds_write_addtid_b32">;
452}
453
454} // End mayLoad = 0
455
456let SubtargetPredicate = isGFX90APlus in {
457  defm DS_ADD_F64     : DS_1A1D_NORET_mc_gfx9<"ds_add_f64", VReg_64>;
458  defm DS_ADD_RTN_F64 : DS_1A1D_RET_mc_gfx9<"ds_add_rtn_f64 ", VReg_64, "ds_add_f64">;
459} // End SubtargetPredicate = isGFX90APlus
460
461defm DS_MSKOR_B32     : DS_1A2D_NORET_mc<"ds_mskor_b32">;
462defm DS_CMPST_B32     : DS_1A2D_NORET_mc<"ds_cmpst_b32">;
463defm DS_CMPST_F32     : DS_1A2D_NORET_mc<"ds_cmpst_f32">;
464
465defm DS_ADD_U64       : DS_1A1D_NORET_mc<"ds_add_u64", VReg_64>;
466defm DS_SUB_U64       : DS_1A1D_NORET_mc<"ds_sub_u64", VReg_64>;
467defm DS_RSUB_U64      : DS_1A1D_NORET_mc<"ds_rsub_u64", VReg_64>;
468defm DS_INC_U64       : DS_1A1D_NORET_mc<"ds_inc_u64", VReg_64>;
469defm DS_DEC_U64       : DS_1A1D_NORET_mc<"ds_dec_u64", VReg_64>;
470defm DS_MIN_I64       : DS_1A1D_NORET_mc<"ds_min_i64", VReg_64>;
471defm DS_MAX_I64       : DS_1A1D_NORET_mc<"ds_max_i64", VReg_64>;
472defm DS_MIN_U64       : DS_1A1D_NORET_mc<"ds_min_u64", VReg_64>;
473defm DS_MAX_U64       : DS_1A1D_NORET_mc<"ds_max_u64", VReg_64>;
474defm DS_AND_B64       : DS_1A1D_NORET_mc<"ds_and_b64", VReg_64>;
475defm DS_OR_B64        : DS_1A1D_NORET_mc<"ds_or_b64", VReg_64>;
476defm DS_XOR_B64       : DS_1A1D_NORET_mc<"ds_xor_b64", VReg_64>;
477defm DS_MSKOR_B64     : DS_1A2D_NORET_mc<"ds_mskor_b64", VReg_64>;
478let mayLoad = 0 in {
479defm DS_WRITE_B64     : DS_1A1D_NORET_mc<"ds_write_b64", VReg_64>;
480defm DS_WRITE2_B64    : DS_1A2D_Off8_NORET_mc<"ds_write2_b64", VReg_64>;
481defm DS_WRITE2ST64_B64: DS_1A2D_Off8_NORET_mc<"ds_write2st64_b64", VReg_64>;
482}
483defm DS_CMPST_B64     : DS_1A2D_NORET_mc<"ds_cmpst_b64", VReg_64>;
484defm DS_CMPST_F64     : DS_1A2D_NORET_mc<"ds_cmpst_f64", VReg_64>;
485defm DS_MIN_F64       : DS_1A1D_NORET_mc<"ds_min_f64", VReg_64>;
486defm DS_MAX_F64       : DS_1A1D_NORET_mc<"ds_max_f64", VReg_64>;
487
488defm DS_ADD_RTN_U32   : DS_1A1D_RET_mc<"ds_add_rtn_u32", VGPR_32, "ds_add_u32">;
489
490let SubtargetPredicate = HasLDSFPAtomics in {
491defm DS_ADD_RTN_F32   : DS_1A1D_RET_mc<"ds_add_rtn_f32", VGPR_32, "ds_add_f32">;
492}
493defm DS_SUB_RTN_U32   : DS_1A1D_RET_mc<"ds_sub_rtn_u32", VGPR_32, "ds_sub_u32">;
494defm DS_RSUB_RTN_U32  : DS_1A1D_RET_mc<"ds_rsub_rtn_u32", VGPR_32, "ds_rsub_u32">;
495defm DS_INC_RTN_U32   : DS_1A1D_RET_mc<"ds_inc_rtn_u32", VGPR_32, "ds_inc_u32">;
496defm DS_DEC_RTN_U32   : DS_1A1D_RET_mc<"ds_dec_rtn_u32", VGPR_32, "ds_dec_u32">;
497defm DS_MIN_RTN_I32   : DS_1A1D_RET_mc<"ds_min_rtn_i32", VGPR_32, "ds_min_i32">;
498defm DS_MAX_RTN_I32   : DS_1A1D_RET_mc<"ds_max_rtn_i32", VGPR_32, "ds_max_i32">;
499defm DS_MIN_RTN_U32   : DS_1A1D_RET_mc<"ds_min_rtn_u32", VGPR_32, "ds_min_u32">;
500defm DS_MAX_RTN_U32   : DS_1A1D_RET_mc<"ds_max_rtn_u32", VGPR_32, "ds_max_u32">;
501defm DS_AND_RTN_B32   : DS_1A1D_RET_mc<"ds_and_rtn_b32", VGPR_32, "ds_and_b32">;
502defm DS_OR_RTN_B32    : DS_1A1D_RET_mc<"ds_or_rtn_b32", VGPR_32, "ds_or_b32">;
503defm DS_XOR_RTN_B32   : DS_1A1D_RET_mc<"ds_xor_rtn_b32", VGPR_32, "ds_xor_b32">;
504defm DS_MSKOR_RTN_B32 : DS_1A2D_RET_mc<"ds_mskor_rtn_b32", VGPR_32, "ds_mskor_b32">;
505defm DS_CMPST_RTN_B32 : DS_1A2D_RET_mc<"ds_cmpst_rtn_b32", VGPR_32, "ds_cmpst_b32">;
506defm DS_CMPST_RTN_F32 : DS_1A2D_RET_mc<"ds_cmpst_rtn_f32", VGPR_32, "ds_cmpst_f32">;
507defm DS_MIN_RTN_F32   : DS_1A1D_RET_mc<"ds_min_rtn_f32", VGPR_32, "ds_min_f32">;
508defm DS_MAX_RTN_F32   : DS_1A1D_RET_mc<"ds_max_rtn_f32", VGPR_32, "ds_max_f32">;
509
510defm DS_WRXCHG_RTN_B32 : DS_1A1D_RET_mc<"ds_wrxchg_rtn_b32">;
511defm DS_WRXCHG2_RTN_B32 : DS_1A2D_Off8_RET_mc<"ds_wrxchg2_rtn_b32", VReg_64, VGPR_32>;
512defm DS_WRXCHG2ST64_RTN_B32 : DS_1A2D_Off8_RET_mc<"ds_wrxchg2st64_rtn_b32", VReg_64, VGPR_32>;
513
514defm DS_ADD_RTN_U64  : DS_1A1D_RET_mc<"ds_add_rtn_u64", VReg_64, "ds_add_u64">;
515defm DS_SUB_RTN_U64  : DS_1A1D_RET_mc<"ds_sub_rtn_u64", VReg_64, "ds_sub_u64">;
516defm DS_RSUB_RTN_U64  : DS_1A1D_RET_mc<"ds_rsub_rtn_u64", VReg_64, "ds_rsub_u64">;
517defm DS_INC_RTN_U64   : DS_1A1D_RET_mc<"ds_inc_rtn_u64", VReg_64, "ds_inc_u64">;
518defm DS_DEC_RTN_U64   : DS_1A1D_RET_mc<"ds_dec_rtn_u64", VReg_64, "ds_dec_u64">;
519defm DS_MIN_RTN_I64    : DS_1A1D_RET_mc<"ds_min_rtn_i64", VReg_64, "ds_min_i64">;
520defm DS_MAX_RTN_I64    : DS_1A1D_RET_mc<"ds_max_rtn_i64", VReg_64, "ds_max_i64">;
521defm DS_MIN_RTN_U64   : DS_1A1D_RET_mc<"ds_min_rtn_u64", VReg_64, "ds_min_u64">;
522defm DS_MAX_RTN_U64   : DS_1A1D_RET_mc<"ds_max_rtn_u64", VReg_64, "ds_max_u64">;
523defm DS_AND_RTN_B64    : DS_1A1D_RET_mc<"ds_and_rtn_b64", VReg_64, "ds_and_b64">;
524defm DS_OR_RTN_B64     : DS_1A1D_RET_mc<"ds_or_rtn_b64", VReg_64, "ds_or_b64">;
525defm DS_XOR_RTN_B64    : DS_1A1D_RET_mc<"ds_xor_rtn_b64", VReg_64, "ds_xor_b64">;
526defm DS_MSKOR_RTN_B64  : DS_1A2D_RET_mc<"ds_mskor_rtn_b64", VReg_64, "ds_mskor_b64">;
527defm DS_CMPST_RTN_B64  : DS_1A2D_RET_mc<"ds_cmpst_rtn_b64", VReg_64, "ds_cmpst_b64">;
528defm DS_CMPST_RTN_F64  : DS_1A2D_RET_mc<"ds_cmpst_rtn_f64", VReg_64, "ds_cmpst_f64">;
529defm DS_MIN_RTN_F64    : DS_1A1D_RET_mc<"ds_min_rtn_f64", VReg_64, "ds_min_f64">;
530defm DS_MAX_RTN_F64    : DS_1A1D_RET_mc<"ds_max_rtn_f64", VReg_64, "ds_max_f64">;
531
532defm DS_WRXCHG_RTN_B64 : DS_1A1D_RET_mc<"ds_wrxchg_rtn_b64", VReg_64>;
533defm DS_WRXCHG2_RTN_B64 : DS_1A2D_Off8_RET_mc<"ds_wrxchg2_rtn_b64", VReg_128, VReg_64>;
534defm DS_WRXCHG2ST64_RTN_B64 : DS_1A2D_Off8_RET_mc<"ds_wrxchg2st64_rtn_b64", VReg_128, VReg_64>;
535
536let isConvergent = 1, usesCustomInserter = 1 in {
537def DS_GWS_INIT       : DS_GWS_1D<"ds_gws_init"> {
538  let mayLoad = 0;
539}
540def DS_GWS_SEMA_V     : DS_GWS_0D<"ds_gws_sema_v">;
541def DS_GWS_SEMA_BR    : DS_GWS_1D<"ds_gws_sema_br">;
542def DS_GWS_SEMA_P     : DS_GWS_0D<"ds_gws_sema_p">;
543def DS_GWS_BARRIER    : DS_GWS_1D<"ds_gws_barrier">;
544}
545
546let SubtargetPredicate = HasDsSrc2Insts in {
547def DS_ADD_SRC2_U32   : DS_1A<"ds_add_src2_u32">;
548def DS_SUB_SRC2_U32   : DS_1A<"ds_sub_src2_u32">;
549def DS_RSUB_SRC2_U32  : DS_1A<"ds_rsub_src2_u32">;
550def DS_INC_SRC2_U32   : DS_1A<"ds_inc_src2_u32">;
551def DS_DEC_SRC2_U32   : DS_1A<"ds_dec_src2_u32">;
552def DS_MIN_SRC2_I32   : DS_1A<"ds_min_src2_i32">;
553def DS_MAX_SRC2_I32   : DS_1A<"ds_max_src2_i32">;
554def DS_MIN_SRC2_U32   : DS_1A<"ds_min_src2_u32">;
555def DS_MAX_SRC2_U32   : DS_1A<"ds_max_src2_u32">;
556def DS_AND_SRC2_B32   : DS_1A<"ds_and_src2_b32">;
557def DS_OR_SRC2_B32    : DS_1A<"ds_or_src2_b32">;
558def DS_XOR_SRC2_B32   : DS_1A<"ds_xor_src2_b32">;
559def DS_MIN_SRC2_F32   : DS_1A<"ds_min_src2_f32">;
560def DS_MAX_SRC2_F32   : DS_1A<"ds_max_src2_f32">;
561
562def DS_ADD_SRC2_U64   : DS_1A<"ds_add_src2_u64">;
563def DS_SUB_SRC2_U64   : DS_1A<"ds_sub_src2_u64">;
564def DS_RSUB_SRC2_U64  : DS_1A<"ds_rsub_src2_u64">;
565def DS_INC_SRC2_U64   : DS_1A<"ds_inc_src2_u64">;
566def DS_DEC_SRC2_U64   : DS_1A<"ds_dec_src2_u64">;
567def DS_MIN_SRC2_I64   : DS_1A<"ds_min_src2_i64">;
568def DS_MAX_SRC2_I64   : DS_1A<"ds_max_src2_i64">;
569def DS_MIN_SRC2_U64   : DS_1A<"ds_min_src2_u64">;
570def DS_MAX_SRC2_U64   : DS_1A<"ds_max_src2_u64">;
571def DS_AND_SRC2_B64   : DS_1A<"ds_and_src2_b64">;
572def DS_OR_SRC2_B64    : DS_1A<"ds_or_src2_b64">;
573def DS_XOR_SRC2_B64   : DS_1A<"ds_xor_src2_b64">;
574def DS_MIN_SRC2_F64   : DS_1A<"ds_min_src2_f64">;
575def DS_MAX_SRC2_F64   : DS_1A<"ds_max_src2_f64">;
576
577def DS_WRITE_SRC2_B32 : DS_1A<"ds_write_src2_b32">;
578def DS_WRITE_SRC2_B64 : DS_1A<"ds_write_src2_b64">;
579} // End SubtargetPredicate = HasDsSrc2Insts
580
581let Uses = [EXEC], mayLoad = 0, mayStore = 0, isConvergent = 1 in {
582def DS_SWIZZLE_B32 : DS_1A_RET <"ds_swizzle_b32", VGPR_32, 0, SwizzleImm>;
583}
584
585let mayStore = 0 in {
586defm DS_READ_I8      : DS_1A_RET_mc<"ds_read_i8">;
587defm DS_READ_U8      : DS_1A_RET_mc<"ds_read_u8">;
588defm DS_READ_I16     : DS_1A_RET_mc<"ds_read_i16">;
589defm DS_READ_U16     : DS_1A_RET_mc<"ds_read_u16">;
590defm DS_READ_B32     : DS_1A_RET_mc<"ds_read_b32">;
591defm DS_READ_B64     : DS_1A_RET_mc<"ds_read_b64", VReg_64>;
592
593defm DS_READ2_B32    : DS_1A_Off8_RET_mc<"ds_read2_b32", VReg_64>;
594defm DS_READ2ST64_B32: DS_1A_Off8_RET_mc<"ds_read2st64_b32", VReg_64>;
595
596defm DS_READ2_B64    : DS_1A_Off8_RET_mc<"ds_read2_b64", VReg_128>;
597defm DS_READ2ST64_B64: DS_1A_Off8_RET_mc<"ds_read2st64_b64", VReg_128>;
598
599let has_m0_read = 0 in {
600let SubtargetPredicate = HasD16LoadStore in {
601def DS_READ_U8_D16     : DS_1A_RET_Tied<"ds_read_u8_d16">;
602def DS_READ_U8_D16_HI  : DS_1A_RET_Tied<"ds_read_u8_d16_hi">;
603def DS_READ_I8_D16     : DS_1A_RET_Tied<"ds_read_i8_d16">;
604def DS_READ_I8_D16_HI  : DS_1A_RET_Tied<"ds_read_i8_d16_hi">;
605def DS_READ_U16_D16    : DS_1A_RET_Tied<"ds_read_u16_d16">;
606def DS_READ_U16_D16_HI : DS_1A_RET_Tied<"ds_read_u16_d16_hi">;
607}
608} // End has_m0_read = 0
609
610let SubtargetPredicate = HasDSAddTid in {
611def DS_READ_ADDTID_B32 : DS_0A_RET<"ds_read_addtid_b32">;
612}
613
614} // End mayStore = 0
615
616def DS_CONSUME       : DS_0A_RET<"ds_consume">;
617def DS_APPEND        : DS_0A_RET<"ds_append">;
618def DS_ORDERED_COUNT : DS_1A_RET_GDS<"ds_ordered_count">;
619
620//===----------------------------------------------------------------------===//
621// Instruction definitions for CI and newer.
622//===----------------------------------------------------------------------===//
623
624let SubtargetPredicate = isGFX7Plus in {
625
626defm DS_WRAP_RTN_B32 : DS_1A2D_RET_mc<"ds_wrap_rtn_b32", VGPR_32>;
627defm DS_CONDXCHG32_RTN_B64 : DS_1A1D_RET_mc<"ds_condxchg32_rtn_b64", VReg_64>;
628
629let isConvergent = 1, usesCustomInserter = 1 in {
630def DS_GWS_SEMA_RELEASE_ALL : DS_GWS_0D<"ds_gws_sema_release_all">;
631}
632
633let mayStore = 0 in {
634defm DS_READ_B96 : DS_1A_RET_mc<"ds_read_b96", VReg_96>;
635defm DS_READ_B128: DS_1A_RET_mc<"ds_read_b128", VReg_128>;
636} // End mayStore = 0
637
638let mayLoad = 0 in {
639defm DS_WRITE_B96 : DS_1A1D_NORET_mc<"ds_write_b96", VReg_96>;
640defm DS_WRITE_B128 : DS_1A1D_NORET_mc<"ds_write_b128", VReg_128>;
641} // End mayLoad = 0
642
643def DS_NOP : DS_VOID<"ds_nop">;
644
645} // let SubtargetPredicate = isGFX7Plus
646
647//===----------------------------------------------------------------------===//
648// Instruction definitions for VI and newer.
649//===----------------------------------------------------------------------===//
650
651let SubtargetPredicate = isGFX8Plus in {
652
653let Uses = [EXEC] in {
654def DS_PERMUTE_B32  : DS_1A1D_PERMUTE <"ds_permute_b32",
655                                       int_amdgcn_ds_permute>;
656def DS_BPERMUTE_B32 : DS_1A1D_PERMUTE <"ds_bpermute_b32",
657                                       int_amdgcn_ds_bpermute>;
658}
659
660} // let SubtargetPredicate = isGFX8Plus
661
662let SubtargetPredicate = HasLDSFPAtomics, OtherPredicates = [HasDsSrc2Insts] in {
663def DS_ADD_SRC2_F32 : DS_1A<"ds_add_src2_f32">;
664}
665
666//===----------------------------------------------------------------------===//
667// DS Patterns
668//===----------------------------------------------------------------------===//
669
670def : GCNPat <
671  (int_amdgcn_ds_swizzle i32:$src, timm:$offset16),
672  (DS_SWIZZLE_B32 VGPR_32:$src, (as_i16timm $offset16), (i1 0))
673>;
674
675class DSReadPat <DS_Pseudo inst, ValueType vt, PatFrag frag, int gds=0> : GCNPat <
676  (vt (frag (DS1Addr1Offset i32:$ptr, i16:$offset))),
677  (inst $ptr, offset:$offset, (i1 gds))
678>;
679
680multiclass DSReadPat_mc<DS_Pseudo inst, ValueType vt, string frag> {
681
682  let OtherPredicates = [LDSRequiresM0Init] in {
683    def : DSReadPat<inst, vt, !cast<PatFrag>(frag#"_m0")>;
684  }
685
686  let OtherPredicates = [NotLDSRequiresM0Init] in {
687    def : DSReadPat<!cast<DS_Pseudo>(!cast<string>(inst)#"_gfx9"), vt, !cast<PatFrag>(frag)>;
688  }
689}
690
691class DSReadPat_D16 <DS_Pseudo inst, PatFrag frag, ValueType vt> : GCNPat <
692  (frag (DS1Addr1Offset i32:$ptr, i16:$offset), vt:$in),
693  (inst $ptr, offset:$offset, (i1 0), $in)
694>;
695
696defm : DSReadPat_mc <DS_READ_I8, i32, "sextloadi8_local">;
697defm : DSReadPat_mc <DS_READ_I8,  i16, "sextloadi8_local">;
698defm : DSReadPat_mc <DS_READ_U8,  i32, "extloadi8_local">;
699defm : DSReadPat_mc <DS_READ_U8,  i32, "zextloadi8_local">;
700defm : DSReadPat_mc <DS_READ_U8,  i16, "extloadi8_local">;
701defm : DSReadPat_mc <DS_READ_U8,  i16, "zextloadi8_local">;
702defm : DSReadPat_mc <DS_READ_I16, i32, "sextloadi16_local">;
703defm : DSReadPat_mc <DS_READ_I16, i32, "sextloadi16_local">;
704defm : DSReadPat_mc <DS_READ_U16, i32, "extloadi16_local">;
705defm : DSReadPat_mc <DS_READ_U16, i32, "zextloadi16_local">;
706defm : DSReadPat_mc <DS_READ_U16, i16, "load_local">;
707
708foreach vt = Reg32Types.types in {
709defm : DSReadPat_mc <DS_READ_B32, vt, "load_local">;
710}
711
712defm : DSReadPat_mc <DS_READ_B32, i32, "atomic_load_32_local">;
713defm : DSReadPat_mc <DS_READ_B64, i64, "atomic_load_64_local">;
714
715let AddedComplexity = 100 in {
716
717foreach vt = VReg_64.RegTypes in {
718defm : DSReadPat_mc <DS_READ_B64, vt, "load_align8_local">;
719}
720
721let SubtargetPredicate = isGFX7Plus in {
722
723foreach vt = VReg_96.RegTypes in {
724defm : DSReadPat_mc <DS_READ_B96, vt, "load_align16_local">;
725}
726
727foreach vt = VReg_128.RegTypes in {
728defm : DSReadPat_mc <DS_READ_B128, vt, "load_align16_local">;
729}
730
731let SubtargetPredicate = HasUnalignedAccessMode in {
732
733foreach vt = VReg_96.RegTypes in {
734defm : DSReadPat_mc <DS_READ_B96, vt, "load_local">;
735}
736
737foreach vt = VReg_128.RegTypes in {
738defm : DSReadPat_mc <DS_READ_B128, vt, "load_local">;
739}
740
741} // End SubtargetPredicate = HasUnalignedAccessMode
742
743} // End SubtargetPredicate = isGFX7Plus
744
745} // End AddedComplexity = 100
746
747let OtherPredicates = [D16PreservesUnusedBits] in {
748def : DSReadPat_D16<DS_READ_U16_D16_HI, load_d16_hi_local, v2i16>;
749def : DSReadPat_D16<DS_READ_U16_D16_HI, load_d16_hi_local, v2f16>;
750def : DSReadPat_D16<DS_READ_U8_D16_HI, az_extloadi8_d16_hi_local, v2i16>;
751def : DSReadPat_D16<DS_READ_U8_D16_HI, az_extloadi8_d16_hi_local, v2f16>;
752def : DSReadPat_D16<DS_READ_I8_D16_HI, sextloadi8_d16_hi_local, v2i16>;
753def : DSReadPat_D16<DS_READ_I8_D16_HI, sextloadi8_d16_hi_local, v2f16>;
754
755def : DSReadPat_D16<DS_READ_U16_D16, load_d16_lo_local, v2i16>;
756def : DSReadPat_D16<DS_READ_U16_D16, load_d16_lo_local, v2f16>;
757def : DSReadPat_D16<DS_READ_U8_D16, az_extloadi8_d16_lo_local, v2i16>;
758def : DSReadPat_D16<DS_READ_U8_D16, az_extloadi8_d16_lo_local, v2f16>;
759def : DSReadPat_D16<DS_READ_I8_D16, sextloadi8_d16_lo_local, v2i16>;
760def : DSReadPat_D16<DS_READ_I8_D16, sextloadi8_d16_lo_local, v2f16>;
761}
762
763class DSWritePat <DS_Pseudo inst, ValueType vt, PatFrag frag, int gds=0> : GCNPat <
764  (frag vt:$value, (DS1Addr1Offset i32:$ptr, i16:$offset)),
765  (inst $ptr, getVregSrcForVT<vt>.ret:$value, offset:$offset, (i1 gds))
766>;
767
768multiclass DSWritePat_mc <DS_Pseudo inst, ValueType vt, string frag> {
769  let OtherPredicates = [LDSRequiresM0Init] in {
770    def : DSWritePat<inst, vt, !cast<PatFrag>(frag#"_m0")>;
771  }
772
773  let OtherPredicates = [NotLDSRequiresM0Init] in {
774    def : DSWritePat<!cast<DS_Pseudo>(!cast<string>(inst)#"_gfx9"), vt, !cast<PatFrag>(frag)>;
775  }
776}
777
778// Irritatingly, atomic_store reverses the order of operands from a
779// normal store.
780class DSAtomicWritePat <DS_Pseudo inst, ValueType vt, PatFrag frag> : GCNPat <
781  (frag (DS1Addr1Offset i32:$ptr, i16:$offset), vt:$value),
782  (inst $ptr, getVregSrcForVT<vt>.ret:$value, offset:$offset, (i1 0))
783>;
784
785multiclass DSAtomicWritePat_mc <DS_Pseudo inst, ValueType vt, string frag> {
786  let OtherPredicates = [LDSRequiresM0Init] in {
787    def : DSAtomicWritePat<inst, vt, !cast<PatFrag>(frag#"_m0")>;
788  }
789
790  let OtherPredicates = [NotLDSRequiresM0Init] in {
791    def : DSAtomicWritePat<!cast<DS_Pseudo>(!cast<string>(inst)#"_gfx9"), vt, !cast<PatFrag>(frag)>;
792  }
793}
794
795defm : DSWritePat_mc <DS_WRITE_B8, i32, "truncstorei8_local">;
796defm : DSWritePat_mc <DS_WRITE_B16, i32, "truncstorei16_local">;
797defm : DSWritePat_mc <DS_WRITE_B8, i16, "truncstorei8_local">;
798defm : DSWritePat_mc <DS_WRITE_B16, i16, "store_local">;
799
800foreach vt = Reg32Types.types in {
801defm : DSWritePat_mc <DS_WRITE_B32, vt, "store_local">;
802}
803
804defm : DSAtomicWritePat_mc <DS_WRITE_B32, i32, "atomic_store_local_32">;
805defm : DSAtomicWritePat_mc <DS_WRITE_B64, i64, "atomic_store_local_64">;
806
807let OtherPredicates = [D16PreservesUnusedBits] in {
808def : DSWritePat <DS_WRITE_B16_D16_HI, i32, store_hi16_local>;
809def : DSWritePat <DS_WRITE_B8_D16_HI, i32, truncstorei8_hi16_local>;
810}
811
812class DS64Bit4ByteAlignedReadPat<DS_Pseudo inst, ValueType vt, PatFrag frag> : GCNPat <
813  (vt:$value (frag (DS64Bit4ByteAligned i32:$ptr, i8:$offset0, i8:$offset1))),
814  (inst $ptr, $offset0, $offset1, (i1 0))
815>;
816
817class DS64Bit4ByteAlignedWritePat<DS_Pseudo inst, ValueType vt, PatFrag frag> : GCNPat<
818  (frag vt:$value, (DS64Bit4ByteAligned i32:$ptr, i8:$offset0, i8:$offset1)),
819  (inst $ptr, (i32 (EXTRACT_SUBREG VReg_64:$value, sub0)),
820              (i32 (EXTRACT_SUBREG VReg_64:$value, sub1)), $offset0, $offset1,
821              (i1 0))
822>;
823
824class DS128Bit8ByteAlignedReadPat<DS_Pseudo inst, ValueType vt, PatFrag frag> : GCNPat <
825  (vt:$value (frag (DS128Bit8ByteAligned i32:$ptr, i8:$offset0, i8:$offset1))),
826  (inst $ptr, $offset0, $offset1, (i1 0))
827>;
828
829class DS128Bit8ByteAlignedWritePat<DS_Pseudo inst, ValueType vt, PatFrag frag> : GCNPat<
830  (frag vt:$value, (DS128Bit8ByteAligned i32:$ptr, i8:$offset0, i8:$offset1)),
831  (inst $ptr, (i64 (EXTRACT_SUBREG VReg_128:$value, sub0_sub1)),
832              (i64 (EXTRACT_SUBREG VReg_128:$value, sub2_sub3)), $offset0, $offset1,
833              (i1 0))
834>;
835
836multiclass DS64Bit4ByteAlignedPat_mc<ValueType vt> {
837  let OtherPredicates = [LDSRequiresM0Init, isGFX7Plus] in {
838    def : DS64Bit4ByteAlignedReadPat<DS_READ2_B32, vt, load_local_m0>;
839    def : DS64Bit4ByteAlignedWritePat<DS_WRITE2_B32, vt, store_local_m0>;
840  }
841
842  let OtherPredicates = [NotLDSRequiresM0Init] in {
843    def : DS64Bit4ByteAlignedReadPat<DS_READ2_B32_gfx9, vt, load_local>;
844    def : DS64Bit4ByteAlignedWritePat<DS_WRITE2_B32_gfx9, vt, store_local>;
845  }
846}
847
848multiclass DS128Bit8ByteAlignedPat_mc<ValueType vt> {
849  let OtherPredicates = [LDSRequiresM0Init, isGFX7Plus] in {
850    def : DS128Bit8ByteAlignedReadPat<DS_READ2_B64, vt, load_local_m0>;
851    def : DS128Bit8ByteAlignedWritePat<DS_WRITE2_B64, vt, store_local_m0>;
852  }
853
854  let OtherPredicates = [NotLDSRequiresM0Init] in {
855    def : DS128Bit8ByteAlignedReadPat<DS_READ2_B64_gfx9, vt, load_local>;
856    def : DS128Bit8ByteAlignedWritePat<DS_WRITE2_B64_gfx9, vt, store_local>;
857  }
858}
859
860// v2i32 loads are split into i32 loads on SI during lowering, due to a bug
861// related to bounds checking.
862foreach vt = VReg_64.RegTypes in {
863defm : DS64Bit4ByteAlignedPat_mc<vt>;
864}
865
866foreach vt = VReg_128.RegTypes in {
867defm : DS128Bit8ByteAlignedPat_mc<vt>;
868}
869
870let AddedComplexity = 100 in {
871
872foreach vt = VReg_64.RegTypes in {
873defm : DSWritePat_mc <DS_WRITE_B64, vt, "store_align8_local">;
874}
875
876let SubtargetPredicate = isGFX7Plus in {
877
878foreach vt = VReg_96.RegTypes in {
879defm : DSWritePat_mc <DS_WRITE_B96, vt, "store_align16_local">;
880}
881
882foreach vt = VReg_128.RegTypes in {
883defm : DSWritePat_mc <DS_WRITE_B128, vt, "store_align16_local">;
884}
885
886let SubtargetPredicate = HasUnalignedAccessMode in {
887
888foreach vt = VReg_96.RegTypes in {
889defm : DSWritePat_mc <DS_WRITE_B96, vt, "store_local">;
890}
891
892foreach vt = VReg_128.RegTypes in {
893defm : DSWritePat_mc <DS_WRITE_B128, vt, "store_local">;
894}
895
896} // End SubtargetPredicate = HasUnalignedAccessMode
897
898} // End SubtargetPredicate = isGFX7Plus
899
900} // End AddedComplexity = 100
901
902class DSAtomicRetPat<DS_Pseudo inst, ValueType vt, PatFrag frag, bit gds=0> : GCNPat <
903  (frag (DS1Addr1Offset i32:$ptr, i16:$offset), vt:$value),
904  (inst $ptr, getVregSrcForVT<vt>.ret:$value, offset:$offset, (i1 gds))
905>;
906
907multiclass DSAtomicRetPat_mc<DS_Pseudo inst, ValueType vt, string frag> {
908  let OtherPredicates = [LDSRequiresM0Init] in {
909    def : DSAtomicRetPat<inst, vt, !cast<PatFrag>(frag#"_local_m0_"#vt.Size)>;
910  }
911
912  let OtherPredicates = [NotLDSRequiresM0Init] in {
913    def : DSAtomicRetPat<!cast<DS_Pseudo>(!cast<string>(inst)#"_gfx9"), vt,
914                         !cast<PatFrag>(frag#"_local_"#vt.Size)>;
915  }
916
917  def : DSAtomicRetPat<inst, vt, !cast<PatFrag>(frag#"_region_m0_"#vt.Size), 1>;
918}
919
920
921
922class DSAtomicCmpXChg<DS_Pseudo inst, ValueType vt, PatFrag frag, bit gds=0> : GCNPat <
923  (frag (DS1Addr1Offset i32:$ptr, i16:$offset), vt:$cmp, vt:$swap),
924  (inst $ptr, getVregSrcForVT<vt>.ret:$cmp, getVregSrcForVT<vt>.ret:$swap, offset:$offset, (i1 gds))
925>;
926
927multiclass DSAtomicCmpXChg_mc<DS_Pseudo inst, ValueType vt, string frag> {
928  let OtherPredicates = [LDSRequiresM0Init] in {
929    def : DSAtomicCmpXChg<inst, vt, !cast<PatFrag>(frag#"_local_m0_"#vt.Size)>;
930  }
931
932  let OtherPredicates = [NotLDSRequiresM0Init] in {
933    def : DSAtomicCmpXChg<!cast<DS_Pseudo>(!cast<string>(inst)#"_gfx9"), vt,
934                          !cast<PatFrag>(frag#"_local_"#vt.Size)>;
935  }
936
937  def : DSAtomicCmpXChg<inst, vt, !cast<PatFrag>(frag#"_region_m0_"#vt.Size), 1>;
938}
939
940
941
942// 32-bit atomics.
943defm : DSAtomicRetPat_mc<DS_WRXCHG_RTN_B32, i32, "atomic_swap">;
944defm : DSAtomicRetPat_mc<DS_ADD_RTN_U32, i32, "atomic_load_add">;
945defm : DSAtomicRetPat_mc<DS_SUB_RTN_U32, i32, "atomic_load_sub">;
946defm : DSAtomicRetPat_mc<DS_INC_RTN_U32, i32, "atomic_inc">;
947defm : DSAtomicRetPat_mc<DS_DEC_RTN_U32, i32, "atomic_dec">;
948defm : DSAtomicRetPat_mc<DS_AND_RTN_B32, i32, "atomic_load_and">;
949defm : DSAtomicRetPat_mc<DS_OR_RTN_B32, i32, "atomic_load_or">;
950defm : DSAtomicRetPat_mc<DS_XOR_RTN_B32, i32, "atomic_load_xor">;
951defm : DSAtomicRetPat_mc<DS_MIN_RTN_I32, i32, "atomic_load_min">;
952defm : DSAtomicRetPat_mc<DS_MAX_RTN_I32, i32, "atomic_load_max">;
953defm : DSAtomicRetPat_mc<DS_MIN_RTN_U32, i32, "atomic_load_umin">;
954defm : DSAtomicRetPat_mc<DS_MAX_RTN_U32, i32, "atomic_load_umax">;
955defm : DSAtomicCmpXChg_mc<DS_CMPST_RTN_B32, i32, "atomic_cmp_swap">;
956
957let SubtargetPredicate = HasLDSFPAtomics in {
958defm : DSAtomicRetPat_mc<DS_MIN_RTN_F32, f32, "atomic_load_fmin">;
959defm : DSAtomicRetPat_mc<DS_MAX_RTN_F32, f32, "atomic_load_fmax">;
960defm : DSAtomicRetPat_mc<DS_ADD_RTN_F32, f32, "atomic_load_fadd">;
961}
962
963// 64-bit atomics.
964defm : DSAtomicRetPat_mc<DS_WRXCHG_RTN_B64, i64, "atomic_swap">;
965defm : DSAtomicRetPat_mc<DS_ADD_RTN_U64, i64, "atomic_load_add">;
966defm : DSAtomicRetPat_mc<DS_SUB_RTN_U64, i64, "atomic_load_sub">;
967defm : DSAtomicRetPat_mc<DS_INC_RTN_U64, i64, "atomic_inc">;
968defm : DSAtomicRetPat_mc<DS_DEC_RTN_U64, i64, "atomic_dec">;
969defm : DSAtomicRetPat_mc<DS_AND_RTN_B64, i64, "atomic_load_and">;
970defm : DSAtomicRetPat_mc<DS_OR_RTN_B64, i64, "atomic_load_or">;
971defm : DSAtomicRetPat_mc<DS_XOR_RTN_B64, i64, "atomic_load_xor">;
972defm : DSAtomicRetPat_mc<DS_MIN_RTN_I64, i64, "atomic_load_min">;
973defm : DSAtomicRetPat_mc<DS_MAX_RTN_I64, i64, "atomic_load_max">;
974defm : DSAtomicRetPat_mc<DS_MIN_RTN_U64, i64, "atomic_load_umin">;
975defm : DSAtomicRetPat_mc<DS_MAX_RTN_U64, i64, "atomic_load_umax">;
976
977defm : DSAtomicCmpXChg_mc<DS_CMPST_RTN_B64, i64, "atomic_cmp_swap">;
978
979let SubtargetPredicate = isGFX90APlus in {
980def : DSAtomicRetPat<DS_ADD_RTN_F64, f64, atomic_load_fadd_local_64>;
981}
982
983def : Pat <
984  (SIds_ordered_count i32:$value, i16:$offset),
985  (DS_ORDERED_COUNT $value, (as_i16imm $offset))
986>;
987
988//===----------------------------------------------------------------------===//
989// Target-specific instruction encodings.
990//===----------------------------------------------------------------------===//
991
992//===----------------------------------------------------------------------===//
993// Base ENC_DS for GFX6, GFX7, GFX10.
994//===----------------------------------------------------------------------===//
995
996class Base_DS_Real_gfx6_gfx7_gfx10<bits<8> op, DS_Pseudo ps, int ef> :
997    DS_Real<ps>, SIMCInstr <ps.Mnemonic, ef> {
998
999  let Inst{7-0}   = !if(ps.has_offset0, offset0, 0);
1000  let Inst{15-8}  = !if(ps.has_offset1, offset1, 0);
1001  let Inst{17}    = !if(ps.has_gds, gds, ps.gdsValue);
1002  let Inst{25-18} = op;
1003  let Inst{31-26} = 0x36;
1004  let Inst{39-32} = !if(ps.has_addr, addr, !if(ps.has_gws_data0, data0{7-0}, 0));
1005  let Inst{47-40} = !if(ps.has_data0, data0{7-0}, 0);
1006  let Inst{55-48} = !if(ps.has_data1, data1{7-0}, 0);
1007  let Inst{63-56} = !if(ps.has_vdst, vdst{7-0}, 0);
1008}
1009
1010//===----------------------------------------------------------------------===//
1011// GFX10.
1012//===----------------------------------------------------------------------===//
1013
1014let AssemblerPredicate = isGFX10Plus, DecoderNamespace = "GFX10" in {
1015  multiclass DS_Real_gfx10<bits<8> op>  {
1016    def _gfx10 : Base_DS_Real_gfx6_gfx7_gfx10<op, !cast<DS_Pseudo>(NAME),
1017                                              SIEncodingFamily.GFX10>;
1018  }
1019} // End AssemblerPredicate = isGFX10Plus, DecoderNamespace = "GFX10"
1020
1021defm DS_ADD_F32          : DS_Real_gfx10<0x015>;
1022defm DS_ADD_RTN_F32      : DS_Real_gfx10<0x055>;
1023defm DS_ADD_SRC2_F32     : DS_Real_gfx10<0x095>;
1024defm DS_WRITE_B8_D16_HI  : DS_Real_gfx10<0x0a0>;
1025defm DS_WRITE_B16_D16_HI : DS_Real_gfx10<0x0a1>;
1026defm DS_READ_U8_D16      : DS_Real_gfx10<0x0a2>;
1027defm DS_READ_U8_D16_HI   : DS_Real_gfx10<0x0a3>;
1028defm DS_READ_I8_D16      : DS_Real_gfx10<0x0a4>;
1029defm DS_READ_I8_D16_HI   : DS_Real_gfx10<0x0a5>;
1030defm DS_READ_U16_D16     : DS_Real_gfx10<0x0a6>;
1031defm DS_READ_U16_D16_HI  : DS_Real_gfx10<0x0a7>;
1032defm DS_WRITE_ADDTID_B32 : DS_Real_gfx10<0x0b0>;
1033defm DS_READ_ADDTID_B32  : DS_Real_gfx10<0x0b1>;
1034defm DS_PERMUTE_B32      : DS_Real_gfx10<0x0b2>;
1035defm DS_BPERMUTE_B32     : DS_Real_gfx10<0x0b3>;
1036
1037//===----------------------------------------------------------------------===//
1038// GFX7, GFX10.
1039//===----------------------------------------------------------------------===//
1040
1041let AssemblerPredicate = isGFX7Only, DecoderNamespace = "GFX7" in {
1042  multiclass DS_Real_gfx7<bits<8> op> {
1043    def _gfx7 : Base_DS_Real_gfx6_gfx7_gfx10<op, !cast<DS_Pseudo>(NAME),
1044                                             SIEncodingFamily.SI>;
1045  }
1046} // End AssemblerPredicate = isGFX7Only, DecoderNamespace = "GFX7"
1047
1048multiclass DS_Real_gfx7_gfx10<bits<8> op> :
1049  DS_Real_gfx7<op>, DS_Real_gfx10<op>;
1050
1051// FIXME-GFX7: Add tests when upstreaming this part.
1052defm DS_GWS_SEMA_RELEASE_ALL : DS_Real_gfx7_gfx10<0x018>;
1053defm DS_WRAP_RTN_B32         : DS_Real_gfx7_gfx10<0x034>;
1054defm DS_CONDXCHG32_RTN_B64   : DS_Real_gfx7_gfx10<0x07e>;
1055defm DS_WRITE_B96            : DS_Real_gfx7_gfx10<0x0de>;
1056defm DS_WRITE_B128           : DS_Real_gfx7_gfx10<0x0df>;
1057defm DS_READ_B96             : DS_Real_gfx7_gfx10<0x0fe>;
1058defm DS_READ_B128            : DS_Real_gfx7_gfx10<0x0ff>;
1059
1060//===----------------------------------------------------------------------===//
1061// GFX6, GFX7, GFX10.
1062//===----------------------------------------------------------------------===//
1063
1064let AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" in {
1065  multiclass DS_Real_gfx6_gfx7<bits<8> op> {
1066    def _gfx6_gfx7 : Base_DS_Real_gfx6_gfx7_gfx10<op, !cast<DS_Pseudo>(NAME),
1067                                                  SIEncodingFamily.SI>;
1068  }
1069} // End AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7"
1070
1071multiclass DS_Real_gfx6_gfx7_gfx10<bits<8> op> :
1072  DS_Real_gfx6_gfx7<op>, DS_Real_gfx10<op>;
1073
1074defm DS_ADD_U32             : DS_Real_gfx6_gfx7_gfx10<0x000>;
1075defm DS_SUB_U32             : DS_Real_gfx6_gfx7_gfx10<0x001>;
1076defm DS_RSUB_U32            : DS_Real_gfx6_gfx7_gfx10<0x002>;
1077defm DS_INC_U32             : DS_Real_gfx6_gfx7_gfx10<0x003>;
1078defm DS_DEC_U32             : DS_Real_gfx6_gfx7_gfx10<0x004>;
1079defm DS_MIN_I32             : DS_Real_gfx6_gfx7_gfx10<0x005>;
1080defm DS_MAX_I32             : DS_Real_gfx6_gfx7_gfx10<0x006>;
1081defm DS_MIN_U32             : DS_Real_gfx6_gfx7_gfx10<0x007>;
1082defm DS_MAX_U32             : DS_Real_gfx6_gfx7_gfx10<0x008>;
1083defm DS_AND_B32             : DS_Real_gfx6_gfx7_gfx10<0x009>;
1084defm DS_OR_B32              : DS_Real_gfx6_gfx7_gfx10<0x00a>;
1085defm DS_XOR_B32             : DS_Real_gfx6_gfx7_gfx10<0x00b>;
1086defm DS_MSKOR_B32           : DS_Real_gfx6_gfx7_gfx10<0x00c>;
1087defm DS_WRITE_B32           : DS_Real_gfx6_gfx7_gfx10<0x00d>;
1088defm DS_WRITE2_B32          : DS_Real_gfx6_gfx7_gfx10<0x00e>;
1089defm DS_WRITE2ST64_B32      : DS_Real_gfx6_gfx7_gfx10<0x00f>;
1090defm DS_CMPST_B32           : DS_Real_gfx6_gfx7_gfx10<0x010>;
1091defm DS_CMPST_F32           : DS_Real_gfx6_gfx7_gfx10<0x011>;
1092defm DS_MIN_F32             : DS_Real_gfx6_gfx7_gfx10<0x012>;
1093defm DS_MAX_F32             : DS_Real_gfx6_gfx7_gfx10<0x013>;
1094defm DS_NOP                 : DS_Real_gfx6_gfx7_gfx10<0x014>;
1095defm DS_GWS_INIT            : DS_Real_gfx6_gfx7_gfx10<0x019>;
1096defm DS_GWS_SEMA_V          : DS_Real_gfx6_gfx7_gfx10<0x01a>;
1097defm DS_GWS_SEMA_BR         : DS_Real_gfx6_gfx7_gfx10<0x01b>;
1098defm DS_GWS_SEMA_P          : DS_Real_gfx6_gfx7_gfx10<0x01c>;
1099defm DS_GWS_BARRIER         : DS_Real_gfx6_gfx7_gfx10<0x01d>;
1100defm DS_WRITE_B8            : DS_Real_gfx6_gfx7_gfx10<0x01e>;
1101defm DS_WRITE_B16           : DS_Real_gfx6_gfx7_gfx10<0x01f>;
1102defm DS_ADD_RTN_U32         : DS_Real_gfx6_gfx7_gfx10<0x020>;
1103defm DS_SUB_RTN_U32         : DS_Real_gfx6_gfx7_gfx10<0x021>;
1104defm DS_RSUB_RTN_U32        : DS_Real_gfx6_gfx7_gfx10<0x022>;
1105defm DS_INC_RTN_U32         : DS_Real_gfx6_gfx7_gfx10<0x023>;
1106defm DS_DEC_RTN_U32         : DS_Real_gfx6_gfx7_gfx10<0x024>;
1107defm DS_MIN_RTN_I32         : DS_Real_gfx6_gfx7_gfx10<0x025>;
1108defm DS_MAX_RTN_I32         : DS_Real_gfx6_gfx7_gfx10<0x026>;
1109defm DS_MIN_RTN_U32         : DS_Real_gfx6_gfx7_gfx10<0x027>;
1110defm DS_MAX_RTN_U32         : DS_Real_gfx6_gfx7_gfx10<0x028>;
1111defm DS_AND_RTN_B32         : DS_Real_gfx6_gfx7_gfx10<0x029>;
1112defm DS_OR_RTN_B32          : DS_Real_gfx6_gfx7_gfx10<0x02a>;
1113defm DS_XOR_RTN_B32         : DS_Real_gfx6_gfx7_gfx10<0x02b>;
1114defm DS_MSKOR_RTN_B32       : DS_Real_gfx6_gfx7_gfx10<0x02c>;
1115defm DS_WRXCHG_RTN_B32      : DS_Real_gfx6_gfx7_gfx10<0x02d>;
1116defm DS_WRXCHG2_RTN_B32     : DS_Real_gfx6_gfx7_gfx10<0x02e>;
1117defm DS_WRXCHG2ST64_RTN_B32 : DS_Real_gfx6_gfx7_gfx10<0x02f>;
1118defm DS_CMPST_RTN_B32       : DS_Real_gfx6_gfx7_gfx10<0x030>;
1119defm DS_CMPST_RTN_F32       : DS_Real_gfx6_gfx7_gfx10<0x031>;
1120defm DS_MIN_RTN_F32         : DS_Real_gfx6_gfx7_gfx10<0x032>;
1121defm DS_MAX_RTN_F32         : DS_Real_gfx6_gfx7_gfx10<0x033>;
1122defm DS_SWIZZLE_B32         : DS_Real_gfx6_gfx7_gfx10<0x035>;
1123defm DS_READ_B32            : DS_Real_gfx6_gfx7_gfx10<0x036>;
1124defm DS_READ2_B32           : DS_Real_gfx6_gfx7_gfx10<0x037>;
1125defm DS_READ2ST64_B32       : DS_Real_gfx6_gfx7_gfx10<0x038>;
1126defm DS_READ_I8             : DS_Real_gfx6_gfx7_gfx10<0x039>;
1127defm DS_READ_U8             : DS_Real_gfx6_gfx7_gfx10<0x03a>;
1128defm DS_READ_I16            : DS_Real_gfx6_gfx7_gfx10<0x03b>;
1129defm DS_READ_U16            : DS_Real_gfx6_gfx7_gfx10<0x03c>;
1130defm DS_CONSUME             : DS_Real_gfx6_gfx7_gfx10<0x03d>;
1131defm DS_APPEND              : DS_Real_gfx6_gfx7_gfx10<0x03e>;
1132defm DS_ORDERED_COUNT       : DS_Real_gfx6_gfx7_gfx10<0x03f>;
1133defm DS_ADD_U64             : DS_Real_gfx6_gfx7_gfx10<0x040>;
1134defm DS_SUB_U64             : DS_Real_gfx6_gfx7_gfx10<0x041>;
1135defm DS_RSUB_U64            : DS_Real_gfx6_gfx7_gfx10<0x042>;
1136defm DS_INC_U64             : DS_Real_gfx6_gfx7_gfx10<0x043>;
1137defm DS_DEC_U64             : DS_Real_gfx6_gfx7_gfx10<0x044>;
1138defm DS_MIN_I64             : DS_Real_gfx6_gfx7_gfx10<0x045>;
1139defm DS_MAX_I64             : DS_Real_gfx6_gfx7_gfx10<0x046>;
1140defm DS_MIN_U64             : DS_Real_gfx6_gfx7_gfx10<0x047>;
1141defm DS_MAX_U64             : DS_Real_gfx6_gfx7_gfx10<0x048>;
1142defm DS_AND_B64             : DS_Real_gfx6_gfx7_gfx10<0x049>;
1143defm DS_OR_B64              : DS_Real_gfx6_gfx7_gfx10<0x04a>;
1144defm DS_XOR_B64             : DS_Real_gfx6_gfx7_gfx10<0x04b>;
1145defm DS_MSKOR_B64           : DS_Real_gfx6_gfx7_gfx10<0x04c>;
1146defm DS_WRITE_B64           : DS_Real_gfx6_gfx7_gfx10<0x04d>;
1147defm DS_WRITE2_B64          : DS_Real_gfx6_gfx7_gfx10<0x04e>;
1148defm DS_WRITE2ST64_B64      : DS_Real_gfx6_gfx7_gfx10<0x04f>;
1149defm DS_CMPST_B64           : DS_Real_gfx6_gfx7_gfx10<0x050>;
1150defm DS_CMPST_F64           : DS_Real_gfx6_gfx7_gfx10<0x051>;
1151defm DS_MIN_F64             : DS_Real_gfx6_gfx7_gfx10<0x052>;
1152defm DS_MAX_F64             : DS_Real_gfx6_gfx7_gfx10<0x053>;
1153defm DS_ADD_RTN_U64         : DS_Real_gfx6_gfx7_gfx10<0x060>;
1154defm DS_SUB_RTN_U64         : DS_Real_gfx6_gfx7_gfx10<0x061>;
1155defm DS_RSUB_RTN_U64        : DS_Real_gfx6_gfx7_gfx10<0x062>;
1156defm DS_INC_RTN_U64         : DS_Real_gfx6_gfx7_gfx10<0x063>;
1157defm DS_DEC_RTN_U64         : DS_Real_gfx6_gfx7_gfx10<0x064>;
1158defm DS_MIN_RTN_I64         : DS_Real_gfx6_gfx7_gfx10<0x065>;
1159defm DS_MAX_RTN_I64         : DS_Real_gfx6_gfx7_gfx10<0x066>;
1160defm DS_MIN_RTN_U64         : DS_Real_gfx6_gfx7_gfx10<0x067>;
1161defm DS_MAX_RTN_U64         : DS_Real_gfx6_gfx7_gfx10<0x068>;
1162defm DS_AND_RTN_B64         : DS_Real_gfx6_gfx7_gfx10<0x069>;
1163defm DS_OR_RTN_B64          : DS_Real_gfx6_gfx7_gfx10<0x06a>;
1164defm DS_XOR_RTN_B64         : DS_Real_gfx6_gfx7_gfx10<0x06b>;
1165defm DS_MSKOR_RTN_B64       : DS_Real_gfx6_gfx7_gfx10<0x06c>;
1166defm DS_WRXCHG_RTN_B64      : DS_Real_gfx6_gfx7_gfx10<0x06d>;
1167defm DS_WRXCHG2_RTN_B64     : DS_Real_gfx6_gfx7_gfx10<0x06e>;
1168defm DS_WRXCHG2ST64_RTN_B64 : DS_Real_gfx6_gfx7_gfx10<0x06f>;
1169defm DS_CMPST_RTN_B64       : DS_Real_gfx6_gfx7_gfx10<0x070>;
1170defm DS_CMPST_RTN_F64       : DS_Real_gfx6_gfx7_gfx10<0x071>;
1171defm DS_MIN_RTN_F64         : DS_Real_gfx6_gfx7_gfx10<0x072>;
1172defm DS_MAX_RTN_F64         : DS_Real_gfx6_gfx7_gfx10<0x073>;
1173defm DS_READ_B64            : DS_Real_gfx6_gfx7_gfx10<0x076>;
1174defm DS_READ2_B64           : DS_Real_gfx6_gfx7_gfx10<0x077>;
1175defm DS_READ2ST64_B64       : DS_Real_gfx6_gfx7_gfx10<0x078>;
1176defm DS_ADD_SRC2_U32        : DS_Real_gfx6_gfx7_gfx10<0x080>;
1177defm DS_SUB_SRC2_U32        : DS_Real_gfx6_gfx7_gfx10<0x081>;
1178defm DS_RSUB_SRC2_U32       : DS_Real_gfx6_gfx7_gfx10<0x082>;
1179defm DS_INC_SRC2_U32        : DS_Real_gfx6_gfx7_gfx10<0x083>;
1180defm DS_DEC_SRC2_U32        : DS_Real_gfx6_gfx7_gfx10<0x084>;
1181defm DS_MIN_SRC2_I32        : DS_Real_gfx6_gfx7_gfx10<0x085>;
1182defm DS_MAX_SRC2_I32        : DS_Real_gfx6_gfx7_gfx10<0x086>;
1183defm DS_MIN_SRC2_U32        : DS_Real_gfx6_gfx7_gfx10<0x087>;
1184defm DS_MAX_SRC2_U32        : DS_Real_gfx6_gfx7_gfx10<0x088>;
1185defm DS_AND_SRC2_B32        : DS_Real_gfx6_gfx7_gfx10<0x089>;
1186defm DS_OR_SRC2_B32         : DS_Real_gfx6_gfx7_gfx10<0x08a>;
1187defm DS_XOR_SRC2_B32        : DS_Real_gfx6_gfx7_gfx10<0x08b>;
1188defm DS_WRITE_SRC2_B32      : DS_Real_gfx6_gfx7_gfx10<0x08d>;
1189defm DS_MIN_SRC2_F32        : DS_Real_gfx6_gfx7_gfx10<0x092>;
1190defm DS_MAX_SRC2_F32        : DS_Real_gfx6_gfx7_gfx10<0x093>;
1191defm DS_ADD_SRC2_U64        : DS_Real_gfx6_gfx7_gfx10<0x0c0>;
1192defm DS_SUB_SRC2_U64        : DS_Real_gfx6_gfx7_gfx10<0x0c1>;
1193defm DS_RSUB_SRC2_U64       : DS_Real_gfx6_gfx7_gfx10<0x0c2>;
1194defm DS_INC_SRC2_U64        : DS_Real_gfx6_gfx7_gfx10<0x0c3>;
1195defm DS_DEC_SRC2_U64        : DS_Real_gfx6_gfx7_gfx10<0x0c4>;
1196defm DS_MIN_SRC2_I64        : DS_Real_gfx6_gfx7_gfx10<0x0c5>;
1197defm DS_MAX_SRC2_I64        : DS_Real_gfx6_gfx7_gfx10<0x0c6>;
1198defm DS_MIN_SRC2_U64        : DS_Real_gfx6_gfx7_gfx10<0x0c7>;
1199defm DS_MAX_SRC2_U64        : DS_Real_gfx6_gfx7_gfx10<0x0c8>;
1200defm DS_AND_SRC2_B64        : DS_Real_gfx6_gfx7_gfx10<0x0c9>;
1201defm DS_OR_SRC2_B64         : DS_Real_gfx6_gfx7_gfx10<0x0ca>;
1202defm DS_XOR_SRC2_B64        : DS_Real_gfx6_gfx7_gfx10<0x0cb>;
1203defm DS_WRITE_SRC2_B64      : DS_Real_gfx6_gfx7_gfx10<0x0cd>;
1204defm DS_MIN_SRC2_F64        : DS_Real_gfx6_gfx7_gfx10<0x0d2>;
1205defm DS_MAX_SRC2_F64        : DS_Real_gfx6_gfx7_gfx10<0x0d3>;
1206
1207//===----------------------------------------------------------------------===//
1208// GFX8, GFX9 (VI).
1209//===----------------------------------------------------------------------===//
1210
1211class DS_Real_vi <bits<8> op, DS_Pseudo ds> :
1212  DS_Real <ds>,
1213  SIMCInstr <ds.Mnemonic, SIEncodingFamily.VI> {
1214  let AssemblerPredicate = isGFX8GFX9;
1215  let DecoderNamespace = "GFX8";
1216
1217  // encoding
1218  let Inst{7-0}   = !if(ds.has_offset0, offset0, 0);
1219  let Inst{15-8}  = !if(ds.has_offset1, offset1, 0);
1220  let Inst{16}    = !if(ds.has_gds, gds, ds.gdsValue);
1221  let Inst{24-17} = op;
1222  let Inst{25}    = acc;
1223  let Inst{31-26} = 0x36; // ds prefix
1224  let Inst{39-32} = !if(ds.has_addr, addr, !if(ds.has_gws_data0, data0{7-0}, 0));
1225  let Inst{47-40} = !if(ds.has_data0, data0{7-0}, 0);
1226  let Inst{55-48} = !if(ds.has_data1, data1{7-0}, 0);
1227  let Inst{63-56} = !if(ds.has_vdst, vdst{7-0}, 0);
1228}
1229
1230def DS_ADD_U32_vi         : DS_Real_vi<0x0,  DS_ADD_U32>;
1231def DS_SUB_U32_vi         : DS_Real_vi<0x1,  DS_SUB_U32>;
1232def DS_RSUB_U32_vi        : DS_Real_vi<0x2,  DS_RSUB_U32>;
1233def DS_INC_U32_vi         : DS_Real_vi<0x3,  DS_INC_U32>;
1234def DS_DEC_U32_vi         : DS_Real_vi<0x4,  DS_DEC_U32>;
1235def DS_MIN_I32_vi         : DS_Real_vi<0x5,  DS_MIN_I32>;
1236def DS_MAX_I32_vi         : DS_Real_vi<0x6,  DS_MAX_I32>;
1237def DS_MIN_U32_vi         : DS_Real_vi<0x7,  DS_MIN_U32>;
1238def DS_MAX_U32_vi         : DS_Real_vi<0x8,  DS_MAX_U32>;
1239def DS_AND_B32_vi         : DS_Real_vi<0x9,  DS_AND_B32>;
1240def DS_OR_B32_vi          : DS_Real_vi<0xa,  DS_OR_B32>;
1241def DS_XOR_B32_vi         : DS_Real_vi<0xb,  DS_XOR_B32>;
1242def DS_MSKOR_B32_vi       : DS_Real_vi<0xc,  DS_MSKOR_B32>;
1243def DS_WRITE_B32_vi       : DS_Real_vi<0xd,  DS_WRITE_B32>;
1244def DS_WRITE2_B32_vi      : DS_Real_vi<0xe,  DS_WRITE2_B32>;
1245def DS_WRITE2ST64_B32_vi  : DS_Real_vi<0xf,  DS_WRITE2ST64_B32>;
1246def DS_CMPST_B32_vi       : DS_Real_vi<0x10, DS_CMPST_B32>;
1247def DS_CMPST_F32_vi       : DS_Real_vi<0x11, DS_CMPST_F32>;
1248def DS_MIN_F32_vi         : DS_Real_vi<0x12, DS_MIN_F32>;
1249def DS_MAX_F32_vi         : DS_Real_vi<0x13, DS_MAX_F32>;
1250def DS_NOP_vi             : DS_Real_vi<0x14, DS_NOP>;
1251def DS_ADD_F32_vi         : DS_Real_vi<0x15, DS_ADD_F32>;
1252def DS_GWS_INIT_vi        : DS_Real_vi<0x99, DS_GWS_INIT>;
1253def DS_GWS_SEMA_V_vi      : DS_Real_vi<0x9a, DS_GWS_SEMA_V>;
1254def DS_GWS_SEMA_BR_vi     : DS_Real_vi<0x9b, DS_GWS_SEMA_BR>;
1255def DS_GWS_SEMA_P_vi      : DS_Real_vi<0x9c, DS_GWS_SEMA_P>;
1256def DS_GWS_BARRIER_vi     : DS_Real_vi<0x9d, DS_GWS_BARRIER>;
1257def DS_WRITE_ADDTID_B32_vi : DS_Real_vi<0x1d, DS_WRITE_ADDTID_B32>;
1258def DS_WRITE_B8_vi        : DS_Real_vi<0x1e, DS_WRITE_B8>;
1259def DS_WRITE_B16_vi       : DS_Real_vi<0x1f, DS_WRITE_B16>;
1260def DS_ADD_RTN_U32_vi     : DS_Real_vi<0x20, DS_ADD_RTN_U32>;
1261def DS_SUB_RTN_U32_vi     : DS_Real_vi<0x21, DS_SUB_RTN_U32>;
1262def DS_RSUB_RTN_U32_vi    : DS_Real_vi<0x22, DS_RSUB_RTN_U32>;
1263def DS_INC_RTN_U32_vi     : DS_Real_vi<0x23, DS_INC_RTN_U32>;
1264def DS_DEC_RTN_U32_vi     : DS_Real_vi<0x24, DS_DEC_RTN_U32>;
1265def DS_MIN_RTN_I32_vi     : DS_Real_vi<0x25, DS_MIN_RTN_I32>;
1266def DS_MAX_RTN_I32_vi     : DS_Real_vi<0x26, DS_MAX_RTN_I32>;
1267def DS_MIN_RTN_U32_vi     : DS_Real_vi<0x27, DS_MIN_RTN_U32>;
1268def DS_MAX_RTN_U32_vi     : DS_Real_vi<0x28, DS_MAX_RTN_U32>;
1269def DS_AND_RTN_B32_vi     : DS_Real_vi<0x29, DS_AND_RTN_B32>;
1270def DS_OR_RTN_B32_vi      : DS_Real_vi<0x2a, DS_OR_RTN_B32>;
1271def DS_XOR_RTN_B32_vi     : DS_Real_vi<0x2b, DS_XOR_RTN_B32>;
1272def DS_MSKOR_RTN_B32_vi   : DS_Real_vi<0x2c, DS_MSKOR_RTN_B32>;
1273def DS_WRXCHG_RTN_B32_vi  : DS_Real_vi<0x2d, DS_WRXCHG_RTN_B32>;
1274def DS_WRXCHG2_RTN_B32_vi : DS_Real_vi<0x2e, DS_WRXCHG2_RTN_B32>;
1275def DS_WRXCHG2ST64_RTN_B32_vi : DS_Real_vi<0x2f, DS_WRXCHG2ST64_RTN_B32>;
1276def DS_CMPST_RTN_B32_vi   : DS_Real_vi<0x30, DS_CMPST_RTN_B32>;
1277def DS_CMPST_RTN_F32_vi   : DS_Real_vi<0x31, DS_CMPST_RTN_F32>;
1278def DS_MIN_RTN_F32_vi     : DS_Real_vi<0x32, DS_MIN_RTN_F32>;
1279def DS_MAX_RTN_F32_vi     : DS_Real_vi<0x33, DS_MAX_RTN_F32>;
1280def DS_WRAP_RTN_B32_vi    : DS_Real_vi<0x34, DS_WRAP_RTN_B32>;
1281def DS_ADD_RTN_F32_vi     : DS_Real_vi<0x35, DS_ADD_RTN_F32>;
1282def DS_READ_B32_vi        : DS_Real_vi<0x36, DS_READ_B32>;
1283def DS_READ2_B32_vi       : DS_Real_vi<0x37, DS_READ2_B32>;
1284def DS_READ2ST64_B32_vi   : DS_Real_vi<0x38, DS_READ2ST64_B32>;
1285def DS_READ_I8_vi         : DS_Real_vi<0x39, DS_READ_I8>;
1286def DS_READ_U8_vi         : DS_Real_vi<0x3a, DS_READ_U8>;
1287def DS_READ_I16_vi        : DS_Real_vi<0x3b, DS_READ_I16>;
1288def DS_READ_U16_vi        : DS_Real_vi<0x3c, DS_READ_U16>;
1289def DS_READ_ADDTID_B32_vi : DS_Real_vi<0xb6, DS_READ_ADDTID_B32>;
1290def DS_CONSUME_vi         : DS_Real_vi<0xbd, DS_CONSUME>;
1291def DS_APPEND_vi          : DS_Real_vi<0xbe, DS_APPEND>;
1292def DS_ORDERED_COUNT_vi   : DS_Real_vi<0xbf, DS_ORDERED_COUNT>;
1293def DS_SWIZZLE_B32_vi     : DS_Real_vi<0x3d, DS_SWIZZLE_B32>;
1294def DS_PERMUTE_B32_vi     : DS_Real_vi<0x3e, DS_PERMUTE_B32>;
1295def DS_BPERMUTE_B32_vi    : DS_Real_vi<0x3f, DS_BPERMUTE_B32>;
1296
1297def DS_ADD_U64_vi         : DS_Real_vi<0x40, DS_ADD_U64>;
1298def DS_SUB_U64_vi         : DS_Real_vi<0x41, DS_SUB_U64>;
1299def DS_RSUB_U64_vi        : DS_Real_vi<0x42, DS_RSUB_U64>;
1300def DS_INC_U64_vi         : DS_Real_vi<0x43, DS_INC_U64>;
1301def DS_DEC_U64_vi         : DS_Real_vi<0x44, DS_DEC_U64>;
1302def DS_MIN_I64_vi         : DS_Real_vi<0x45, DS_MIN_I64>;
1303def DS_MAX_I64_vi         : DS_Real_vi<0x46, DS_MAX_I64>;
1304def DS_MIN_U64_vi         : DS_Real_vi<0x47, DS_MIN_U64>;
1305def DS_MAX_U64_vi         : DS_Real_vi<0x48, DS_MAX_U64>;
1306def DS_AND_B64_vi         : DS_Real_vi<0x49, DS_AND_B64>;
1307def DS_OR_B64_vi          : DS_Real_vi<0x4a, DS_OR_B64>;
1308def DS_XOR_B64_vi         : DS_Real_vi<0x4b, DS_XOR_B64>;
1309def DS_MSKOR_B64_vi       : DS_Real_vi<0x4c, DS_MSKOR_B64>;
1310def DS_WRITE_B64_vi       : DS_Real_vi<0x4d, DS_WRITE_B64>;
1311def DS_WRITE2_B64_vi      : DS_Real_vi<0x4E, DS_WRITE2_B64>;
1312def DS_WRITE2ST64_B64_vi  : DS_Real_vi<0x4f, DS_WRITE2ST64_B64>;
1313def DS_CMPST_B64_vi       : DS_Real_vi<0x50, DS_CMPST_B64>;
1314def DS_CMPST_F64_vi       : DS_Real_vi<0x51, DS_CMPST_F64>;
1315def DS_MIN_F64_vi         : DS_Real_vi<0x52, DS_MIN_F64>;
1316def DS_MAX_F64_vi         : DS_Real_vi<0x53, DS_MAX_F64>;
1317
1318def DS_WRITE_B8_D16_HI_vi  : DS_Real_vi<0x54, DS_WRITE_B8_D16_HI>;
1319def DS_WRITE_B16_D16_HI_vi : DS_Real_vi<0x55, DS_WRITE_B16_D16_HI>;
1320
1321def DS_READ_U8_D16_vi     : DS_Real_vi<0x56, DS_READ_U8_D16>;
1322def DS_READ_U8_D16_HI_vi  : DS_Real_vi<0x57, DS_READ_U8_D16_HI>;
1323def DS_READ_I8_D16_vi     : DS_Real_vi<0x58, DS_READ_I8_D16>;
1324def DS_READ_I8_D16_HI_vi  : DS_Real_vi<0x59, DS_READ_I8_D16_HI>;
1325def DS_READ_U16_D16_vi    : DS_Real_vi<0x5a, DS_READ_U16_D16>;
1326def DS_READ_U16_D16_HI_vi : DS_Real_vi<0x5b, DS_READ_U16_D16_HI>;
1327
1328def DS_ADD_RTN_U64_vi     : DS_Real_vi<0x60, DS_ADD_RTN_U64>;
1329def DS_SUB_RTN_U64_vi     : DS_Real_vi<0x61, DS_SUB_RTN_U64>;
1330def DS_RSUB_RTN_U64_vi    : DS_Real_vi<0x62, DS_RSUB_RTN_U64>;
1331def DS_INC_RTN_U64_vi     : DS_Real_vi<0x63, DS_INC_RTN_U64>;
1332def DS_DEC_RTN_U64_vi     : DS_Real_vi<0x64, DS_DEC_RTN_U64>;
1333def DS_MIN_RTN_I64_vi     : DS_Real_vi<0x65, DS_MIN_RTN_I64>;
1334def DS_MAX_RTN_I64_vi     : DS_Real_vi<0x66, DS_MAX_RTN_I64>;
1335def DS_MIN_RTN_U64_vi     : DS_Real_vi<0x67, DS_MIN_RTN_U64>;
1336def DS_MAX_RTN_U64_vi     : DS_Real_vi<0x68, DS_MAX_RTN_U64>;
1337def DS_AND_RTN_B64_vi     : DS_Real_vi<0x69, DS_AND_RTN_B64>;
1338def DS_OR_RTN_B64_vi      : DS_Real_vi<0x6a, DS_OR_RTN_B64>;
1339def DS_XOR_RTN_B64_vi     : DS_Real_vi<0x6b, DS_XOR_RTN_B64>;
1340def DS_MSKOR_RTN_B64_vi   : DS_Real_vi<0x6c, DS_MSKOR_RTN_B64>;
1341def DS_WRXCHG_RTN_B64_vi  : DS_Real_vi<0x6d, DS_WRXCHG_RTN_B64>;
1342def DS_WRXCHG2_RTN_B64_vi : DS_Real_vi<0x6e, DS_WRXCHG2_RTN_B64>;
1343def DS_WRXCHG2ST64_RTN_B64_vi : DS_Real_vi<0x6f, DS_WRXCHG2ST64_RTN_B64>;
1344def DS_CONDXCHG32_RTN_B64_vi   : DS_Real_vi<0x7e, DS_CONDXCHG32_RTN_B64>;
1345def DS_GWS_SEMA_RELEASE_ALL_vi : DS_Real_vi<0x98, DS_GWS_SEMA_RELEASE_ALL>;
1346def DS_CMPST_RTN_B64_vi   : DS_Real_vi<0x70, DS_CMPST_RTN_B64>;
1347def DS_CMPST_RTN_F64_vi   : DS_Real_vi<0x71, DS_CMPST_RTN_F64>;
1348def DS_MIN_RTN_F64_vi     : DS_Real_vi<0x72, DS_MIN_RTN_F64>;
1349def DS_MAX_RTN_F64_vi     : DS_Real_vi<0x73, DS_MAX_RTN_F64>;
1350
1351def DS_READ_B64_vi        : DS_Real_vi<0x76, DS_READ_B64>;
1352def DS_READ2_B64_vi       : DS_Real_vi<0x77, DS_READ2_B64>;
1353def DS_READ2ST64_B64_vi   : DS_Real_vi<0x78, DS_READ2ST64_B64>;
1354
1355def DS_ADD_SRC2_U32_vi    : DS_Real_vi<0x80, DS_ADD_SRC2_U32>;
1356def DS_SUB_SRC2_U32_vi    : DS_Real_vi<0x81, DS_SUB_SRC2_U32>;
1357def DS_RSUB_SRC2_U32_vi   : DS_Real_vi<0x82, DS_RSUB_SRC2_U32>;
1358def DS_INC_SRC2_U32_vi    : DS_Real_vi<0x83, DS_INC_SRC2_U32>;
1359def DS_DEC_SRC2_U32_vi    : DS_Real_vi<0x84, DS_DEC_SRC2_U32>;
1360def DS_MIN_SRC2_I32_vi    : DS_Real_vi<0x85, DS_MIN_SRC2_I32>;
1361def DS_MAX_SRC2_I32_vi    : DS_Real_vi<0x86, DS_MAX_SRC2_I32>;
1362def DS_MIN_SRC2_U32_vi    : DS_Real_vi<0x87, DS_MIN_SRC2_U32>;
1363def DS_MAX_SRC2_U32_vi    : DS_Real_vi<0x88, DS_MAX_SRC2_U32>;
1364def DS_AND_SRC2_B32_vi    : DS_Real_vi<0x89, DS_AND_SRC2_B32>;
1365def DS_OR_SRC2_B32_vi     : DS_Real_vi<0x8a, DS_OR_SRC2_B32>;
1366def DS_XOR_SRC2_B32_vi    : DS_Real_vi<0x8b, DS_XOR_SRC2_B32>;
1367def DS_WRITE_SRC2_B32_vi  : DS_Real_vi<0x8d, DS_WRITE_SRC2_B32>;
1368def DS_MIN_SRC2_F32_vi    : DS_Real_vi<0x92, DS_MIN_SRC2_F32>;
1369def DS_MAX_SRC2_F32_vi    : DS_Real_vi<0x93, DS_MAX_SRC2_F32>;
1370def DS_ADD_SRC2_F32_vi    : DS_Real_vi<0x95, DS_ADD_SRC2_F32>;
1371def DS_ADD_SRC2_U64_vi    : DS_Real_vi<0xc0, DS_ADD_SRC2_U64>;
1372def DS_SUB_SRC2_U64_vi    : DS_Real_vi<0xc1, DS_SUB_SRC2_U64>;
1373def DS_RSUB_SRC2_U64_vi   : DS_Real_vi<0xc2, DS_RSUB_SRC2_U64>;
1374def DS_INC_SRC2_U64_vi    : DS_Real_vi<0xc3, DS_INC_SRC2_U64>;
1375def DS_DEC_SRC2_U64_vi    : DS_Real_vi<0xc4, DS_DEC_SRC2_U64>;
1376def DS_MIN_SRC2_I64_vi    : DS_Real_vi<0xc5, DS_MIN_SRC2_I64>;
1377def DS_MAX_SRC2_I64_vi    : DS_Real_vi<0xc6, DS_MAX_SRC2_I64>;
1378def DS_MIN_SRC2_U64_vi    : DS_Real_vi<0xc7, DS_MIN_SRC2_U64>;
1379def DS_MAX_SRC2_U64_vi    : DS_Real_vi<0xc8, DS_MAX_SRC2_U64>;
1380def DS_AND_SRC2_B64_vi    : DS_Real_vi<0xc9, DS_AND_SRC2_B64>;
1381def DS_OR_SRC2_B64_vi     : DS_Real_vi<0xca, DS_OR_SRC2_B64>;
1382def DS_XOR_SRC2_B64_vi    : DS_Real_vi<0xcb, DS_XOR_SRC2_B64>;
1383def DS_WRITE_SRC2_B64_vi  : DS_Real_vi<0xcd, DS_WRITE_SRC2_B64>;
1384def DS_MIN_SRC2_F64_vi    : DS_Real_vi<0xd2, DS_MIN_SRC2_F64>;
1385def DS_MAX_SRC2_F64_vi    : DS_Real_vi<0xd3, DS_MAX_SRC2_F64>;
1386def DS_WRITE_B96_vi       : DS_Real_vi<0xde, DS_WRITE_B96>;
1387def DS_WRITE_B128_vi      : DS_Real_vi<0xdf, DS_WRITE_B128>;
1388def DS_READ_B96_vi        : DS_Real_vi<0xfe, DS_READ_B96>;
1389def DS_READ_B128_vi       : DS_Real_vi<0xff, DS_READ_B128>;
1390
1391let SubtargetPredicate = isGFX90APlus in {
1392  def DS_ADD_F64_vi     : DS_Real_vi<0x5c, DS_ADD_F64>;
1393  def DS_ADD_RTN_F64_vi : DS_Real_vi<0x7c, DS_ADD_RTN_F64>;
1394} // End SubtargetPredicate = isGFX90APlus
1395