1//===-- FLATInstructions.td - FLAT Instruction Defintions -----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10def FLATAtomic : ComplexPattern<i64, 3, "SelectFlat">;
11
12//===----------------------------------------------------------------------===//
13// FLAT classes
14//===----------------------------------------------------------------------===//
15
16class FLAT_Pseudo<string opName, dag outs, dag ins,
17                  string asmOps, list<dag> pattern=[]> :
18  InstSI<outs, ins, "", pattern>,
19  SIMCInstr<opName, SIEncodingFamily.NONE> {
20
21  let isPseudo = 1;
22  let isCodeGenOnly = 1;
23
24  let SubtargetPredicate = isCIVI;
25
26  let FLAT = 1;
27  // Internally, FLAT instruction are executed as both an LDS and a
28  // Buffer instruction; so, they increment both VM_CNT and LGKM_CNT
29  // and are not considered done until both have been decremented.
30  let VM_CNT = 1;
31  let LGKM_CNT = 1;
32
33  let Uses = [EXEC, FLAT_SCR]; // M0
34
35  let UseNamedOperandTable = 1;
36  let hasSideEffects = 0;
37  let SchedRW = [WriteVMEM];
38
39  string Mnemonic = opName;
40  string AsmOperands = asmOps;
41
42  bits<1> has_vdst = 1;
43  bits<1> has_data = 1;
44  bits<1> has_glc  = 1;
45  bits<1> glcValue = 0;
46}
47
48class FLAT_Real <bits<7> op, FLAT_Pseudo ps> :
49  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
50  Enc64 {
51
52  let isPseudo = 0;
53  let isCodeGenOnly = 0;
54
55  // copy relevant pseudo op flags
56  let SubtargetPredicate = ps.SubtargetPredicate;
57  let AsmMatchConverter  = ps.AsmMatchConverter;
58
59  // encoding fields
60  bits<8> vaddr;
61  bits<8> vdata;
62  bits<8> vdst;
63  bits<1> slc;
64  bits<1> glc;
65  bits<1> tfe;
66
67  // 15-0 is reserved.
68  let Inst{16}    = !if(ps.has_glc, glc, ps.glcValue);
69  let Inst{17}    = slc;
70  let Inst{24-18} = op;
71  let Inst{31-26} = 0x37; // Encoding.
72  let Inst{39-32} = vaddr;
73  let Inst{47-40} = !if(ps.has_data, vdata, ?);
74  // 54-48 is reserved.
75  let Inst{55}    = tfe;
76  let Inst{63-56} = !if(ps.has_vdst, vdst, ?);
77}
78
79class FLAT_Load_Pseudo <string opName, RegisterClass regClass> : FLAT_Pseudo<
80  opName,
81  (outs regClass:$vdst),
82  (ins VReg_64:$vaddr, GLC:$glc, slc:$slc, tfe:$tfe),
83  " $vdst, $vaddr$glc$slc$tfe"> {
84  let has_data = 0;
85  let mayLoad = 1;
86}
87
88class FLAT_Store_Pseudo <string opName, RegisterClass vdataClass> : FLAT_Pseudo<
89  opName,
90  (outs),
91  (ins VReg_64:$vaddr, vdataClass:$vdata, GLC:$glc, slc:$slc, tfe:$tfe),
92  " $vaddr, $vdata$glc$slc$tfe"> {
93  let mayLoad  = 0;
94  let mayStore = 1;
95  let has_vdst = 0;
96}
97
98multiclass FLAT_Atomic_Pseudo<
99  string opName,
100  RegisterClass vdst_rc,
101  ValueType vt,
102  SDPatternOperator atomic = null_frag,
103  ValueType data_vt = vt,
104  RegisterClass data_rc = vdst_rc> {
105
106  def "" : FLAT_Pseudo <opName,
107    (outs),
108    (ins VReg_64:$vaddr, data_rc:$vdata, slc:$slc, tfe:$tfe),
109    " $vaddr, $vdata$slc$tfe",
110    []>,
111    AtomicNoRet <NAME, 0> {
112    let mayLoad = 1;
113    let mayStore = 1;
114    let has_glc  = 0;
115    let glcValue = 0;
116    let has_vdst = 0;
117    let PseudoInstr = NAME;
118  }
119
120  def _RTN : FLAT_Pseudo <opName,
121    (outs vdst_rc:$vdst),
122    (ins VReg_64:$vaddr, data_rc:$vdata, slc:$slc, tfe:$tfe),
123    " $vdst, $vaddr, $vdata glc$slc$tfe",
124    [(set vt:$vdst,
125      (atomic (FLATAtomic i64:$vaddr, i1:$slc, i1:$tfe), data_vt:$vdata))]>,
126    AtomicNoRet <NAME, 1> {
127    let mayLoad  = 1;
128    let mayStore = 1;
129    let hasPostISelHook = 1;
130    let has_glc  = 0;
131    let glcValue = 1;
132    let PseudoInstr = NAME # "_RTN";
133  }
134}
135
136class flat_binary_atomic_op<SDNode atomic_op> : PatFrag<
137  (ops node:$ptr, node:$value),
138  (atomic_op node:$ptr, node:$value),
139  [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::FLAT_ADDRESS;}]
140>;
141
142def atomic_cmp_swap_flat : flat_binary_atomic_op<AMDGPUatomic_cmp_swap>;
143def atomic_swap_flat     : flat_binary_atomic_op<atomic_swap>;
144def atomic_add_flat      : flat_binary_atomic_op<atomic_load_add>;
145def atomic_and_flat      : flat_binary_atomic_op<atomic_load_and>;
146def atomic_max_flat      : flat_binary_atomic_op<atomic_load_max>;
147def atomic_min_flat      : flat_binary_atomic_op<atomic_load_min>;
148def atomic_or_flat       : flat_binary_atomic_op<atomic_load_or>;
149def atomic_sub_flat      : flat_binary_atomic_op<atomic_load_sub>;
150def atomic_umax_flat     : flat_binary_atomic_op<atomic_load_umax>;
151def atomic_umin_flat     : flat_binary_atomic_op<atomic_load_umin>;
152def atomic_xor_flat      : flat_binary_atomic_op<atomic_load_xor>;
153def atomic_inc_flat      : flat_binary_atomic_op<SIatomic_inc>;
154def atomic_dec_flat      : flat_binary_atomic_op<SIatomic_dec>;
155
156
157
158//===----------------------------------------------------------------------===//
159// Flat Instructions
160//===----------------------------------------------------------------------===//
161
162def FLAT_LOAD_UBYTE    : FLAT_Load_Pseudo <"flat_load_ubyte", VGPR_32>;
163def FLAT_LOAD_SBYTE    : FLAT_Load_Pseudo <"flat_load_sbyte", VGPR_32>;
164def FLAT_LOAD_USHORT   : FLAT_Load_Pseudo <"flat_load_ushort", VGPR_32>;
165def FLAT_LOAD_SSHORT   : FLAT_Load_Pseudo <"flat_load_sshort", VGPR_32>;
166def FLAT_LOAD_DWORD    : FLAT_Load_Pseudo <"flat_load_dword", VGPR_32>;
167def FLAT_LOAD_DWORDX2  : FLAT_Load_Pseudo <"flat_load_dwordx2", VReg_64>;
168def FLAT_LOAD_DWORDX4  : FLAT_Load_Pseudo <"flat_load_dwordx4", VReg_128>;
169def FLAT_LOAD_DWORDX3  : FLAT_Load_Pseudo <"flat_load_dwordx3", VReg_96>;
170
171def FLAT_STORE_BYTE    : FLAT_Store_Pseudo <"flat_store_byte", VGPR_32>;
172def FLAT_STORE_SHORT   : FLAT_Store_Pseudo <"flat_store_short", VGPR_32>;
173def FLAT_STORE_DWORD   : FLAT_Store_Pseudo <"flat_store_dword", VGPR_32>;
174def FLAT_STORE_DWORDX2 : FLAT_Store_Pseudo <"flat_store_dwordx2", VReg_64>;
175def FLAT_STORE_DWORDX4 : FLAT_Store_Pseudo <"flat_store_dwordx4", VReg_128>;
176def FLAT_STORE_DWORDX3 : FLAT_Store_Pseudo <"flat_store_dwordx3", VReg_96>;
177
178defm FLAT_ATOMIC_CMPSWAP    : FLAT_Atomic_Pseudo <"flat_atomic_cmpswap",
179                                VGPR_32, i32, atomic_cmp_swap_flat,
180                                v2i32, VReg_64>;
181
182defm FLAT_ATOMIC_CMPSWAP_X2 : FLAT_Atomic_Pseudo <"flat_atomic_cmpswap_x2",
183                                VReg_64, i64, atomic_cmp_swap_flat,
184                                v2i64, VReg_128>;
185
186defm FLAT_ATOMIC_SWAP       : FLAT_Atomic_Pseudo <"flat_atomic_swap",
187                                VGPR_32, i32, atomic_swap_flat>;
188
189defm FLAT_ATOMIC_SWAP_X2    : FLAT_Atomic_Pseudo <"flat_atomic_swap_x2",
190                                VReg_64, i64, atomic_swap_flat>;
191
192defm FLAT_ATOMIC_ADD        : FLAT_Atomic_Pseudo <"flat_atomic_add",
193                                VGPR_32, i32, atomic_add_flat>;
194
195defm FLAT_ATOMIC_SUB        : FLAT_Atomic_Pseudo <"flat_atomic_sub",
196                                VGPR_32, i32, atomic_sub_flat>;
197
198defm FLAT_ATOMIC_SMIN       : FLAT_Atomic_Pseudo <"flat_atomic_smin",
199                                VGPR_32, i32, atomic_min_flat>;
200
201defm FLAT_ATOMIC_UMIN       : FLAT_Atomic_Pseudo <"flat_atomic_umin",
202                                VGPR_32, i32, atomic_umin_flat>;
203
204defm FLAT_ATOMIC_SMAX       : FLAT_Atomic_Pseudo <"flat_atomic_smax",
205                                VGPR_32, i32, atomic_max_flat>;
206
207defm FLAT_ATOMIC_UMAX       : FLAT_Atomic_Pseudo <"flat_atomic_umax",
208                                VGPR_32, i32, atomic_umax_flat>;
209
210defm FLAT_ATOMIC_AND        : FLAT_Atomic_Pseudo <"flat_atomic_and",
211                                VGPR_32, i32, atomic_and_flat>;
212
213defm FLAT_ATOMIC_OR         : FLAT_Atomic_Pseudo <"flat_atomic_or",
214                                VGPR_32, i32, atomic_or_flat>;
215
216defm FLAT_ATOMIC_XOR        : FLAT_Atomic_Pseudo <"flat_atomic_xor",
217                                VGPR_32, i32, atomic_xor_flat>;
218
219defm FLAT_ATOMIC_INC        : FLAT_Atomic_Pseudo <"flat_atomic_inc",
220                                VGPR_32, i32, atomic_inc_flat>;
221
222defm FLAT_ATOMIC_DEC        : FLAT_Atomic_Pseudo <"flat_atomic_dec",
223                                VGPR_32, i32, atomic_dec_flat>;
224
225defm FLAT_ATOMIC_ADD_X2     : FLAT_Atomic_Pseudo <"flat_atomic_add_x2",
226                                VReg_64, i64, atomic_add_flat>;
227
228defm FLAT_ATOMIC_SUB_X2     : FLAT_Atomic_Pseudo <"flat_atomic_sub_x2",
229                                VReg_64, i64, atomic_sub_flat>;
230
231defm FLAT_ATOMIC_SMIN_X2    : FLAT_Atomic_Pseudo <"flat_atomic_smin_x2",
232                                VReg_64, i64, atomic_min_flat>;
233
234defm FLAT_ATOMIC_UMIN_X2    : FLAT_Atomic_Pseudo <"flat_atomic_umin_x2",
235                                VReg_64, i64, atomic_umin_flat>;
236
237defm FLAT_ATOMIC_SMAX_X2    : FLAT_Atomic_Pseudo <"flat_atomic_smax_x2",
238                                VReg_64, i64, atomic_max_flat>;
239
240defm FLAT_ATOMIC_UMAX_X2    : FLAT_Atomic_Pseudo <"flat_atomic_umax_x2",
241                                VReg_64, i64, atomic_umax_flat>;
242
243defm FLAT_ATOMIC_AND_X2     : FLAT_Atomic_Pseudo <"flat_atomic_and_x2",
244                                VReg_64, i64, atomic_and_flat>;
245
246defm FLAT_ATOMIC_OR_X2      : FLAT_Atomic_Pseudo <"flat_atomic_or_x2",
247                                VReg_64, i64, atomic_or_flat>;
248
249defm FLAT_ATOMIC_XOR_X2     : FLAT_Atomic_Pseudo <"flat_atomic_xor_x2",
250                                VReg_64, i64, atomic_xor_flat>;
251
252defm FLAT_ATOMIC_INC_X2     : FLAT_Atomic_Pseudo <"flat_atomic_inc_x2",
253                                VReg_64, i64, atomic_inc_flat>;
254
255defm FLAT_ATOMIC_DEC_X2     : FLAT_Atomic_Pseudo <"flat_atomic_dec_x2",
256                                VReg_64, i64, atomic_dec_flat>;
257
258let SubtargetPredicate = isCI in { // CI Only flat instructions : FIXME Only?
259
260defm FLAT_ATOMIC_FCMPSWAP    : FLAT_Atomic_Pseudo <"flat_atomic_fcmpswap",
261                                VGPR_32, f32, null_frag, v2f32, VReg_64>;
262
263defm FLAT_ATOMIC_FCMPSWAP_X2 : FLAT_Atomic_Pseudo <"flat_atomic_fcmpswap_x2",
264                                VReg_64, f64, null_frag, v2f64, VReg_128>;
265
266defm FLAT_ATOMIC_FMIN        : FLAT_Atomic_Pseudo <"flat_atomic_fmin",
267                                VGPR_32, f32>;
268
269defm FLAT_ATOMIC_FMAX        : FLAT_Atomic_Pseudo <"flat_atomic_fmax",
270                                VGPR_32, f32>;
271
272defm FLAT_ATOMIC_FMIN_X2     : FLAT_Atomic_Pseudo <"flat_atomic_fmin_x2",
273                                VReg_64, f64>;
274
275defm FLAT_ATOMIC_FMAX_X2     : FLAT_Atomic_Pseudo <"flat_atomic_fmax_x2",
276                                VReg_64, f64>;
277
278} // End SubtargetPredicate = isCI
279
280//===----------------------------------------------------------------------===//
281// Flat Patterns
282//===----------------------------------------------------------------------===//
283
284class flat_ld <SDPatternOperator ld> : PatFrag<(ops node:$ptr),
285                                               (ld node:$ptr), [{
286  auto const AS = cast<MemSDNode>(N)->getAddressSpace();
287  return AS == AMDGPUAS::FLAT_ADDRESS ||
288         AS == AMDGPUAS::GLOBAL_ADDRESS ||
289         AS == AMDGPUAS::CONSTANT_ADDRESS;
290}]>;
291
292class flat_st <SDPatternOperator st> : PatFrag<(ops node:$val, node:$ptr),
293                                               (st node:$val, node:$ptr), [{
294  auto const AS = cast<MemSDNode>(N)->getAddressSpace();
295  return AS == AMDGPUAS::FLAT_ADDRESS ||
296         AS == AMDGPUAS::GLOBAL_ADDRESS;
297}]>;
298
299def atomic_flat_load   : flat_ld <atomic_load>;
300def flat_load          : flat_ld <load>;
301def flat_az_extloadi8  : flat_ld <az_extloadi8>;
302def flat_sextloadi8    : flat_ld <sextloadi8>;
303def flat_az_extloadi16 : flat_ld <az_extloadi16>;
304def flat_sextloadi16   : flat_ld <sextloadi16>;
305
306def atomic_flat_store  : flat_st <atomic_store>;
307def flat_store         : flat_st <store>;
308def flat_truncstorei8  : flat_st <truncstorei8>;
309def flat_truncstorei16 : flat_st <truncstorei16>;
310
311// Patterns for global loads with no offset.
312class FlatLoadPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : Pat <
313  (vt (node i64:$addr)),
314  (inst $addr, 0, 0, 0)
315>;
316
317class FlatLoadAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : Pat <
318  (vt (node i64:$addr)),
319  (inst $addr, 1, 0, 0)
320>;
321
322class FlatStorePat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : Pat <
323  (node vt:$data, i64:$addr),
324  (inst $addr, $data, 0, 0, 0)
325>;
326
327class FlatStoreAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : Pat <
328  // atomic store follows atomic binop convention so the address comes
329  // first.
330  (node i64:$addr, vt:$data),
331  (inst $addr, $data, 1, 0, 0)
332>;
333
334class FlatAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt,
335                     ValueType data_vt = vt> : Pat <
336  (vt (node i64:$addr, data_vt:$data)),
337  (inst $addr, $data, 0, 0)
338>;
339
340let Predicates = [isCIVI] in {
341
342def : FlatLoadPat <FLAT_LOAD_UBYTE, flat_az_extloadi8, i32>;
343def : FlatLoadPat <FLAT_LOAD_SBYTE, flat_sextloadi8, i32>;
344def : FlatLoadPat <FLAT_LOAD_UBYTE, flat_az_extloadi8, i16>;
345def : FlatLoadPat <FLAT_LOAD_SBYTE, flat_sextloadi8, i16>;
346def : FlatLoadPat <FLAT_LOAD_USHORT, flat_az_extloadi16, i32>;
347def : FlatLoadPat <FLAT_LOAD_SSHORT, flat_sextloadi16, i32>;
348def : FlatLoadPat <FLAT_LOAD_DWORD, flat_load, i32>;
349def : FlatLoadPat <FLAT_LOAD_DWORDX2, flat_load, v2i32>;
350def : FlatLoadPat <FLAT_LOAD_DWORDX4, flat_load, v4i32>;
351
352def : FlatLoadAtomicPat <FLAT_LOAD_DWORD, atomic_flat_load, i32>;
353def : FlatLoadAtomicPat <FLAT_LOAD_DWORDX2, atomic_flat_load, i64>;
354
355def : FlatStorePat <FLAT_STORE_BYTE, flat_truncstorei8, i32>;
356def : FlatStorePat <FLAT_STORE_SHORT, flat_truncstorei16, i32>;
357def : FlatStorePat <FLAT_STORE_DWORD, flat_store, i32>;
358def : FlatStorePat <FLAT_STORE_DWORDX2, flat_store, v2i32>;
359def : FlatStorePat <FLAT_STORE_DWORDX4, flat_store, v4i32>;
360
361def : FlatStoreAtomicPat <FLAT_STORE_DWORD, atomic_flat_store, i32>;
362def : FlatStoreAtomicPat <FLAT_STORE_DWORDX2, atomic_flat_store, i64>;
363
364def : FlatAtomicPat <FLAT_ATOMIC_ADD_RTN, atomic_add_global, i32>;
365def : FlatAtomicPat <FLAT_ATOMIC_SUB_RTN, atomic_sub_global, i32>;
366def : FlatAtomicPat <FLAT_ATOMIC_INC_RTN, atomic_inc_global, i32>;
367def : FlatAtomicPat <FLAT_ATOMIC_DEC_RTN, atomic_dec_global, i32>;
368def : FlatAtomicPat <FLAT_ATOMIC_AND_RTN, atomic_and_global, i32>;
369def : FlatAtomicPat <FLAT_ATOMIC_SMAX_RTN, atomic_max_global, i32>;
370def : FlatAtomicPat <FLAT_ATOMIC_UMAX_RTN, atomic_umax_global, i32>;
371def : FlatAtomicPat <FLAT_ATOMIC_SMIN_RTN, atomic_min_global, i32>;
372def : FlatAtomicPat <FLAT_ATOMIC_UMIN_RTN, atomic_umin_global, i32>;
373def : FlatAtomicPat <FLAT_ATOMIC_OR_RTN, atomic_or_global, i32>;
374def : FlatAtomicPat <FLAT_ATOMIC_SWAP_RTN, atomic_swap_global, i32>;
375def : FlatAtomicPat <FLAT_ATOMIC_CMPSWAP_RTN, AMDGPUatomic_cmp_swap_global, i32, v2i32>;
376def : FlatAtomicPat <FLAT_ATOMIC_XOR_RTN, atomic_xor_global, i32>;
377
378def : FlatAtomicPat <FLAT_ATOMIC_ADD_X2_RTN, atomic_add_global, i64>;
379def : FlatAtomicPat <FLAT_ATOMIC_SUB_X2_RTN, atomic_sub_global, i64>;
380def : FlatAtomicPat <FLAT_ATOMIC_INC_X2_RTN, atomic_inc_global, i64>;
381def : FlatAtomicPat <FLAT_ATOMIC_DEC_X2_RTN, atomic_dec_global, i64>;
382def : FlatAtomicPat <FLAT_ATOMIC_AND_X2_RTN, atomic_and_global, i64>;
383def : FlatAtomicPat <FLAT_ATOMIC_SMAX_X2_RTN, atomic_max_global, i64>;
384def : FlatAtomicPat <FLAT_ATOMIC_UMAX_X2_RTN, atomic_umax_global, i64>;
385def : FlatAtomicPat <FLAT_ATOMIC_SMIN_X2_RTN, atomic_min_global, i64>;
386def : FlatAtomicPat <FLAT_ATOMIC_UMIN_X2_RTN, atomic_umin_global, i64>;
387def : FlatAtomicPat <FLAT_ATOMIC_OR_X2_RTN, atomic_or_global, i64>;
388def : FlatAtomicPat <FLAT_ATOMIC_SWAP_X2_RTN, atomic_swap_global, i64>;
389def : FlatAtomicPat <FLAT_ATOMIC_CMPSWAP_X2_RTN, AMDGPUatomic_cmp_swap_global, i64, v2i64>;
390def : FlatAtomicPat <FLAT_ATOMIC_XOR_X2_RTN, atomic_xor_global, i64>;
391
392} // End Predicates = [isCIVI]
393
394let Predicates = [isVI] in {
395  def : FlatStorePat <FLAT_STORE_BYTE, flat_truncstorei8, i16>;
396  def : FlatStorePat <FLAT_STORE_SHORT, flat_store, i16>;
397}
398
399
400//===----------------------------------------------------------------------===//
401// Target
402//===----------------------------------------------------------------------===//
403
404//===----------------------------------------------------------------------===//
405// CI
406//===----------------------------------------------------------------------===//
407
408class FLAT_Real_ci <bits<7> op, FLAT_Pseudo ps> :
409  FLAT_Real <op, ps>,
410  SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SI> {
411  let AssemblerPredicate = isCIOnly;
412  let DecoderNamespace="CI";
413}
414
415def FLAT_LOAD_UBYTE_ci         : FLAT_Real_ci <0x8,  FLAT_LOAD_UBYTE>;
416def FLAT_LOAD_SBYTE_ci         : FLAT_Real_ci <0x9,  FLAT_LOAD_SBYTE>;
417def FLAT_LOAD_USHORT_ci        : FLAT_Real_ci <0xa,  FLAT_LOAD_USHORT>;
418def FLAT_LOAD_SSHORT_ci        : FLAT_Real_ci <0xb,  FLAT_LOAD_SSHORT>;
419def FLAT_LOAD_DWORD_ci         : FLAT_Real_ci <0xc,  FLAT_LOAD_DWORD>;
420def FLAT_LOAD_DWORDX2_ci       : FLAT_Real_ci <0xd,  FLAT_LOAD_DWORDX2>;
421def FLAT_LOAD_DWORDX4_ci       : FLAT_Real_ci <0xe,  FLAT_LOAD_DWORDX4>;
422def FLAT_LOAD_DWORDX3_ci       : FLAT_Real_ci <0xf,  FLAT_LOAD_DWORDX3>;
423
424def FLAT_STORE_BYTE_ci         : FLAT_Real_ci <0x18, FLAT_STORE_BYTE>;
425def FLAT_STORE_SHORT_ci        : FLAT_Real_ci <0x1a, FLAT_STORE_SHORT>;
426def FLAT_STORE_DWORD_ci        : FLAT_Real_ci <0x1c, FLAT_STORE_DWORD>;
427def FLAT_STORE_DWORDX2_ci      : FLAT_Real_ci <0x1d, FLAT_STORE_DWORDX2>;
428def FLAT_STORE_DWORDX4_ci      : FLAT_Real_ci <0x1e, FLAT_STORE_DWORDX4>;
429def FLAT_STORE_DWORDX3_ci      : FLAT_Real_ci <0x1f, FLAT_STORE_DWORDX3>;
430
431multiclass FLAT_Real_Atomics_ci <bits<7> op, FLAT_Pseudo ps> {
432  def _ci     : FLAT_Real_ci<op, !cast<FLAT_Pseudo>(ps.PseudoInstr)>;
433  def _RTN_ci : FLAT_Real_ci<op, !cast<FLAT_Pseudo>(ps.PseudoInstr # "_RTN")>;
434}
435
436defm FLAT_ATOMIC_SWAP          : FLAT_Real_Atomics_ci <0x30, FLAT_ATOMIC_SWAP>;
437defm FLAT_ATOMIC_CMPSWAP       : FLAT_Real_Atomics_ci <0x31, FLAT_ATOMIC_CMPSWAP>;
438defm FLAT_ATOMIC_ADD           : FLAT_Real_Atomics_ci <0x32, FLAT_ATOMIC_ADD>;
439defm FLAT_ATOMIC_SUB           : FLAT_Real_Atomics_ci <0x33, FLAT_ATOMIC_SUB>;
440defm FLAT_ATOMIC_SMIN          : FLAT_Real_Atomics_ci <0x35, FLAT_ATOMIC_SMIN>;
441defm FLAT_ATOMIC_UMIN          : FLAT_Real_Atomics_ci <0x36, FLAT_ATOMIC_UMIN>;
442defm FLAT_ATOMIC_SMAX          : FLAT_Real_Atomics_ci <0x37, FLAT_ATOMIC_SMAX>;
443defm FLAT_ATOMIC_UMAX          : FLAT_Real_Atomics_ci <0x38, FLAT_ATOMIC_UMAX>;
444defm FLAT_ATOMIC_AND           : FLAT_Real_Atomics_ci <0x39, FLAT_ATOMIC_AND>;
445defm FLAT_ATOMIC_OR            : FLAT_Real_Atomics_ci <0x3a, FLAT_ATOMIC_OR>;
446defm FLAT_ATOMIC_XOR           : FLAT_Real_Atomics_ci <0x3b, FLAT_ATOMIC_XOR>;
447defm FLAT_ATOMIC_INC           : FLAT_Real_Atomics_ci <0x3c, FLAT_ATOMIC_INC>;
448defm FLAT_ATOMIC_DEC           : FLAT_Real_Atomics_ci <0x3d, FLAT_ATOMIC_DEC>;
449defm FLAT_ATOMIC_SWAP_X2       : FLAT_Real_Atomics_ci <0x50, FLAT_ATOMIC_SWAP_X2>;
450defm FLAT_ATOMIC_CMPSWAP_X2    : FLAT_Real_Atomics_ci <0x51, FLAT_ATOMIC_CMPSWAP_X2>;
451defm FLAT_ATOMIC_ADD_X2        : FLAT_Real_Atomics_ci <0x52, FLAT_ATOMIC_ADD_X2>;
452defm FLAT_ATOMIC_SUB_X2        : FLAT_Real_Atomics_ci <0x53, FLAT_ATOMIC_SUB_X2>;
453defm FLAT_ATOMIC_SMIN_X2       : FLAT_Real_Atomics_ci <0x55, FLAT_ATOMIC_SMIN_X2>;
454defm FLAT_ATOMIC_UMIN_X2       : FLAT_Real_Atomics_ci <0x56, FLAT_ATOMIC_UMIN_X2>;
455defm FLAT_ATOMIC_SMAX_X2       : FLAT_Real_Atomics_ci <0x57, FLAT_ATOMIC_SMAX_X2>;
456defm FLAT_ATOMIC_UMAX_X2       : FLAT_Real_Atomics_ci <0x58, FLAT_ATOMIC_UMAX_X2>;
457defm FLAT_ATOMIC_AND_X2        : FLAT_Real_Atomics_ci <0x59, FLAT_ATOMIC_AND_X2>;
458defm FLAT_ATOMIC_OR_X2         : FLAT_Real_Atomics_ci <0x5a, FLAT_ATOMIC_OR_X2>;
459defm FLAT_ATOMIC_XOR_X2        : FLAT_Real_Atomics_ci <0x5b, FLAT_ATOMIC_XOR_X2>;
460defm FLAT_ATOMIC_INC_X2        : FLAT_Real_Atomics_ci <0x5c, FLAT_ATOMIC_INC_X2>;
461defm FLAT_ATOMIC_DEC_X2        : FLAT_Real_Atomics_ci <0x5d, FLAT_ATOMIC_DEC_X2>;
462
463// CI Only flat instructions
464defm FLAT_ATOMIC_FCMPSWAP      : FLAT_Real_Atomics_ci <0x3e, FLAT_ATOMIC_FCMPSWAP>;
465defm FLAT_ATOMIC_FMIN          : FLAT_Real_Atomics_ci <0x3f, FLAT_ATOMIC_FMIN>;
466defm FLAT_ATOMIC_FMAX          : FLAT_Real_Atomics_ci <0x40, FLAT_ATOMIC_FMAX>;
467defm FLAT_ATOMIC_FCMPSWAP_X2   : FLAT_Real_Atomics_ci <0x5e, FLAT_ATOMIC_FCMPSWAP_X2>;
468defm FLAT_ATOMIC_FMIN_X2       : FLAT_Real_Atomics_ci <0x5f, FLAT_ATOMIC_FMIN_X2>;
469defm FLAT_ATOMIC_FMAX_X2       : FLAT_Real_Atomics_ci <0x60, FLAT_ATOMIC_FMAX_X2>;
470
471
472//===----------------------------------------------------------------------===//
473// VI
474//===----------------------------------------------------------------------===//
475
476class FLAT_Real_vi <bits<7> op, FLAT_Pseudo ps> :
477  FLAT_Real <op, ps>,
478  SIMCInstr <ps.PseudoInstr, SIEncodingFamily.VI> {
479  let AssemblerPredicate = isVI;
480  let DecoderNamespace="VI";
481}
482
483def FLAT_LOAD_UBYTE_vi         : FLAT_Real_vi <0x10, FLAT_LOAD_UBYTE>;
484def FLAT_LOAD_SBYTE_vi         : FLAT_Real_vi <0x11, FLAT_LOAD_SBYTE>;
485def FLAT_LOAD_USHORT_vi        : FLAT_Real_vi <0x12, FLAT_LOAD_USHORT>;
486def FLAT_LOAD_SSHORT_vi        : FLAT_Real_vi <0x13, FLAT_LOAD_SSHORT>;
487def FLAT_LOAD_DWORD_vi         : FLAT_Real_vi <0x14, FLAT_LOAD_DWORD>;
488def FLAT_LOAD_DWORDX2_vi       : FLAT_Real_vi <0x15, FLAT_LOAD_DWORDX2>;
489def FLAT_LOAD_DWORDX4_vi       : FLAT_Real_vi <0x17, FLAT_LOAD_DWORDX4>;
490def FLAT_LOAD_DWORDX3_vi       : FLAT_Real_vi <0x16, FLAT_LOAD_DWORDX3>;
491
492def FLAT_STORE_BYTE_vi         : FLAT_Real_vi <0x18, FLAT_STORE_BYTE>;
493def FLAT_STORE_SHORT_vi        : FLAT_Real_vi <0x1a, FLAT_STORE_SHORT>;
494def FLAT_STORE_DWORD_vi        : FLAT_Real_vi <0x1c, FLAT_STORE_DWORD>;
495def FLAT_STORE_DWORDX2_vi      : FLAT_Real_vi <0x1d, FLAT_STORE_DWORDX2>;
496def FLAT_STORE_DWORDX4_vi      : FLAT_Real_vi <0x1f, FLAT_STORE_DWORDX4>;
497def FLAT_STORE_DWORDX3_vi      : FLAT_Real_vi <0x1e, FLAT_STORE_DWORDX3>;
498
499multiclass FLAT_Real_Atomics_vi <bits<7> op, FLAT_Pseudo ps> {
500  def _vi     : FLAT_Real_vi<op, !cast<FLAT_Pseudo>(ps.PseudoInstr)>;
501  def _RTN_vi : FLAT_Real_vi<op, !cast<FLAT_Pseudo>(ps.PseudoInstr # "_RTN")>;
502}
503
504defm FLAT_ATOMIC_SWAP       : FLAT_Real_Atomics_vi <0x40, FLAT_ATOMIC_SWAP>;
505defm FLAT_ATOMIC_CMPSWAP    : FLAT_Real_Atomics_vi <0x41, FLAT_ATOMIC_CMPSWAP>;
506defm FLAT_ATOMIC_ADD        : FLAT_Real_Atomics_vi <0x42, FLAT_ATOMIC_ADD>;
507defm FLAT_ATOMIC_SUB        : FLAT_Real_Atomics_vi <0x43, FLAT_ATOMIC_SUB>;
508defm FLAT_ATOMIC_SMIN       : FLAT_Real_Atomics_vi <0x44, FLAT_ATOMIC_SMIN>;
509defm FLAT_ATOMIC_UMIN       : FLAT_Real_Atomics_vi <0x45, FLAT_ATOMIC_UMIN>;
510defm FLAT_ATOMIC_SMAX       : FLAT_Real_Atomics_vi <0x46, FLAT_ATOMIC_SMAX>;
511defm FLAT_ATOMIC_UMAX       : FLAT_Real_Atomics_vi <0x47, FLAT_ATOMIC_UMAX>;
512defm FLAT_ATOMIC_AND        : FLAT_Real_Atomics_vi <0x48, FLAT_ATOMIC_AND>;
513defm FLAT_ATOMIC_OR         : FLAT_Real_Atomics_vi <0x49, FLAT_ATOMIC_OR>;
514defm FLAT_ATOMIC_XOR        : FLAT_Real_Atomics_vi <0x4a, FLAT_ATOMIC_XOR>;
515defm FLAT_ATOMIC_INC        : FLAT_Real_Atomics_vi <0x4b, FLAT_ATOMIC_INC>;
516defm FLAT_ATOMIC_DEC        : FLAT_Real_Atomics_vi <0x4c, FLAT_ATOMIC_DEC>;
517defm FLAT_ATOMIC_SWAP_X2    : FLAT_Real_Atomics_vi <0x60, FLAT_ATOMIC_SWAP_X2>;
518defm FLAT_ATOMIC_CMPSWAP_X2 : FLAT_Real_Atomics_vi <0x61, FLAT_ATOMIC_CMPSWAP_X2>;
519defm FLAT_ATOMIC_ADD_X2     : FLAT_Real_Atomics_vi <0x62, FLAT_ATOMIC_ADD_X2>;
520defm FLAT_ATOMIC_SUB_X2     : FLAT_Real_Atomics_vi <0x63, FLAT_ATOMIC_SUB_X2>;
521defm FLAT_ATOMIC_SMIN_X2    : FLAT_Real_Atomics_vi <0x64, FLAT_ATOMIC_SMIN_X2>;
522defm FLAT_ATOMIC_UMIN_X2    : FLAT_Real_Atomics_vi <0x65, FLAT_ATOMIC_UMIN_X2>;
523defm FLAT_ATOMIC_SMAX_X2    : FLAT_Real_Atomics_vi <0x66, FLAT_ATOMIC_SMAX_X2>;
524defm FLAT_ATOMIC_UMAX_X2    : FLAT_Real_Atomics_vi <0x67, FLAT_ATOMIC_UMAX_X2>;
525defm FLAT_ATOMIC_AND_X2     : FLAT_Real_Atomics_vi <0x68, FLAT_ATOMIC_AND_X2>;
526defm FLAT_ATOMIC_OR_X2      : FLAT_Real_Atomics_vi <0x69, FLAT_ATOMIC_OR_X2>;
527defm FLAT_ATOMIC_XOR_X2     : FLAT_Real_Atomics_vi <0x6a, FLAT_ATOMIC_XOR_X2>;
528defm FLAT_ATOMIC_INC_X2     : FLAT_Real_Atomics_vi <0x6b, FLAT_ATOMIC_INC_X2>;
529defm FLAT_ATOMIC_DEC_X2     : FLAT_Real_Atomics_vi <0x6c, FLAT_ATOMIC_DEC_X2>;
530
531