blob: 9b9d5588ed5c3c4b404740db5005de03ff3b8412 [file] [log] [blame]
Valery Pykhtin1b138862016-09-01 09:56:47 +00001//===---- SMInstructions.td - Scalar Memory 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 smrd_offset : NamedOperandU32<"SMRDOffset",
11 NamedMatchClass<"SMRDOffset">> {
12 let OperandType = "OPERAND_IMMEDIATE";
13}
14
15
16//===----------------------------------------------------------------------===//
17// Scalar Memory classes
18//===----------------------------------------------------------------------===//
19
20class SM_Pseudo <string opName, dag outs, dag ins, string asmOps, list<dag> pattern=[]> :
21 InstSI <outs, ins, "", pattern>,
22 SIMCInstr<opName, SIEncodingFamily.NONE> {
23 let isPseudo = 1;
24 let isCodeGenOnly = 1;
25
26 let LGKM_CNT = 1;
27 let SMRD = 1;
28 let mayStore = 0;
29 let mayLoad = 1;
30 let hasSideEffects = 0;
31 let UseNamedOperandTable = 1;
32 let SchedRW = [WriteSMEM];
33 let SubtargetPredicate = isGCN;
34
35 string Mnemonic = opName;
36 string AsmOperands = asmOps;
37
38 bits<1> has_sbase = 1;
39 bits<1> has_sdst = 1;
Matt Arsenault7b647552016-10-28 21:55:15 +000040 bit has_glc = 0;
Valery Pykhtin1b138862016-09-01 09:56:47 +000041 bits<1> has_offset = 1;
42 bits<1> offset_is_imm = 0;
43}
44
45class SM_Real <SM_Pseudo ps>
46 : InstSI<ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []> {
47
48 let isPseudo = 0;
49 let isCodeGenOnly = 0;
50
51 // copy relevant pseudo op flags
52 let SubtargetPredicate = ps.SubtargetPredicate;
53 let AsmMatchConverter = ps.AsmMatchConverter;
54
55 // encoding
56 bits<7> sbase;
57 bits<7> sdst;
58 bits<32> offset;
Matt Arsenault7b647552016-10-28 21:55:15 +000059 bits<1> imm = !if(ps.has_offset, ps.offset_is_imm, 0);
Valery Pykhtin1b138862016-09-01 09:56:47 +000060}
61
62class SM_Load_Pseudo <string opName, dag outs, dag ins, string asmOps, list<dag> pattern=[]>
63 : SM_Pseudo<opName, outs, ins, asmOps, pattern> {
64 RegisterClass BaseClass;
Matt Arsenault7b647552016-10-28 21:55:15 +000065 let mayLoad = 1;
66 let mayStore = 0;
67 let has_glc = 1;
68}
69
70class SM_Store_Pseudo <string opName, dag ins, string asmOps, list<dag> pattern = []>
71 : SM_Pseudo<opName, (outs), ins, asmOps, pattern> {
72 RegisterClass BaseClass;
73 RegisterClass SrcClass;
74 let mayLoad = 0;
75 let mayStore = 1;
76 let has_glc = 1;
77 let ScalarStore = 1;
Valery Pykhtin1b138862016-09-01 09:56:47 +000078}
79
80multiclass SM_Pseudo_Loads<string opName,
81 RegisterClass baseClass,
82 RegisterClass dstClass> {
83 def _IMM : SM_Load_Pseudo <opName,
84 (outs dstClass:$sdst),
Matt Arsenault7b647552016-10-28 21:55:15 +000085 (ins baseClass:$sbase, i32imm:$offset, i1imm:$glc),
86 " $sdst, $sbase, $offset$glc", []> {
Valery Pykhtin1b138862016-09-01 09:56:47 +000087 let offset_is_imm = 1;
88 let BaseClass = baseClass;
89 let PseudoInstr = opName # "_IMM";
Matt Arsenault7b647552016-10-28 21:55:15 +000090 let has_glc = 1;
Valery Pykhtin1b138862016-09-01 09:56:47 +000091 }
Matt Arsenault7b647552016-10-28 21:55:15 +000092
Valery Pykhtin1b138862016-09-01 09:56:47 +000093 def _SGPR : SM_Load_Pseudo <opName,
94 (outs dstClass:$sdst),
Matt Arsenault7b647552016-10-28 21:55:15 +000095 (ins baseClass:$sbase, SReg_32:$soff, i1imm:$glc),
96 " $sdst, $sbase, $offset$glc", []> {
Valery Pykhtin1b138862016-09-01 09:56:47 +000097 let BaseClass = baseClass;
98 let PseudoInstr = opName # "_SGPR";
Matt Arsenault7b647552016-10-28 21:55:15 +000099 let has_glc = 1;
100 }
101}
102
103multiclass SM_Pseudo_Stores<string opName,
104 RegisterClass baseClass,
105 RegisterClass srcClass> {
106 def _IMM : SM_Store_Pseudo <opName,
107 (ins srcClass:$sdata, baseClass:$sbase, i32imm:$offset, i1imm:$glc),
108 " $sdata, $sbase, $offset$glc", []> {
109 let offset_is_imm = 1;
110 let BaseClass = baseClass;
111 let SrcClass = srcClass;
112 let PseudoInstr = opName # "_IMM";
113 }
114
115 def _SGPR : SM_Store_Pseudo <opName,
116 (ins srcClass:$sdata, baseClass:$sbase, SReg_32:$soff, i1imm:$glc),
117 " $sdata, $sbase, $offset$glc", []> {
118 let BaseClass = baseClass;
119 let SrcClass = srcClass;
120 let PseudoInstr = opName # "_SGPR";
Valery Pykhtin1b138862016-09-01 09:56:47 +0000121 }
122}
123
124class SM_Time_Pseudo<string opName, SDPatternOperator node> : SM_Pseudo<
125 opName, (outs SReg_64:$sdst), (ins),
126 " $sdst", [(set i64:$sdst, (node))]> {
127 let hasSideEffects = 1;
128 // FIXME: mayStore = ? is a workaround for tablegen bug for different
129 // inferred mayStore flags for the instruction pattern vs. standalone
130 // Pat. Each considers the other contradictory.
131 let mayStore = ?;
132 let mayLoad = ?;
133 let has_sbase = 0;
134 let has_offset = 0;
135}
136
137class SM_Inval_Pseudo <string opName, SDPatternOperator node> : SM_Pseudo<
138 opName, (outs), (ins), "", [(node)]> {
139 let hasSideEffects = 1;
140 let mayStore = 1;
141 let has_sdst = 0;
142 let has_sbase = 0;
143 let has_offset = 0;
144}
145
146
147//===----------------------------------------------------------------------===//
148// Scalar Memory Instructions
149//===----------------------------------------------------------------------===//
150
151// We are using the SReg_32_XM0 and not the SReg_32 register class for 32-bit
152// SMRD instructions, because the SReg_32_XM0 register class does not include M0
153// and writing to M0 from an SMRD instruction will hang the GPU.
154defm S_LOAD_DWORD : SM_Pseudo_Loads <"s_load_dword", SReg_64, SReg_32_XM0>;
155defm S_LOAD_DWORDX2 : SM_Pseudo_Loads <"s_load_dwordx2", SReg_64, SReg_64>;
156defm S_LOAD_DWORDX4 : SM_Pseudo_Loads <"s_load_dwordx4", SReg_64, SReg_128>;
157defm S_LOAD_DWORDX8 : SM_Pseudo_Loads <"s_load_dwordx8", SReg_64, SReg_256>;
158defm S_LOAD_DWORDX16 : SM_Pseudo_Loads <"s_load_dwordx16", SReg_64, SReg_512>;
159
160defm S_BUFFER_LOAD_DWORD : SM_Pseudo_Loads <
161 "s_buffer_load_dword", SReg_128, SReg_32_XM0
162>;
163
164defm S_BUFFER_LOAD_DWORDX2 : SM_Pseudo_Loads <
165 "s_buffer_load_dwordx2", SReg_128, SReg_64
166>;
167
168defm S_BUFFER_LOAD_DWORDX4 : SM_Pseudo_Loads <
169 "s_buffer_load_dwordx4", SReg_128, SReg_128
170>;
171
172defm S_BUFFER_LOAD_DWORDX8 : SM_Pseudo_Loads <
173 "s_buffer_load_dwordx8", SReg_128, SReg_256
174>;
175
176defm S_BUFFER_LOAD_DWORDX16 : SM_Pseudo_Loads <
177 "s_buffer_load_dwordx16", SReg_128, SReg_512
178>;
179
Matt Arsenault7b647552016-10-28 21:55:15 +0000180defm S_STORE_DWORD : SM_Pseudo_Stores <"s_store_dword", SReg_64, SReg_32_XM0>;
181defm S_STORE_DWORDX2 : SM_Pseudo_Stores <"s_store_dwordx2", SReg_64, SReg_64>;
182defm S_STORE_DWORDX4 : SM_Pseudo_Stores <"s_store_dwordx4", SReg_64, SReg_128>;
183
184defm S_BUFFER_STORE_DWORD : SM_Pseudo_Stores <
185 "s_buffer_store_dword", SReg_128, SReg_32_XM0
186>;
187
188defm S_BUFFER_STORE_DWORDX2 : SM_Pseudo_Stores <
189 "s_buffer_store_dwordx2", SReg_128, SReg_64
190>;
191
192defm S_BUFFER_STORE_DWORDX4 : SM_Pseudo_Stores <
193 "s_buffer_store_dwordx4", SReg_128, SReg_128
194>;
195
196
Valery Pykhtin1b138862016-09-01 09:56:47 +0000197def S_MEMTIME : SM_Time_Pseudo <"s_memtime", int_amdgcn_s_memtime>;
198def S_DCACHE_INV : SM_Inval_Pseudo <"s_dcache_inv", int_amdgcn_s_dcache_inv>;
199
200let SubtargetPredicate = isCIVI in {
201def S_DCACHE_INV_VOL : SM_Inval_Pseudo <"s_dcache_inv_vol", int_amdgcn_s_dcache_inv_vol>;
202} // let SubtargetPredicate = isCIVI
203
204let SubtargetPredicate = isVI in {
205def S_DCACHE_WB : SM_Inval_Pseudo <"s_dcache_wb", int_amdgcn_s_dcache_wb>;
206def S_DCACHE_WB_VOL : SM_Inval_Pseudo <"s_dcache_wb_vol", int_amdgcn_s_dcache_wb_vol>;
207def S_MEMREALTIME : SM_Time_Pseudo <"s_memrealtime", int_amdgcn_s_memrealtime>;
208} // SubtargetPredicate = isVI
209
210
211
212//===----------------------------------------------------------------------===//
213// Scalar Memory Patterns
214//===----------------------------------------------------------------------===//
215
216def smrd_load : PatFrag <(ops node:$ptr), (load node:$ptr), [{
217 auto Ld = cast<LoadSDNode>(N);
218 return Ld->getAlignment() >= 4 &&
219 Ld->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS &&
220 static_cast<const SITargetLowering *>(getTargetLowering())->isMemOpUniform(N);
221}]>;
222
223def SMRDImm : ComplexPattern<i64, 2, "SelectSMRDImm">;
224def SMRDImm32 : ComplexPattern<i64, 2, "SelectSMRDImm32">;
225def SMRDSgpr : ComplexPattern<i64, 2, "SelectSMRDSgpr">;
226def SMRDBufferImm : ComplexPattern<i32, 1, "SelectSMRDBufferImm">;
227def SMRDBufferImm32 : ComplexPattern<i32, 1, "SelectSMRDBufferImm32">;
228def SMRDBufferSgpr : ComplexPattern<i32, 1, "SelectSMRDBufferSgpr">;
229
230let Predicates = [isGCN] in {
231
232multiclass SMRD_Pattern <string Instr, ValueType vt> {
233
234 // 1. IMM offset
235 def : Pat <
236 (smrd_load (SMRDImm i64:$sbase, i32:$offset)),
Matt Arsenault7b647552016-10-28 21:55:15 +0000237 (vt (!cast<SM_Pseudo>(Instr#"_IMM") $sbase, $offset, 0))
Valery Pykhtin1b138862016-09-01 09:56:47 +0000238 >;
239
240 // 2. SGPR offset
241 def : Pat <
242 (smrd_load (SMRDSgpr i64:$sbase, i32:$offset)),
Matt Arsenault7b647552016-10-28 21:55:15 +0000243 (vt (!cast<SM_Pseudo>(Instr#"_SGPR") $sbase, $offset, 0))
Valery Pykhtin1b138862016-09-01 09:56:47 +0000244 >;
245}
246
247let Predicates = [isSICI] in {
248def : Pat <
249 (i64 (readcyclecounter)),
250 (S_MEMTIME)
251>;
252}
253
254// Global and constant loads can be selected to either MUBUF or SMRD
255// instructions, but SMRD instructions are faster so we want the instruction
256// selector to prefer those.
257let AddedComplexity = 100 in {
258
259defm : SMRD_Pattern <"S_LOAD_DWORD", i32>;
260defm : SMRD_Pattern <"S_LOAD_DWORDX2", v2i32>;
261defm : SMRD_Pattern <"S_LOAD_DWORDX4", v4i32>;
262defm : SMRD_Pattern <"S_LOAD_DWORDX8", v8i32>;
263defm : SMRD_Pattern <"S_LOAD_DWORDX16", v16i32>;
264
265// 1. Offset as an immediate
266def SM_LOAD_PATTERN : Pat < // name this pattern to reuse AddedComplexity on CI
267 (SIload_constant v4i32:$sbase, (SMRDBufferImm i32:$offset)),
Matt Arsenault7b647552016-10-28 21:55:15 +0000268 (S_BUFFER_LOAD_DWORD_IMM $sbase, $offset, 0)
Valery Pykhtin1b138862016-09-01 09:56:47 +0000269>;
270
271// 2. Offset loaded in an 32bit SGPR
272def : Pat <
273 (SIload_constant v4i32:$sbase, (SMRDBufferSgpr i32:$offset)),
Matt Arsenault7b647552016-10-28 21:55:15 +0000274 (S_BUFFER_LOAD_DWORD_SGPR $sbase, $offset, 0)
Valery Pykhtin1b138862016-09-01 09:56:47 +0000275>;
276
277} // End let AddedComplexity = 100
278
279} // let Predicates = [isGCN]
280
281let Predicates = [isVI] in {
282
283// 1. Offset as 20bit DWORD immediate
284def : Pat <
285 (SIload_constant v4i32:$sbase, IMM20bit:$offset),
Matt Arsenault7b647552016-10-28 21:55:15 +0000286 (S_BUFFER_LOAD_DWORD_IMM $sbase, (as_i32imm $offset), 0)
Valery Pykhtin1b138862016-09-01 09:56:47 +0000287>;
288
289def : Pat <
290 (i64 (readcyclecounter)),
291 (S_MEMREALTIME)
292>;
293
294} // let Predicates = [isVI]
295
296
297//===----------------------------------------------------------------------===//
298// Targets
299//===----------------------------------------------------------------------===//
300
301//===----------------------------------------------------------------------===//
302// SI
303//===----------------------------------------------------------------------===//
304
305class SMRD_Real_si <bits<5> op, SM_Pseudo ps>
306 : SM_Real<ps>
307 , SIMCInstr<ps.PseudoInstr, SIEncodingFamily.SI>
308 , Enc32 {
309
310 let AssemblerPredicates = [isSICI];
311 let DecoderNamespace = "SICI";
312
313 let Inst{7-0} = !if(ps.has_offset, offset{7-0}, ?);
314 let Inst{8} = imm;
315 let Inst{14-9} = !if(ps.has_sbase, sbase{6-1}, ?);
316 let Inst{21-15} = !if(ps.has_sdst, sdst{6-0}, ?);
317 let Inst{26-22} = op;
318 let Inst{31-27} = 0x18; //encoding
319}
320
Matt Arsenault7b647552016-10-28 21:55:15 +0000321// FIXME: Assembler should reject trying to use glc on SMRD
322// instructions on SI.
Valery Pykhtin1b138862016-09-01 09:56:47 +0000323multiclass SM_Real_Loads_si<bits<5> op, string ps,
324 SM_Load_Pseudo immPs = !cast<SM_Load_Pseudo>(ps#_IMM),
325 SM_Load_Pseudo sgprPs = !cast<SM_Load_Pseudo>(ps#_SGPR)> {
Matt Arsenault7b647552016-10-28 21:55:15 +0000326
Valery Pykhtin1b138862016-09-01 09:56:47 +0000327 def _IMM_si : SMRD_Real_si <op, immPs> {
Matt Arsenault7b647552016-10-28 21:55:15 +0000328 let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
Valery Pykhtin1b138862016-09-01 09:56:47 +0000329 }
Matt Arsenault7b647552016-10-28 21:55:15 +0000330
331 // FIXME: The operand name $offset is inconsistent with $soff used
332 // in the pseudo
Valery Pykhtin1b138862016-09-01 09:56:47 +0000333 def _SGPR_si : SMRD_Real_si <op, sgprPs> {
Matt Arsenault7b647552016-10-28 21:55:15 +0000334 let InOperandList = (ins sgprPs.BaseClass:$sbase, SReg_32:$offset, GLC:$glc);
Valery Pykhtin1b138862016-09-01 09:56:47 +0000335 }
Matt Arsenault7b647552016-10-28 21:55:15 +0000336
Valery Pykhtin1b138862016-09-01 09:56:47 +0000337}
338
339defm S_LOAD_DWORD : SM_Real_Loads_si <0x00, "S_LOAD_DWORD">;
340defm S_LOAD_DWORDX2 : SM_Real_Loads_si <0x01, "S_LOAD_DWORDX2">;
341defm S_LOAD_DWORDX4 : SM_Real_Loads_si <0x02, "S_LOAD_DWORDX4">;
342defm S_LOAD_DWORDX8 : SM_Real_Loads_si <0x03, "S_LOAD_DWORDX8">;
343defm S_LOAD_DWORDX16 : SM_Real_Loads_si <0x04, "S_LOAD_DWORDX16">;
344defm S_BUFFER_LOAD_DWORD : SM_Real_Loads_si <0x08, "S_BUFFER_LOAD_DWORD">;
345defm S_BUFFER_LOAD_DWORDX2 : SM_Real_Loads_si <0x09, "S_BUFFER_LOAD_DWORDX2">;
346defm S_BUFFER_LOAD_DWORDX4 : SM_Real_Loads_si <0x0a, "S_BUFFER_LOAD_DWORDX4">;
347defm S_BUFFER_LOAD_DWORDX8 : SM_Real_Loads_si <0x0b, "S_BUFFER_LOAD_DWORDX8">;
348defm S_BUFFER_LOAD_DWORDX16 : SM_Real_Loads_si <0x0c, "S_BUFFER_LOAD_DWORDX16">;
349
350def S_MEMTIME_si : SMRD_Real_si <0x1e, S_MEMTIME>;
351def S_DCACHE_INV_si : SMRD_Real_si <0x1f, S_DCACHE_INV>;
352
353
354//===----------------------------------------------------------------------===//
355// VI
356//===----------------------------------------------------------------------===//
357
358class SMEM_Real_vi <bits<8> op, SM_Pseudo ps>
359 : SM_Real<ps>
360 , SIMCInstr<ps.PseudoInstr, SIEncodingFamily.VI>
361 , Enc64 {
Matt Arsenault7b647552016-10-28 21:55:15 +0000362 bit glc;
Valery Pykhtin1b138862016-09-01 09:56:47 +0000363
364 let AssemblerPredicates = [isVI];
365 let DecoderNamespace = "VI";
366
367 let Inst{5-0} = !if(ps.has_sbase, sbase{6-1}, ?);
368 let Inst{12-6} = !if(ps.has_sdst, sdst{6-0}, ?);
369
Matt Arsenault7b647552016-10-28 21:55:15 +0000370 let Inst{16} = !if(ps.has_glc, glc, ?);
371 let Inst{17} = imm;
Valery Pykhtin1b138862016-09-01 09:56:47 +0000372 let Inst{25-18} = op;
373 let Inst{31-26} = 0x30; //encoding
374 let Inst{51-32} = !if(ps.has_offset, offset{19-0}, ?);
375}
376
377multiclass SM_Real_Loads_vi<bits<8> op, string ps,
378 SM_Load_Pseudo immPs = !cast<SM_Load_Pseudo>(ps#_IMM),
379 SM_Load_Pseudo sgprPs = !cast<SM_Load_Pseudo>(ps#_SGPR)> {
380 def _IMM_vi : SMEM_Real_vi <op, immPs> {
Matt Arsenault7b647552016-10-28 21:55:15 +0000381 let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
Valery Pykhtin1b138862016-09-01 09:56:47 +0000382 }
383 def _SGPR_vi : SMEM_Real_vi <op, sgprPs> {
Matt Arsenault7b647552016-10-28 21:55:15 +0000384 let InOperandList = (ins sgprPs.BaseClass:$sbase, SReg_32:$offset, GLC:$glc);
385 }
386}
387
388multiclass SM_Real_Stores_vi<bits<8> op, string ps,
389 SM_Store_Pseudo immPs = !cast<SM_Store_Pseudo>(ps#_IMM),
390 SM_Store_Pseudo sgprPs = !cast<SM_Store_Pseudo>(ps#_SGPR)> {
391 // FIXME: The operand name $offset is inconsistent with $soff used
392 // in the pseudo
393 def _IMM_vi : SMEM_Real_vi <op, immPs> {
394 let InOperandList = (ins immPs.SrcClass:$sdata, immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
395 }
396
397 def _SGPR_vi : SMEM_Real_vi <op, sgprPs> {
398 let InOperandList = (ins sgprPs.SrcClass:$sdata, sgprPs.BaseClass:$sbase, SReg_32:$offset, GLC:$glc);
Valery Pykhtin1b138862016-09-01 09:56:47 +0000399 }
400}
401
402defm S_LOAD_DWORD : SM_Real_Loads_vi <0x00, "S_LOAD_DWORD">;
403defm S_LOAD_DWORDX2 : SM_Real_Loads_vi <0x01, "S_LOAD_DWORDX2">;
404defm S_LOAD_DWORDX4 : SM_Real_Loads_vi <0x02, "S_LOAD_DWORDX4">;
405defm S_LOAD_DWORDX8 : SM_Real_Loads_vi <0x03, "S_LOAD_DWORDX8">;
406defm S_LOAD_DWORDX16 : SM_Real_Loads_vi <0x04, "S_LOAD_DWORDX16">;
407defm S_BUFFER_LOAD_DWORD : SM_Real_Loads_vi <0x08, "S_BUFFER_LOAD_DWORD">;
408defm S_BUFFER_LOAD_DWORDX2 : SM_Real_Loads_vi <0x09, "S_BUFFER_LOAD_DWORDX2">;
409defm S_BUFFER_LOAD_DWORDX4 : SM_Real_Loads_vi <0x0a, "S_BUFFER_LOAD_DWORDX4">;
410defm S_BUFFER_LOAD_DWORDX8 : SM_Real_Loads_vi <0x0b, "S_BUFFER_LOAD_DWORDX8">;
411defm S_BUFFER_LOAD_DWORDX16 : SM_Real_Loads_vi <0x0c, "S_BUFFER_LOAD_DWORDX16">;
412
Matt Arsenault7b647552016-10-28 21:55:15 +0000413defm S_STORE_DWORD : SM_Real_Stores_vi <0x10, "S_STORE_DWORD">;
414defm S_STORE_DWORDX2 : SM_Real_Stores_vi <0x11, "S_STORE_DWORDX2">;
415defm S_STORE_DWORDX4 : SM_Real_Stores_vi <0x12, "S_STORE_DWORDX4">;
416
417defm S_BUFFER_STORE_DWORD : SM_Real_Stores_vi <0x18, "S_BUFFER_STORE_DWORD">;
418defm S_BUFFER_STORE_DWORDX2 : SM_Real_Stores_vi <0x19, "S_BUFFER_STORE_DWORDX2">;
419defm S_BUFFER_STORE_DWORDX4 : SM_Real_Stores_vi <0x1a, "S_BUFFER_STORE_DWORDX4">;
420
Valery Pykhtin1b138862016-09-01 09:56:47 +0000421def S_DCACHE_INV_vi : SMEM_Real_vi <0x20, S_DCACHE_INV>;
422def S_DCACHE_WB_vi : SMEM_Real_vi <0x21, S_DCACHE_WB>;
423def S_DCACHE_INV_VOL_vi : SMEM_Real_vi <0x22, S_DCACHE_INV_VOL>;
424def S_DCACHE_WB_VOL_vi : SMEM_Real_vi <0x23, S_DCACHE_WB_VOL>;
425def S_MEMTIME_vi : SMEM_Real_vi <0x24, S_MEMTIME>;
426def S_MEMREALTIME_vi : SMEM_Real_vi <0x25, S_MEMREALTIME>;
427
428
429//===----------------------------------------------------------------------===//
430// CI
431//===----------------------------------------------------------------------===//
432
433def smrd_literal_offset : NamedOperandU32<"SMRDLiteralOffset",
434 NamedMatchClass<"SMRDLiteralOffset">> {
435 let OperandType = "OPERAND_IMMEDIATE";
436}
437
438class SMRD_Real_Load_IMM_ci <bits<5> op, SM_Load_Pseudo ps> :
439 SM_Real<ps>,
440 Enc64 {
441
442 let AssemblerPredicates = [isCIOnly];
443 let DecoderNamespace = "CI";
Matt Arsenault7b647552016-10-28 21:55:15 +0000444 let InOperandList = (ins ps.BaseClass:$sbase, smrd_literal_offset:$offset, GLC:$glc);
Valery Pykhtin1b138862016-09-01 09:56:47 +0000445
446 let LGKM_CNT = ps.LGKM_CNT;
447 let SMRD = ps.SMRD;
448 let mayLoad = ps.mayLoad;
449 let mayStore = ps.mayStore;
450 let hasSideEffects = ps.hasSideEffects;
451 let SchedRW = ps.SchedRW;
452 let UseNamedOperandTable = ps.UseNamedOperandTable;
453
454 let Inst{7-0} = 0xff;
455 let Inst{8} = 0;
456 let Inst{14-9} = sbase{6-1};
457 let Inst{21-15} = sdst{6-0};
458 let Inst{26-22} = op;
459 let Inst{31-27} = 0x18; //encoding
460 let Inst{63-32} = offset{31-0};
461}
462
463def S_LOAD_DWORD_IMM_ci : SMRD_Real_Load_IMM_ci <0x00, S_LOAD_DWORD_IMM>;
464def S_LOAD_DWORDX2_IMM_ci : SMRD_Real_Load_IMM_ci <0x01, S_LOAD_DWORDX2_IMM>;
465def S_LOAD_DWORDX4_IMM_ci : SMRD_Real_Load_IMM_ci <0x02, S_LOAD_DWORDX4_IMM>;
466def S_LOAD_DWORDX8_IMM_ci : SMRD_Real_Load_IMM_ci <0x03, S_LOAD_DWORDX8_IMM>;
467def S_LOAD_DWORDX16_IMM_ci : SMRD_Real_Load_IMM_ci <0x04, S_LOAD_DWORDX16_IMM>;
468def S_BUFFER_LOAD_DWORD_IMM_ci : SMRD_Real_Load_IMM_ci <0x08, S_BUFFER_LOAD_DWORD_IMM>;
469def S_BUFFER_LOAD_DWORDX2_IMM_ci : SMRD_Real_Load_IMM_ci <0x09, S_BUFFER_LOAD_DWORDX2_IMM>;
470def S_BUFFER_LOAD_DWORDX4_IMM_ci : SMRD_Real_Load_IMM_ci <0x0a, S_BUFFER_LOAD_DWORDX4_IMM>;
471def S_BUFFER_LOAD_DWORDX8_IMM_ci : SMRD_Real_Load_IMM_ci <0x0b, S_BUFFER_LOAD_DWORDX8_IMM>;
472def S_BUFFER_LOAD_DWORDX16_IMM_ci : SMRD_Real_Load_IMM_ci <0x0c, S_BUFFER_LOAD_DWORDX16_IMM>;
473
474class SMRD_Real_ci <bits<5> op, SM_Pseudo ps>
475 : SM_Real<ps>
476 , SIMCInstr<ps.PseudoInstr, SIEncodingFamily.SI>
477 , Enc32 {
478
479 let AssemblerPredicates = [isCIOnly];
480 let DecoderNamespace = "CI";
481
482 let Inst{7-0} = !if(ps.has_offset, offset{7-0}, ?);
483 let Inst{8} = imm;
484 let Inst{14-9} = !if(ps.has_sbase, sbase{6-1}, ?);
485 let Inst{21-15} = !if(ps.has_sdst, sdst{6-0}, ?);
486 let Inst{26-22} = op;
487 let Inst{31-27} = 0x18; //encoding
488}
489
490def S_DCACHE_INV_VOL_ci : SMRD_Real_ci <0x1d, S_DCACHE_INV_VOL>;
491
492let AddedComplexity = SM_LOAD_PATTERN.AddedComplexity in {
493
494class SMRD_Pattern_ci <string Instr, ValueType vt> : Pat <
495 (smrd_load (SMRDImm32 i64:$sbase, i32:$offset)),
Matt Arsenault7b647552016-10-28 21:55:15 +0000496 (vt (!cast<SM_Pseudo>(Instr#"_IMM_ci") $sbase, $offset, 0))> {
Valery Pykhtin1b138862016-09-01 09:56:47 +0000497 let Predicates = [isCIOnly];
498}
499
500def : SMRD_Pattern_ci <"S_LOAD_DWORD", i32>;
501def : SMRD_Pattern_ci <"S_LOAD_DWORDX2", v2i32>;
502def : SMRD_Pattern_ci <"S_LOAD_DWORDX4", v4i32>;
503def : SMRD_Pattern_ci <"S_LOAD_DWORDX8", v8i32>;
504def : SMRD_Pattern_ci <"S_LOAD_DWORDX16", v16i32>;
505
506def : Pat <
507 (SIload_constant v4i32:$sbase, (SMRDBufferImm32 i32:$offset)),
Matt Arsenault7b647552016-10-28 21:55:15 +0000508 (S_BUFFER_LOAD_DWORD_IMM_ci $sbase, $offset, 0)> {
Valery Pykhtin1b138862016-09-01 09:56:47 +0000509 let Predicates = [isCI]; // should this be isCIOnly?
510}
511
512} // End let AddedComplexity = SM_LOAD_PATTERN.AddedComplexity
513