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