blob: 09728f80e5d59047e202ff5f215d7fa97ccac463 [file] [log] [blame]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001//===-- R600Instructions.td - R600 Instruction defs -------*- tablegen -*-===//
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// R600 Tablegen instruction definitions
11//
12//===----------------------------------------------------------------------===//
13
14include "R600Intrinsics.td"
15
Vincent Lejeune8723c9e2013-04-30 00:13:20 +000016class InstR600 <dag outs, dag ins, string asm, list<dag> pattern,
Tom Stellardf98f2ce2012-12-11 21:25:42 +000017 InstrItinClass itin>
18 : AMDGPUInst <outs, ins, asm, pattern> {
19
20 field bits<64> Inst;
21 bit Trig = 0;
22 bit Op3 = 0;
23 bit isVector = 0;
24 bits<2> FlagOperandIdx = 0;
25 bit Op1 = 0;
26 bit Op2 = 0;
27 bit HasNativeOperands = 0;
Vincent Lejeune631591e2013-04-30 00:13:39 +000028 bit VTXInst = 0;
29 bit TEXInst = 0;
Tom Stellardf98f2ce2012-12-11 21:25:42 +000030
Tom Stellardf98f2ce2012-12-11 21:25:42 +000031 let Namespace = "AMDGPU";
32 let OutOperandList = outs;
33 let InOperandList = ins;
34 let AsmString = asm;
35 let Pattern = pattern;
36 let Itinerary = itin;
37
38 let TSFlags{4} = Trig;
39 let TSFlags{5} = Op3;
40
41 // Vector instructions are instructions that must fill all slots in an
42 // instruction group
43 let TSFlags{6} = isVector;
44 let TSFlags{8-7} = FlagOperandIdx;
45 let TSFlags{9} = HasNativeOperands;
46 let TSFlags{10} = Op1;
47 let TSFlags{11} = Op2;
Vincent Lejeune631591e2013-04-30 00:13:39 +000048 let TSFlags{12} = VTXInst;
49 let TSFlags{13} = TEXInst;
Tom Stellardf98f2ce2012-12-11 21:25:42 +000050}
51
52class InstR600ISA <dag outs, dag ins, string asm, list<dag> pattern> :
Vincent Lejeune8723c9e2013-04-30 00:13:20 +000053 InstR600 <outs, ins, asm, pattern, NullALU> {
Tom Stellardf98f2ce2012-12-11 21:25:42 +000054
55 let Namespace = "AMDGPU";
56}
57
58def MEMxi : Operand<iPTR> {
59 let MIOperandInfo = (ops R600_TReg32_X:$ptr, i32imm:$index);
60 let PrintMethod = "printMemOperand";
61}
62
63def MEMrr : Operand<iPTR> {
64 let MIOperandInfo = (ops R600_Reg32:$ptr, R600_Reg32:$index);
65}
66
67// Operands for non-registers
68
69class InstFlag<string PM = "printOperand", int Default = 0>
70 : OperandWithDefaultOps <i32, (ops (i32 Default))> {
71 let PrintMethod = PM;
72}
73
Vincent Lejeunea311c5262013-02-10 17:57:33 +000074// src_sel for ALU src operands, see also ALU_CONST, ALU_PARAM registers
Tom Stellard9f7818d2013-01-23 02:09:06 +000075def SEL : OperandWithDefaultOps <i32, (ops (i32 -1))> {
76 let PrintMethod = "printSel";
77}
78
Tom Stellardf98f2ce2012-12-11 21:25:42 +000079def LITERAL : InstFlag<"printLiteral">;
80
81def WRITE : InstFlag <"printWrite", 1>;
82def OMOD : InstFlag <"printOMOD">;
83def REL : InstFlag <"printRel">;
84def CLAMP : InstFlag <"printClamp">;
85def NEG : InstFlag <"printNeg">;
86def ABS : InstFlag <"printAbs">;
87def UEM : InstFlag <"printUpdateExecMask">;
88def UP : InstFlag <"printUpdatePred">;
89
90// XXX: The r600g finalizer in Mesa expects last to be one in most cases.
91// Once we start using the packetizer in this backend we should have this
92// default to 0.
93def LAST : InstFlag<"printLast", 1>;
94
Tom Stellardc0b0c672013-02-06 17:32:29 +000095def FRAMEri : Operand<iPTR> {
96 let MIOperandInfo = (ops R600_Reg32:$ptr, i32imm:$index);
97}
98
Tom Stellardf98f2ce2012-12-11 21:25:42 +000099def ADDRParam : ComplexPattern<i32, 2, "SelectADDRParam", [], []>;
100def ADDRDWord : ComplexPattern<i32, 1, "SelectADDRDWord", [], []>;
101def ADDRVTX_READ : ComplexPattern<i32, 2, "SelectADDRVTX_READ", [], []>;
Tom Stellard9f7818d2013-01-23 02:09:06 +0000102def ADDRGA_CONST_OFFSET : ComplexPattern<i32, 1, "SelectGlobalValueConstantOffset", [], []>;
103def ADDRGA_VAR_OFFSET : ComplexPattern<i32, 2, "SelectGlobalValueVariableOffset", [], []>;
Tom Stellardc0b0c672013-02-06 17:32:29 +0000104def ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000105
106class R600ALU_Word0 {
107 field bits<32> Word0;
108
109 bits<11> src0;
110 bits<1> src0_neg;
111 bits<1> src0_rel;
112 bits<11> src1;
113 bits<1> src1_rel;
114 bits<1> src1_neg;
115 bits<3> index_mode = 0;
116 bits<2> pred_sel;
117 bits<1> last;
118
119 bits<9> src0_sel = src0{8-0};
120 bits<2> src0_chan = src0{10-9};
121 bits<9> src1_sel = src1{8-0};
122 bits<2> src1_chan = src1{10-9};
123
124 let Word0{8-0} = src0_sel;
125 let Word0{9} = src0_rel;
126 let Word0{11-10} = src0_chan;
127 let Word0{12} = src0_neg;
128 let Word0{21-13} = src1_sel;
129 let Word0{22} = src1_rel;
130 let Word0{24-23} = src1_chan;
131 let Word0{25} = src1_neg;
132 let Word0{28-26} = index_mode;
133 let Word0{30-29} = pred_sel;
134 let Word0{31} = last;
135}
136
137class R600ALU_Word1 {
138 field bits<32> Word1;
139
140 bits<11> dst;
141 bits<3> bank_swizzle = 0;
142 bits<1> dst_rel;
143 bits<1> clamp;
144
145 bits<7> dst_sel = dst{6-0};
146 bits<2> dst_chan = dst{10-9};
147
148 let Word1{20-18} = bank_swizzle;
149 let Word1{27-21} = dst_sel;
150 let Word1{28} = dst_rel;
151 let Word1{30-29} = dst_chan;
152 let Word1{31} = clamp;
153}
154
155class R600ALU_Word1_OP2 <bits<11> alu_inst> : R600ALU_Word1{
156
157 bits<1> src0_abs;
158 bits<1> src1_abs;
159 bits<1> update_exec_mask;
160 bits<1> update_pred;
161 bits<1> write;
162 bits<2> omod;
163
164 let Word1{0} = src0_abs;
165 let Word1{1} = src1_abs;
166 let Word1{2} = update_exec_mask;
167 let Word1{3} = update_pred;
168 let Word1{4} = write;
169 let Word1{6-5} = omod;
170 let Word1{17-7} = alu_inst;
171}
172
173class R600ALU_Word1_OP3 <bits<5> alu_inst> : R600ALU_Word1{
174
175 bits<11> src2;
176 bits<1> src2_rel;
177 bits<1> src2_neg;
178
179 bits<9> src2_sel = src2{8-0};
180 bits<2> src2_chan = src2{10-9};
181
182 let Word1{8-0} = src2_sel;
183 let Word1{9} = src2_rel;
184 let Word1{11-10} = src2_chan;
185 let Word1{12} = src2_neg;
186 let Word1{17-13} = alu_inst;
187}
188
Tom Stellard80537b92013-01-23 02:09:01 +0000189class VTX_WORD0 {
190 field bits<32> Word0;
191 bits<7> SRC_GPR;
192 bits<5> VC_INST;
193 bits<2> FETCH_TYPE;
194 bits<1> FETCH_WHOLE_QUAD;
195 bits<8> BUFFER_ID;
196 bits<1> SRC_REL;
197 bits<2> SRC_SEL_X;
198 bits<6> MEGA_FETCH_COUNT;
199
200 let Word0{4-0} = VC_INST;
201 let Word0{6-5} = FETCH_TYPE;
202 let Word0{7} = FETCH_WHOLE_QUAD;
203 let Word0{15-8} = BUFFER_ID;
204 let Word0{22-16} = SRC_GPR;
205 let Word0{23} = SRC_REL;
206 let Word0{25-24} = SRC_SEL_X;
207 let Word0{31-26} = MEGA_FETCH_COUNT;
208}
209
210class VTX_WORD1_GPR {
211 field bits<32> Word1;
212 bits<7> DST_GPR;
213 bits<1> DST_REL;
214 bits<3> DST_SEL_X;
215 bits<3> DST_SEL_Y;
216 bits<3> DST_SEL_Z;
217 bits<3> DST_SEL_W;
218 bits<1> USE_CONST_FIELDS;
219 bits<6> DATA_FORMAT;
220 bits<2> NUM_FORMAT_ALL;
221 bits<1> FORMAT_COMP_ALL;
222 bits<1> SRF_MODE_ALL;
223
224 let Word1{6-0} = DST_GPR;
225 let Word1{7} = DST_REL;
226 let Word1{8} = 0; // Reserved
227 let Word1{11-9} = DST_SEL_X;
228 let Word1{14-12} = DST_SEL_Y;
229 let Word1{17-15} = DST_SEL_Z;
230 let Word1{20-18} = DST_SEL_W;
231 let Word1{21} = USE_CONST_FIELDS;
232 let Word1{27-22} = DATA_FORMAT;
233 let Word1{29-28} = NUM_FORMAT_ALL;
234 let Word1{30} = FORMAT_COMP_ALL;
235 let Word1{31} = SRF_MODE_ALL;
236}
237
Vincent Lejeune2691fe92013-03-31 19:33:04 +0000238class TEX_WORD0 {
239 field bits<32> Word0;
240
241 bits<5> TEX_INST;
242 bits<2> INST_MOD;
243 bits<1> FETCH_WHOLE_QUAD;
244 bits<8> RESOURCE_ID;
245 bits<7> SRC_GPR;
246 bits<1> SRC_REL;
247 bits<1> ALT_CONST;
248 bits<2> RESOURCE_INDEX_MODE;
249 bits<2> SAMPLER_INDEX_MODE;
250
251 let Word0{4-0} = TEX_INST;
252 let Word0{6-5} = INST_MOD;
253 let Word0{7} = FETCH_WHOLE_QUAD;
254 let Word0{15-8} = RESOURCE_ID;
255 let Word0{22-16} = SRC_GPR;
256 let Word0{23} = SRC_REL;
257 let Word0{24} = ALT_CONST;
258 let Word0{26-25} = RESOURCE_INDEX_MODE;
259 let Word0{28-27} = SAMPLER_INDEX_MODE;
260}
261
262class TEX_WORD1 {
263 field bits<32> Word1;
264
265 bits<7> DST_GPR;
266 bits<1> DST_REL;
267 bits<3> DST_SEL_X;
268 bits<3> DST_SEL_Y;
269 bits<3> DST_SEL_Z;
270 bits<3> DST_SEL_W;
271 bits<7> LOD_BIAS;
272 bits<1> COORD_TYPE_X;
273 bits<1> COORD_TYPE_Y;
274 bits<1> COORD_TYPE_Z;
275 bits<1> COORD_TYPE_W;
276
277 let Word1{6-0} = DST_GPR;
278 let Word1{7} = DST_REL;
279 let Word1{11-9} = DST_SEL_X;
280 let Word1{14-12} = DST_SEL_Y;
281 let Word1{17-15} = DST_SEL_Z;
282 let Word1{20-18} = DST_SEL_W;
283 let Word1{27-21} = LOD_BIAS;
284 let Word1{28} = COORD_TYPE_X;
285 let Word1{29} = COORD_TYPE_Y;
286 let Word1{30} = COORD_TYPE_Z;
287 let Word1{31} = COORD_TYPE_W;
288}
289
290class TEX_WORD2 {
291 field bits<32> Word2;
292
293 bits<5> OFFSET_X;
294 bits<5> OFFSET_Y;
295 bits<5> OFFSET_Z;
296 bits<5> SAMPLER_ID;
297 bits<3> SRC_SEL_X;
298 bits<3> SRC_SEL_Y;
299 bits<3> SRC_SEL_Z;
300 bits<3> SRC_SEL_W;
301
302 let Word2{4-0} = OFFSET_X;
303 let Word2{9-5} = OFFSET_Y;
304 let Word2{14-10} = OFFSET_Z;
305 let Word2{19-15} = SAMPLER_ID;
306 let Word2{22-20} = SRC_SEL_X;
307 let Word2{25-23} = SRC_SEL_Y;
308 let Word2{28-26} = SRC_SEL_Z;
309 let Word2{31-29} = SRC_SEL_W;
310}
311
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000312/*
313XXX: R600 subtarget uses a slightly different encoding than the other
314subtargets. We currently handle this in R600MCCodeEmitter, but we may
315want to use these instruction classes in the future.
316
317class R600ALU_Word1_OP2_r600 : R600ALU_Word1_OP2 {
318
319 bits<1> fog_merge;
320 bits<10> alu_inst;
321
322 let Inst{37} = fog_merge;
323 let Inst{39-38} = omod;
324 let Inst{49-40} = alu_inst;
325}
326
327class R600ALU_Word1_OP2_r700 : R600ALU_Word1_OP2 {
328
329 bits<11> alu_inst;
330
331 let Inst{38-37} = omod;
332 let Inst{49-39} = alu_inst;
333}
334*/
335
336def R600_Pred : PredicateOperand<i32, (ops R600_Predicate),
337 (ops PRED_SEL_OFF)>;
338
339
340let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
341
342// Class for instructions with only one source register.
343// If you add new ins to this instruction, make sure they are listed before
344// $literal, because the backend currently assumes that the last operand is
345// a literal. Also be sure to update the enum R600Op1OperandIndex::ROI in
346// R600Defines.h, R600InstrInfo::buildDefaultInstruction(),
347// and R600InstrInfo::getOperandIdx().
348class R600_1OP <bits<11> inst, string opName, list<dag> pattern,
349 InstrItinClass itin = AnyALU> :
Vincent Lejeune8723c9e2013-04-30 00:13:20 +0000350 InstR600 <(outs R600_Reg32:$dst),
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000351 (ins WRITE:$write, OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
Tom Stellard9f7818d2013-01-23 02:09:06 +0000352 R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000353 LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
Vincent Lejeune8e591912013-04-01 21:47:42 +0000354 !strconcat(" ", opName,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000355 "$clamp $dst$write$dst_rel$omod, "
Vincent Lejeune8e591912013-04-01 21:47:42 +0000356 "$src0_neg$src0_abs$src0$src0_abs$src0_rel, "
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000357 "$literal $pred_sel$last"),
358 pattern,
359 itin>,
360 R600ALU_Word0,
361 R600ALU_Word1_OP2 <inst> {
362
363 let src1 = 0;
364 let src1_rel = 0;
365 let src1_neg = 0;
366 let src1_abs = 0;
367 let update_exec_mask = 0;
368 let update_pred = 0;
369 let HasNativeOperands = 1;
370 let Op1 = 1;
371 let DisableEncoding = "$literal";
372
373 let Inst{31-0} = Word0;
374 let Inst{63-32} = Word1;
375}
376
377class R600_1OP_Helper <bits<11> inst, string opName, SDPatternOperator node,
378 InstrItinClass itin = AnyALU> :
379 R600_1OP <inst, opName,
380 [(set R600_Reg32:$dst, (node R600_Reg32:$src0))]
381>;
382
383// If you add our change the operands for R600_2OP instructions, you must
384// also update the R600Op2OperandIndex::ROI enum in R600Defines.h,
385// R600InstrInfo::buildDefaultInstruction(), and R600InstrInfo::getOperandIdx().
386class R600_2OP <bits<11> inst, string opName, list<dag> pattern,
387 InstrItinClass itin = AnyALU> :
Vincent Lejeune8723c9e2013-04-30 00:13:20 +0000388 InstR600 <(outs R600_Reg32:$dst),
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000389 (ins UEM:$update_exec_mask, UP:$update_pred, WRITE:$write,
390 OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
Tom Stellard9f7818d2013-01-23 02:09:06 +0000391 R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel,
392 R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, ABS:$src1_abs, SEL:$src1_sel,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000393 LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
Vincent Lejeune8e591912013-04-01 21:47:42 +0000394 !strconcat(" ", opName,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000395 "$clamp $update_exec_mask$update_pred$dst$write$dst_rel$omod, "
Vincent Lejeune8e591912013-04-01 21:47:42 +0000396 "$src0_neg$src0_abs$src0$src0_abs$src0_rel, "
397 "$src1_neg$src1_abs$src1$src1_abs$src1_rel, "
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000398 "$literal $pred_sel$last"),
399 pattern,
400 itin>,
401 R600ALU_Word0,
402 R600ALU_Word1_OP2 <inst> {
403
404 let HasNativeOperands = 1;
405 let Op2 = 1;
406 let DisableEncoding = "$literal";
407
408 let Inst{31-0} = Word0;
409 let Inst{63-32} = Word1;
410}
411
412class R600_2OP_Helper <bits<11> inst, string opName, SDPatternOperator node,
413 InstrItinClass itim = AnyALU> :
414 R600_2OP <inst, opName,
415 [(set R600_Reg32:$dst, (node R600_Reg32:$src0,
416 R600_Reg32:$src1))]
417>;
418
419// If you add our change the operands for R600_3OP instructions, you must
420// also update the R600Op3OperandIndex::ROI enum in R600Defines.h,
421// R600InstrInfo::buildDefaultInstruction(), and
422// R600InstrInfo::getOperandIdx().
423class R600_3OP <bits<5> inst, string opName, list<dag> pattern,
424 InstrItinClass itin = AnyALU> :
Vincent Lejeune8723c9e2013-04-30 00:13:20 +0000425 InstR600 <(outs R600_Reg32:$dst),
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000426 (ins REL:$dst_rel, CLAMP:$clamp,
Tom Stellard9f7818d2013-01-23 02:09:06 +0000427 R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, SEL:$src0_sel,
428 R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, SEL:$src1_sel,
429 R600_Reg32:$src2, NEG:$src2_neg, REL:$src2_rel, SEL:$src2_sel,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000430 LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
Vincent Lejeune8e591912013-04-01 21:47:42 +0000431 !strconcat(" ", opName, "$clamp $dst$dst_rel, "
432 "$src0_neg$src0$src0_rel, "
433 "$src1_neg$src1$src1_rel, "
434 "$src2_neg$src2$src2_rel, "
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000435 "$literal $pred_sel$last"),
436 pattern,
437 itin>,
438 R600ALU_Word0,
439 R600ALU_Word1_OP3<inst>{
440
441 let HasNativeOperands = 1;
442 let DisableEncoding = "$literal";
443 let Op3 = 1;
444
445 let Inst{31-0} = Word0;
446 let Inst{63-32} = Word1;
447}
448
449class R600_REDUCTION <bits<11> inst, dag ins, string asm, list<dag> pattern,
450 InstrItinClass itin = VecALU> :
Vincent Lejeune8723c9e2013-04-30 00:13:20 +0000451 InstR600 <(outs R600_Reg32:$dst),
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000452 ins,
453 asm,
454 pattern,
455 itin>;
456
457class R600_TEX <bits<11> inst, string opName, list<dag> pattern,
458 InstrItinClass itin = AnyALU> :
Vincent Lejeune8723c9e2013-04-30 00:13:20 +0000459 InstR600 <(outs R600_Reg128:$DST_GPR),
Vincent Lejeune2691fe92013-03-31 19:33:04 +0000460 (ins R600_Reg128:$SRC_GPR, i32imm:$RESOURCE_ID, i32imm:$SAMPLER_ID, i32imm:$textureTarget),
461 !strconcat(opName, "$DST_GPR, $SRC_GPR, $RESOURCE_ID, $SAMPLER_ID, $textureTarget"),
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000462 pattern,
Vincent Lejeune2691fe92013-03-31 19:33:04 +0000463 itin>, TEX_WORD0, TEX_WORD1, TEX_WORD2 {
464 let Inst{31-0} = Word0;
465 let Inst{63-32} = Word1;
466
467 let TEX_INST = inst{4-0};
468 let SRC_REL = 0;
469 let DST_REL = 0;
470 let DST_SEL_X = 0;
471 let DST_SEL_Y = 1;
472 let DST_SEL_Z = 2;
473 let DST_SEL_W = 3;
474 let LOD_BIAS = 0;
475
476 let INST_MOD = 0;
477 let FETCH_WHOLE_QUAD = 0;
478 let ALT_CONST = 0;
479 let SAMPLER_INDEX_MODE = 0;
Vincent Lejeuneb6379de2013-04-30 00:13:53 +0000480 let RESOURCE_INDEX_MODE = 0;
Vincent Lejeune2691fe92013-03-31 19:33:04 +0000481
482 let COORD_TYPE_X = 0;
483 let COORD_TYPE_Y = 0;
484 let COORD_TYPE_Z = 0;
485 let COORD_TYPE_W = 0;
Vincent Lejeune631591e2013-04-30 00:13:39 +0000486
487 let TEXInst = 1;
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000488 }
489
490} // End mayLoad = 1, mayStore = 0, hasSideEffects = 0
491
492def TEX_SHADOW : PatLeaf<
493 (imm),
494 [{uint32_t TType = (uint32_t)N->getZExtValue();
Michel Danzer6158ad12013-02-12 12:11:23 +0000495 return (TType >= 6 && TType <= 8) || (TType >= 11 && TType <= 13);
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000496 }]
497>;
498
Tom Stellard97ff6182013-01-21 15:40:48 +0000499def TEX_RECT : PatLeaf<
500 (imm),
501 [{uint32_t TType = (uint32_t)N->getZExtValue();
502 return TType == 5;
503 }]
504>;
505
Tom Stellard64dca862013-02-07 17:02:14 +0000506def TEX_ARRAY : PatLeaf<
507 (imm),
508 [{uint32_t TType = (uint32_t)N->getZExtValue();
509 return TType == 9 || TType == 10 || TType == 15 || TType == 16;
510 }]
511>;
512
513def TEX_SHADOW_ARRAY : PatLeaf<
514 (imm),
515 [{uint32_t TType = (uint32_t)N->getZExtValue();
516 return TType == 11 || TType == 12 || TType == 17;
517 }]
518>;
519
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000520class EG_CF_RAT <bits <8> cf_inst, bits <6> rat_inst, bits<4> rat_id, dag outs,
521 dag ins, string asm, list<dag> pattern> :
522 InstR600ISA <outs, ins, asm, pattern> {
523 bits<7> RW_GPR;
524 bits<7> INDEX_GPR;
525
526 bits<2> RIM;
527 bits<2> TYPE;
528 bits<1> RW_REL;
529 bits<2> ELEM_SIZE;
530
531 bits<12> ARRAY_SIZE;
532 bits<4> COMP_MASK;
533 bits<4> BURST_COUNT;
534 bits<1> VPM;
535 bits<1> eop;
536 bits<1> MARK;
537 bits<1> BARRIER;
538
539 // CF_ALLOC_EXPORT_WORD0_RAT
540 let Inst{3-0} = rat_id;
541 let Inst{9-4} = rat_inst;
542 let Inst{10} = 0; // Reserved
543 let Inst{12-11} = RIM;
544 let Inst{14-13} = TYPE;
545 let Inst{21-15} = RW_GPR;
546 let Inst{22} = RW_REL;
547 let Inst{29-23} = INDEX_GPR;
548 let Inst{31-30} = ELEM_SIZE;
549
550 // CF_ALLOC_EXPORT_WORD1_BUF
551 let Inst{43-32} = ARRAY_SIZE;
552 let Inst{47-44} = COMP_MASK;
553 let Inst{51-48} = BURST_COUNT;
554 let Inst{52} = VPM;
555 let Inst{53} = eop;
556 let Inst{61-54} = cf_inst;
557 let Inst{62} = MARK;
558 let Inst{63} = BARRIER;
559}
560
561class LoadParamFrag <PatFrag load_type> : PatFrag <
562 (ops node:$ptr), (load_type node:$ptr),
563 [{ return isParamLoad(dyn_cast<LoadSDNode>(N)); }]
564>;
565
566def load_param : LoadParamFrag<load>;
567def load_param_zexti8 : LoadParamFrag<zextloadi8>;
568def load_param_zexti16 : LoadParamFrag<zextloadi16>;
569
570def isR600 : Predicate<"Subtarget.device()"
571 "->getGeneration() == AMDGPUDeviceInfo::HD4XXX">;
572def isR700 : Predicate<"Subtarget.device()"
573 "->getGeneration() == AMDGPUDeviceInfo::HD4XXX &&"
574 "Subtarget.device()->getDeviceFlag()"
575 ">= OCL_DEVICE_RV710">;
576def isEG : Predicate<
577 "Subtarget.device()->getGeneration() >= AMDGPUDeviceInfo::HD5XXX && "
578 "Subtarget.device()->getGeneration() < AMDGPUDeviceInfo::HD7XXX && "
579 "Subtarget.device()->getDeviceFlag() != OCL_DEVICE_CAYMAN">;
580
581def isCayman : Predicate<"Subtarget.device()"
582 "->getDeviceFlag() == OCL_DEVICE_CAYMAN">;
583def isEGorCayman : Predicate<"Subtarget.device()"
584 "->getGeneration() == AMDGPUDeviceInfo::HD5XXX"
585 "|| Subtarget.device()->getGeneration() =="
586 "AMDGPUDeviceInfo::HD6XXX">;
587
588def isR600toCayman : Predicate<
589 "Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX">;
590
591//===----------------------------------------------------------------------===//
Tom Stellardc7e18882013-01-23 02:09:03 +0000592// R600 SDNodes
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000593//===----------------------------------------------------------------------===//
594
Tom Stellard29b15a32013-02-05 17:09:14 +0000595def INTERP_PAIR_XY : AMDGPUShaderInst <
596 (outs R600_TReg32_X:$dst0, R600_TReg32_Y:$dst1),
597 (ins i32imm:$src0, R600_Reg32:$src1, R600_Reg32:$src2),
598 "INTERP_PAIR_XY $src0 $src1 $src2 : $dst0 dst1",
599 []>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000600
Tom Stellard29b15a32013-02-05 17:09:14 +0000601def INTERP_PAIR_ZW : AMDGPUShaderInst <
602 (outs R600_TReg32_Z:$dst0, R600_TReg32_W:$dst1),
603 (ins i32imm:$src0, R600_Reg32:$src1, R600_Reg32:$src2),
604 "INTERP_PAIR_ZW $src0 $src1 $src2 : $dst0 dst1",
605 []>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000606
Tom Stellardc7e18882013-01-23 02:09:03 +0000607def CONST_ADDRESS: SDNode<"AMDGPUISD::CONST_ADDRESS",
Vincent Lejeune3f7f8e82013-03-05 15:04:29 +0000608 SDTypeProfile<1, -1, [SDTCisInt<0>, SDTCisPtrTy<1>]>,
Vincent Lejeune64ca84d2013-03-05 15:04:42 +0000609 [SDNPVariadic]
Tom Stellardc7e18882013-01-23 02:09:03 +0000610>;
611
612//===----------------------------------------------------------------------===//
613// Interpolation Instructions
614//===----------------------------------------------------------------------===//
615
Tom Stellard29b15a32013-02-05 17:09:14 +0000616def INTERP_VEC_LOAD : AMDGPUShaderInst <
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000617 (outs R600_Reg128:$dst),
Tom Stellard29b15a32013-02-05 17:09:14 +0000618 (ins i32imm:$src0),
619 "INTERP_LOAD $src0 : $dst",
620 []>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000621
622def INTERP_XY : R600_2OP <0xD6, "INTERP_XY", []> {
623 let bank_swizzle = 5;
624}
625
626def INTERP_ZW : R600_2OP <0xD7, "INTERP_ZW", []> {
627 let bank_swizzle = 5;
628}
629
630def INTERP_LOAD_P0 : R600_1OP <0xE0, "INTERP_LOAD_P0", []>;
631
632//===----------------------------------------------------------------------===//
633// Export Instructions
634//===----------------------------------------------------------------------===//
635
Vincent Lejeuneabfd5f62013-02-14 16:55:06 +0000636def ExportType : SDTypeProfile<0, 7, [SDTCisFP<0>, SDTCisInt<1>]>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000637
638def EXPORT: SDNode<"AMDGPUISD::EXPORT", ExportType,
639 [SDNPHasChain, SDNPSideEffect]>;
640
641class ExportWord0 {
642 field bits<32> Word0;
643
644 bits<13> arraybase;
645 bits<2> type;
646 bits<7> gpr;
647 bits<2> elem_size;
648
649 let Word0{12-0} = arraybase;
650 let Word0{14-13} = type;
651 let Word0{21-15} = gpr;
652 let Word0{22} = 0; // RW_REL
653 let Word0{29-23} = 0; // INDEX_GPR
654 let Word0{31-30} = elem_size;
655}
656
657class ExportSwzWord1 {
658 field bits<32> Word1;
659
660 bits<3> sw_x;
661 bits<3> sw_y;
662 bits<3> sw_z;
663 bits<3> sw_w;
664 bits<1> eop;
665 bits<8> inst;
666
667 let Word1{2-0} = sw_x;
668 let Word1{5-3} = sw_y;
669 let Word1{8-6} = sw_z;
670 let Word1{11-9} = sw_w;
671}
672
673class ExportBufWord1 {
674 field bits<32> Word1;
675
676 bits<12> arraySize;
677 bits<4> compMask;
678 bits<1> eop;
679 bits<8> inst;
680
681 let Word1{11-0} = arraySize;
682 let Word1{15-12} = compMask;
683}
684
685multiclass ExportPattern<Instruction ExportInst, bits<8> cf_inst> {
686 def : Pat<(int_R600_store_pixel_depth R600_Reg32:$reg),
687 (ExportInst
Tom Stellard07b59ba2013-02-07 14:02:37 +0000688 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), R600_Reg32:$reg, sub0),
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000689 0, 61, 0, 7, 7, 7, cf_inst, 0)
690 >;
691
692 def : Pat<(int_R600_store_pixel_stencil R600_Reg32:$reg),
693 (ExportInst
Tom Stellard07b59ba2013-02-07 14:02:37 +0000694 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), R600_Reg32:$reg, sub0),
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000695 0, 61, 7, 0, 7, 7, cf_inst, 0)
696 >;
697
Tom Stellard44ddc362013-01-31 22:11:46 +0000698 def : Pat<(int_R600_store_dummy (i32 imm:$type)),
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000699 (ExportInst
Tom Stellard44ddc362013-01-31 22:11:46 +0000700 (v4f32 (IMPLICIT_DEF)), imm:$type, 0, 7, 7, 7, 7, cf_inst, 0)
701 >;
702
703 def : Pat<(int_R600_store_dummy 1),
704 (ExportInst
705 (v4f32 (IMPLICIT_DEF)), 1, 60, 7, 7, 7, 7, cf_inst, 0)
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000706 >;
707
Vincent Lejeuneabfd5f62013-02-14 16:55:06 +0000708 def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 imm:$base), (i32 imm:$type),
709 (i32 imm:$swz_x), (i32 imm:$swz_y), (i32 imm:$swz_z), (i32 imm:$swz_w)),
710 (ExportInst R600_Reg128:$src, imm:$type, imm:$base,
711 imm:$swz_x, imm:$swz_y, imm:$swz_z, imm:$swz_w, cf_inst, 0)
Tom Stellard254a83e2013-01-23 21:39:49 +0000712 >;
713
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000714}
715
716multiclass SteamOutputExportPattern<Instruction ExportInst,
717 bits<8> buf0inst, bits<8> buf1inst, bits<8> buf2inst, bits<8> buf3inst> {
718// Stream0
Tom Stellard2a3e0d72013-01-23 21:39:47 +0000719 def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src),
720 (i32 imm:$arraybase), (i32 0), (i32 imm:$mask)),
721 (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000722 4095, imm:$mask, buf0inst, 0)>;
723// Stream1
Tom Stellard2a3e0d72013-01-23 21:39:47 +0000724 def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src),
725 (i32 imm:$arraybase), (i32 1), (i32 imm:$mask)),
726 (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000727 4095, imm:$mask, buf1inst, 0)>;
728// Stream2
Tom Stellard2a3e0d72013-01-23 21:39:47 +0000729 def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src),
730 (i32 imm:$arraybase), (i32 2), (i32 imm:$mask)),
731 (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000732 4095, imm:$mask, buf2inst, 0)>;
733// Stream3
Tom Stellard2a3e0d72013-01-23 21:39:47 +0000734 def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src),
735 (i32 imm:$arraybase), (i32 3), (i32 imm:$mask)),
736 (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000737 4095, imm:$mask, buf3inst, 0)>;
738}
739
Vincent Lejeune26ebd7a2013-04-17 15:17:39 +0000740// Export Instructions should not be duplicated by TailDuplication pass
741// (which assumes that duplicable instruction are affected by exec mask)
742let usesCustomInserter = 1, isNotDuplicable = 1 in {
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000743
744class ExportSwzInst : InstR600ISA<(
745 outs),
746 (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase,
747 i32imm:$sw_x, i32imm:$sw_y, i32imm:$sw_z, i32imm:$sw_w, i32imm:$inst,
748 i32imm:$eop),
749 !strconcat("EXPORT", " $gpr"),
750 []>, ExportWord0, ExportSwzWord1 {
751 let elem_size = 3;
752 let Inst{31-0} = Word0;
753 let Inst{63-32} = Word1;
754}
755
Vincent Lejeunef846add2013-02-14 16:55:11 +0000756} // End usesCustomInserter = 1
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000757
758class ExportBufInst : InstR600ISA<(
759 outs),
760 (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase,
761 i32imm:$arraySize, i32imm:$compMask, i32imm:$inst, i32imm:$eop),
762 !strconcat("EXPORT", " $gpr"),
763 []>, ExportWord0, ExportBufWord1 {
764 let elem_size = 0;
765 let Inst{31-0} = Word0;
766 let Inst{63-32} = Word1;
767}
768
Vincent Lejeune8e591912013-04-01 21:47:42 +0000769//===----------------------------------------------------------------------===//
770// Control Flow Instructions
771//===----------------------------------------------------------------------===//
772
773class CF_ALU_WORD0 {
774 field bits<32> Word0;
775
776 bits<22> ADDR;
777 bits<4> KCACHE_BANK0;
778 bits<4> KCACHE_BANK1;
779 bits<2> KCACHE_MODE0;
780
781 let Word0{21-0} = ADDR;
782 let Word0{25-22} = KCACHE_BANK0;
783 let Word0{29-26} = KCACHE_BANK1;
784 let Word0{31-30} = KCACHE_MODE0;
785}
786
787class CF_ALU_WORD1 {
788 field bits<32> Word1;
789
790 bits<2> KCACHE_MODE1;
791 bits<8> KCACHE_ADDR0;
792 bits<8> KCACHE_ADDR1;
793 bits<7> COUNT;
794 bits<1> ALT_CONST;
795 bits<4> CF_INST;
796 bits<1> WHOLE_QUAD_MODE;
797 bits<1> BARRIER;
798
799 let Word1{1-0} = KCACHE_MODE1;
800 let Word1{9-2} = KCACHE_ADDR0;
801 let Word1{17-10} = KCACHE_ADDR1;
802 let Word1{24-18} = COUNT;
803 let Word1{25} = ALT_CONST;
804 let Word1{29-26} = CF_INST;
805 let Word1{30} = WHOLE_QUAD_MODE;
806 let Word1{31} = BARRIER;
807}
808
809class ALU_CLAUSE<bits<4> inst, string OpName> : AMDGPUInst <(outs),
810(ins i32imm:$ADDR, i32imm:$KCACHE_BANK0, i32imm:$KCACHE_BANK1, i32imm:$KCACHE_MODE0, i32imm:$KCACHE_MODE1,
811i32imm:$KCACHE_ADDR0, i32imm:$KCACHE_ADDR1, i32imm:$COUNT),
812!strconcat(OpName, " $COUNT, @$ADDR, "
813"KC0[CB$KCACHE_BANK0:$KCACHE_ADDR0-$KCACHE_ADDR0+32]"
814", KC1[CB$KCACHE_BANK1:$KCACHE_ADDR1-$KCACHE_ADDR1+32]"),
815[] >, CF_ALU_WORD0, CF_ALU_WORD1 {
816 field bits<64> Inst;
817
818 let CF_INST = inst;
819 let ALT_CONST = 0;
820 let WHOLE_QUAD_MODE = 0;
821 let BARRIER = 1;
822
823 let Inst{31-0} = Word0;
824 let Inst{63-32} = Word1;
825}
826
Vincent Lejeunebd7c6342013-04-08 13:05:49 +0000827class CF_WORD0_R600 {
828 field bits<32> Word0;
829
830 bits<32> ADDR;
831
832 let Word0 = ADDR;
833}
834
835class CF_WORD1_R600 {
836 field bits<32> Word1;
837
838 bits<3> POP_COUNT;
839 bits<5> CF_CONST;
840 bits<2> COND;
841 bits<3> COUNT;
842 bits<6> CALL_COUNT;
843 bits<1> COUNT_3;
844 bits<1> END_OF_PROGRAM;
845 bits<1> VALID_PIXEL_MODE;
846 bits<7> CF_INST;
847 bits<1> WHOLE_QUAD_MODE;
848 bits<1> BARRIER;
849
850 let Word1{2-0} = POP_COUNT;
851 let Word1{7-3} = CF_CONST;
852 let Word1{9-8} = COND;
853 let Word1{12-10} = COUNT;
854 let Word1{18-13} = CALL_COUNT;
855 let Word1{19} = COUNT_3;
856 let Word1{21} = END_OF_PROGRAM;
857 let Word1{22} = VALID_PIXEL_MODE;
858 let Word1{29-23} = CF_INST;
859 let Word1{30} = WHOLE_QUAD_MODE;
860 let Word1{31} = BARRIER;
861}
862
863class CF_CLAUSE_R600 <bits<7> inst, dag ins, string AsmPrint> : AMDGPUInst <(outs),
864ins, AsmPrint, [] >, CF_WORD0_R600, CF_WORD1_R600 {
865 field bits<64> Inst;
866
867 let CF_INST = inst;
868 let BARRIER = 1;
869 let CF_CONST = 0;
870 let VALID_PIXEL_MODE = 0;
871 let COND = 0;
872 let CALL_COUNT = 0;
873 let COUNT_3 = 0;
874 let END_OF_PROGRAM = 0;
875 let WHOLE_QUAD_MODE = 0;
876
877 let Inst{31-0} = Word0;
878 let Inst{63-32} = Word1;
879}
880
881class CF_WORD0_EG {
Vincent Lejeune08001a52013-04-01 21:48:05 +0000882 field bits<32> Word0;
883
884 bits<24> ADDR;
885 bits<3> JUMPTABLE_SEL;
886
887 let Word0{23-0} = ADDR;
888 let Word0{26-24} = JUMPTABLE_SEL;
889}
890
Vincent Lejeunebd7c6342013-04-08 13:05:49 +0000891class CF_WORD1_EG {
Vincent Lejeune08001a52013-04-01 21:48:05 +0000892 field bits<32> Word1;
893
894 bits<3> POP_COUNT;
895 bits<5> CF_CONST;
896 bits<2> COND;
897 bits<6> COUNT;
898 bits<1> VALID_PIXEL_MODE;
Vincent Lejeune7a28d8a2013-04-23 17:34:00 +0000899 bits<1> END_OF_PROGRAM;
Vincent Lejeune08001a52013-04-01 21:48:05 +0000900 bits<8> CF_INST;
901 bits<1> BARRIER;
902
903 let Word1{2-0} = POP_COUNT;
904 let Word1{7-3} = CF_CONST;
905 let Word1{9-8} = COND;
906 let Word1{15-10} = COUNT;
907 let Word1{20} = VALID_PIXEL_MODE;
Tom Stellard015f5862013-04-29 22:23:54 +0000908 let Word1{21} = END_OF_PROGRAM;
Vincent Lejeune08001a52013-04-01 21:48:05 +0000909 let Word1{29-22} = CF_INST;
910 let Word1{31} = BARRIER;
911}
912
Vincent Lejeunebd7c6342013-04-08 13:05:49 +0000913class CF_CLAUSE_EG <bits<8> inst, dag ins, string AsmPrint> : AMDGPUInst <(outs),
914ins, AsmPrint, [] >, CF_WORD0_EG, CF_WORD1_EG {
Vincent Lejeune08001a52013-04-01 21:48:05 +0000915 field bits<64> Inst;
916
917 let CF_INST = inst;
918 let BARRIER = 1;
919 let JUMPTABLE_SEL = 0;
920 let CF_CONST = 0;
921 let VALID_PIXEL_MODE = 0;
922 let COND = 0;
Vincent Lejeune7a28d8a2013-04-23 17:34:00 +0000923 let END_OF_PROGRAM = 0;
Vincent Lejeune08001a52013-04-01 21:48:05 +0000924
925 let Inst{31-0} = Word0;
926 let Inst{63-32} = Word1;
927}
928
Vincent Lejeune8e591912013-04-01 21:47:42 +0000929def CF_ALU : ALU_CLAUSE<8, "ALU">;
930def CF_ALU_PUSH_BEFORE : ALU_CLAUSE<9, "ALU_PUSH_BEFORE">;
931
Vincent Lejeuneb6379de2013-04-30 00:13:53 +0000932def FETCH_CLAUSE : AMDGPUInst <(outs),
933(ins i32imm:$addr), "Fetch clause starting at $addr:", [] > {
934 field bits<8> Inst;
935 bits<8> num;
936 let Inst = num;
937}
938
Vincent Lejeune7a28d8a2013-04-23 17:34:00 +0000939def PAD : AMDGPUInst <(outs), (ins), "PAD", [] > {
940 field bits<64> Inst;
941}
942
Vincent Lejeunea311c5262013-02-10 17:57:33 +0000943let Predicates = [isR600toCayman] in {
Tom Stellardf98f2ce2012-12-11 21:25:42 +0000944
945//===----------------------------------------------------------------------===//
946// Common Instructions R600, R700, Evergreen, Cayman
947//===----------------------------------------------------------------------===//
948
949def ADD : R600_2OP_Helper <0x0, "ADD", fadd>;
950// Non-IEEE MUL: 0 * anything = 0
951def MUL : R600_2OP_Helper <0x1, "MUL NON-IEEE", int_AMDGPU_mul>;
952def MUL_IEEE : R600_2OP_Helper <0x2, "MUL_IEEE", fmul>;
953def MAX : R600_2OP_Helper <0x3, "MAX", AMDGPUfmax>;
954def MIN : R600_2OP_Helper <0x4, "MIN", AMDGPUfmin>;
955
956// For the SET* instructions there is a naming conflict in TargetSelectionDAG.td,
957// so some of the instruction names don't match the asm string.
958// XXX: Use the defs in TargetSelectionDAG.td instead of intrinsics.
959def SETE : R600_2OP <
960 0x08, "SETE",
961 [(set R600_Reg32:$dst,
962 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
963 COND_EQ))]
964>;
965
966def SGT : R600_2OP <
967 0x09, "SETGT",
968 [(set R600_Reg32:$dst,
969 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
970 COND_GT))]
971>;
972
973def SGE : R600_2OP <
974 0xA, "SETGE",
975 [(set R600_Reg32:$dst,
976 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
977 COND_GE))]
978>;
979
980def SNE : R600_2OP <
981 0xB, "SETNE",
982 [(set R600_Reg32:$dst,
983 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
984 COND_NE))]
985>;
986
Tom Stellard1234c9b2013-02-07 14:02:35 +0000987def SETE_DX10 : R600_2OP <
988 0xC, "SETE_DX10",
989 [(set R600_Reg32:$dst,
990 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0),
991 COND_EQ))]
992>;
993
994def SETGT_DX10 : R600_2OP <
995 0xD, "SETGT_DX10",
996 [(set R600_Reg32:$dst,
997 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0),
998 COND_GT))]
999>;
1000
1001def SETGE_DX10 : R600_2OP <
1002 0xE, "SETGE_DX10",
1003 [(set R600_Reg32:$dst,
1004 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0),
1005 COND_GE))]
1006>;
1007
1008def SETNE_DX10 : R600_2OP <
1009 0xF, "SETNE_DX10",
1010 [(set R600_Reg32:$dst,
1011 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0),
1012 COND_NE))]
1013>;
1014
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001015def FRACT : R600_1OP_Helper <0x10, "FRACT", AMDGPUfract>;
1016def TRUNC : R600_1OP_Helper <0x11, "TRUNC", int_AMDGPU_trunc>;
1017def CEIL : R600_1OP_Helper <0x12, "CEIL", fceil>;
1018def RNDNE : R600_1OP_Helper <0x13, "RNDNE", frint>;
1019def FLOOR : R600_1OP_Helper <0x14, "FLOOR", ffloor>;
1020
1021def MOV : R600_1OP <0x19, "MOV", []>;
1022
1023let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in {
1024
1025class MOV_IMM <ValueType vt, Operand immType> : AMDGPUInst <
1026 (outs R600_Reg32:$dst),
1027 (ins immType:$imm),
1028 "",
1029 []
1030>;
1031
1032} // end let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1
1033
1034def MOV_IMM_I32 : MOV_IMM<i32, i32imm>;
1035def : Pat <
1036 (imm:$val),
1037 (MOV_IMM_I32 imm:$val)
1038>;
1039
1040def MOV_IMM_F32 : MOV_IMM<f32, f32imm>;
1041def : Pat <
1042 (fpimm:$val),
1043 (MOV_IMM_F32 fpimm:$val)
1044>;
1045
1046def PRED_SETE : R600_2OP <0x20, "PRED_SETE", []>;
1047def PRED_SETGT : R600_2OP <0x21, "PRED_SETGT", []>;
1048def PRED_SETGE : R600_2OP <0x22, "PRED_SETGE", []>;
1049def PRED_SETNE : R600_2OP <0x23, "PRED_SETNE", []>;
1050
1051let hasSideEffects = 1 in {
1052
1053def KILLGT : R600_2OP <0x2D, "KILLGT", []>;
1054
1055} // end hasSideEffects
1056
1057def AND_INT : R600_2OP_Helper <0x30, "AND_INT", and>;
1058def OR_INT : R600_2OP_Helper <0x31, "OR_INT", or>;
1059def XOR_INT : R600_2OP_Helper <0x32, "XOR_INT", xor>;
1060def NOT_INT : R600_1OP_Helper <0x33, "NOT_INT", not>;
1061def ADD_INT : R600_2OP_Helper <0x34, "ADD_INT", add>;
1062def SUB_INT : R600_2OP_Helper <0x35, "SUB_INT", sub>;
1063def MAX_INT : R600_2OP_Helper <0x36, "MAX_INT", AMDGPUsmax>;
1064def MIN_INT : R600_2OP_Helper <0x37, "MIN_INT", AMDGPUsmin>;
Tom Stellardeef0d5a2012-12-21 20:12:01 +00001065def MAX_UINT : R600_2OP_Helper <0x38, "MAX_UINT", AMDGPUumax>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001066def MIN_UINT : R600_2OP_Helper <0x39, "MIN_UINT", AMDGPUumin>;
1067
1068def SETE_INT : R600_2OP <
1069 0x3A, "SETE_INT",
1070 [(set (i32 R600_Reg32:$dst),
1071 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETEQ))]
1072>;
1073
1074def SETGT_INT : R600_2OP <
Tom Stellardb4409612013-02-07 14:02:27 +00001075 0x3B, "SETGT_INT",
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001076 [(set (i32 R600_Reg32:$dst),
1077 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETGT))]
1078>;
1079
1080def SETGE_INT : R600_2OP <
1081 0x3C, "SETGE_INT",
1082 [(set (i32 R600_Reg32:$dst),
1083 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETGE))]
1084>;
1085
1086def SETNE_INT : R600_2OP <
1087 0x3D, "SETNE_INT",
1088 [(set (i32 R600_Reg32:$dst),
1089 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETNE))]
1090>;
1091
1092def SETGT_UINT : R600_2OP <
1093 0x3E, "SETGT_UINT",
1094 [(set (i32 R600_Reg32:$dst),
1095 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGT))]
1096>;
1097
1098def SETGE_UINT : R600_2OP <
1099 0x3F, "SETGE_UINT",
1100 [(set (i32 R600_Reg32:$dst),
1101 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGE))]
1102>;
1103
1104def PRED_SETE_INT : R600_2OP <0x42, "PRED_SETE_INT", []>;
1105def PRED_SETGT_INT : R600_2OP <0x43, "PRED_SETGE_INT", []>;
1106def PRED_SETGE_INT : R600_2OP <0x44, "PRED_SETGE_INT", []>;
1107def PRED_SETNE_INT : R600_2OP <0x45, "PRED_SETNE_INT", []>;
1108
1109def CNDE_INT : R600_3OP <
1110 0x1C, "CNDE_INT",
1111 [(set (i32 R600_Reg32:$dst),
1112 (selectcc (i32 R600_Reg32:$src0), 0,
1113 (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
1114 COND_EQ))]
1115>;
1116
1117def CNDGE_INT : R600_3OP <
1118 0x1E, "CNDGE_INT",
1119 [(set (i32 R600_Reg32:$dst),
1120 (selectcc (i32 R600_Reg32:$src0), 0,
1121 (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
1122 COND_GE))]
1123>;
1124
1125def CNDGT_INT : R600_3OP <
1126 0x1D, "CNDGT_INT",
1127 [(set (i32 R600_Reg32:$dst),
1128 (selectcc (i32 R600_Reg32:$src0), 0,
1129 (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
1130 COND_GT))]
1131>;
1132
1133//===----------------------------------------------------------------------===//
1134// Texture instructions
1135//===----------------------------------------------------------------------===//
1136
1137def TEX_LD : R600_TEX <
1138 0x03, "TEX_LD",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001139 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txf R600_Reg128:$SRC_GPR,
1140 imm:$OFFSET_X, imm:$OFFSET_Y, imm:$OFFSET_Z, imm:$RESOURCE_ID,
1141 imm:$SAMPLER_ID, imm:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001142> {
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001143let AsmString = "TEX_LD $DST_GPR, $SRC_GPR, $OFFSET_X, $OFFSET_Y, $OFFSET_Z,"
1144 "$RESOURCE_ID, $SAMPLER_ID, $textureTarget";
1145let InOperandList = (ins R600_Reg128:$SRC_GPR, i32imm:$OFFSET_X,
1146 i32imm:$OFFSET_Y, i32imm:$OFFSET_Z, i32imm:$RESOURCE_ID, i32imm:$SAMPLER_ID,
1147 i32imm:$textureTarget);
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001148}
1149
1150def TEX_GET_TEXTURE_RESINFO : R600_TEX <
1151 0x04, "TEX_GET_TEXTURE_RESINFO",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001152 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txq R600_Reg128:$SRC_GPR,
1153 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001154>;
1155
1156def TEX_GET_GRADIENTS_H : R600_TEX <
1157 0x07, "TEX_GET_GRADIENTS_H",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001158 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_ddx R600_Reg128:$SRC_GPR,
1159 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001160>;
1161
1162def TEX_GET_GRADIENTS_V : R600_TEX <
1163 0x08, "TEX_GET_GRADIENTS_V",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001164 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_ddy R600_Reg128:$SRC_GPR,
1165 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001166>;
1167
1168def TEX_SET_GRADIENTS_H : R600_TEX <
1169 0x0B, "TEX_SET_GRADIENTS_H",
1170 []
1171>;
1172
1173def TEX_SET_GRADIENTS_V : R600_TEX <
1174 0x0C, "TEX_SET_GRADIENTS_V",
1175 []
1176>;
1177
1178def TEX_SAMPLE : R600_TEX <
1179 0x10, "TEX_SAMPLE",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001180 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_tex R600_Reg128:$SRC_GPR,
1181 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001182>;
1183
1184def TEX_SAMPLE_C : R600_TEX <
1185 0x18, "TEX_SAMPLE_C",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001186 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_tex R600_Reg128:$SRC_GPR,
1187 imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001188>;
1189
1190def TEX_SAMPLE_L : R600_TEX <
1191 0x11, "TEX_SAMPLE_L",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001192 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txl R600_Reg128:$SRC_GPR,
1193 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001194>;
1195
1196def TEX_SAMPLE_C_L : R600_TEX <
1197 0x19, "TEX_SAMPLE_C_L",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001198 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txl R600_Reg128:$SRC_GPR,
1199 imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001200>;
1201
1202def TEX_SAMPLE_LB : R600_TEX <
1203 0x12, "TEX_SAMPLE_LB",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001204 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txb R600_Reg128:$SRC_GPR,
1205 imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001206>;
1207
1208def TEX_SAMPLE_C_LB : R600_TEX <
1209 0x1A, "TEX_SAMPLE_C_LB",
Vincent Lejeune2691fe92013-03-31 19:33:04 +00001210 [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txb R600_Reg128:$SRC_GPR,
1211 imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001212>;
1213
1214def TEX_SAMPLE_G : R600_TEX <
1215 0x14, "TEX_SAMPLE_G",
1216 []
1217>;
1218
1219def TEX_SAMPLE_C_G : R600_TEX <
1220 0x1C, "TEX_SAMPLE_C_G",
1221 []
1222>;
1223
1224//===----------------------------------------------------------------------===//
1225// Helper classes for common instructions
1226//===----------------------------------------------------------------------===//
1227
1228class MUL_LIT_Common <bits<5> inst> : R600_3OP <
1229 inst, "MUL_LIT",
1230 []
1231>;
1232
1233class MULADD_Common <bits<5> inst> : R600_3OP <
1234 inst, "MULADD",
Vincent Lejeunee3111962013-02-18 14:11:28 +00001235 []
1236>;
1237
1238class MULADD_IEEE_Common <bits<5> inst> : R600_3OP <
1239 inst, "MULADD_IEEE",
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001240 [(set (f32 R600_Reg32:$dst),
Vincent Lejeunee3111962013-02-18 14:11:28 +00001241 (fadd (fmul R600_Reg32:$src0, R600_Reg32:$src1), R600_Reg32:$src2))]
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001242>;
1243
1244class CNDE_Common <bits<5> inst> : R600_3OP <
1245 inst, "CNDE",
1246 [(set R600_Reg32:$dst,
1247 (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
1248 (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
1249 COND_EQ))]
1250>;
1251
1252class CNDGT_Common <bits<5> inst> : R600_3OP <
1253 inst, "CNDGT",
1254 [(set R600_Reg32:$dst,
1255 (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
1256 (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
1257 COND_GT))]
1258>;
1259
1260class CNDGE_Common <bits<5> inst> : R600_3OP <
1261 inst, "CNDGE",
1262 [(set R600_Reg32:$dst,
1263 (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
1264 (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
1265 COND_GE))]
1266>;
1267
1268multiclass DOT4_Common <bits<11> inst> {
1269
1270 def _pseudo : R600_REDUCTION <inst,
1271 (ins R600_Reg128:$src0, R600_Reg128:$src1),
1272 "DOT4 $dst $src0, $src1",
1273 [(set R600_Reg32:$dst, (int_AMDGPU_dp4 R600_Reg128:$src0, R600_Reg128:$src1))]
1274 >;
1275
1276 def _real : R600_2OP <inst, "DOT4", []>;
1277}
1278
1279let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
1280multiclass CUBE_Common <bits<11> inst> {
1281
1282 def _pseudo : InstR600 <
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001283 (outs R600_Reg128:$dst),
1284 (ins R600_Reg128:$src),
1285 "CUBE $dst $src",
1286 [(set R600_Reg128:$dst, (int_AMDGPU_cube R600_Reg128:$src))],
1287 VecALU
1288 > {
1289 let isPseudo = 1;
1290 }
1291
1292 def _real : R600_2OP <inst, "CUBE", []>;
1293}
1294} // End mayLoad = 0, mayStore = 0, hasSideEffects = 0
1295
1296class EXP_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
1297 inst, "EXP_IEEE", fexp2
1298>;
1299
1300class FLT_TO_INT_Common <bits<11> inst> : R600_1OP_Helper <
1301 inst, "FLT_TO_INT", fp_to_sint
1302>;
1303
1304class INT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
1305 inst, "INT_TO_FLT", sint_to_fp
1306>;
1307
1308class FLT_TO_UINT_Common <bits<11> inst> : R600_1OP_Helper <
1309 inst, "FLT_TO_UINT", fp_to_uint
1310>;
1311
1312class UINT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
1313 inst, "UINT_TO_FLT", uint_to_fp
1314>;
1315
1316class LOG_CLAMPED_Common <bits<11> inst> : R600_1OP <
1317 inst, "LOG_CLAMPED", []
1318>;
1319
1320class LOG_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
1321 inst, "LOG_IEEE", flog2
1322>;
1323
1324class LSHL_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHL", shl>;
1325class LSHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHR", srl>;
1326class ASHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "ASHR", sra>;
1327class MULHI_INT_Common <bits<11> inst> : R600_2OP_Helper <
1328 inst, "MULHI_INT", mulhs
1329>;
1330class MULHI_UINT_Common <bits<11> inst> : R600_2OP_Helper <
1331 inst, "MULHI", mulhu
1332>;
1333class MULLO_INT_Common <bits<11> inst> : R600_2OP_Helper <
1334 inst, "MULLO_INT", mul
1335>;
1336class MULLO_UINT_Common <bits<11> inst> : R600_2OP <inst, "MULLO_UINT", []>;
1337
1338class RECIP_CLAMPED_Common <bits<11> inst> : R600_1OP <
1339 inst, "RECIP_CLAMPED", []
1340>;
1341
1342class RECIP_IEEE_Common <bits<11> inst> : R600_1OP <
1343 inst, "RECIP_IEEE", [(set R600_Reg32:$dst, (fdiv FP_ONE, R600_Reg32:$src0))]
1344>;
1345
1346class RECIP_UINT_Common <bits<11> inst> : R600_1OP_Helper <
1347 inst, "RECIP_UINT", AMDGPUurecip
1348>;
1349
1350class RECIPSQRT_CLAMPED_Common <bits<11> inst> : R600_1OP_Helper <
1351 inst, "RECIPSQRT_CLAMPED", int_AMDGPU_rsq
1352>;
1353
1354class RECIPSQRT_IEEE_Common <bits<11> inst> : R600_1OP <
1355 inst, "RECIPSQRT_IEEE", []
1356>;
1357
1358class SIN_Common <bits<11> inst> : R600_1OP <
1359 inst, "SIN", []>{
1360 let Trig = 1;
1361}
1362
1363class COS_Common <bits<11> inst> : R600_1OP <
1364 inst, "COS", []> {
1365 let Trig = 1;
1366}
1367
1368//===----------------------------------------------------------------------===//
1369// Helper patterns for complex intrinsics
1370//===----------------------------------------------------------------------===//
1371
1372multiclass DIV_Common <InstR600 recip_ieee> {
1373def : Pat<
1374 (int_AMDGPU_div R600_Reg32:$src0, R600_Reg32:$src1),
Vincent Lejeunef49cf1c2013-03-05 15:04:37 +00001375 (MUL_IEEE R600_Reg32:$src0, (recip_ieee R600_Reg32:$src1))
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001376>;
1377
1378def : Pat<
1379 (fdiv R600_Reg32:$src0, R600_Reg32:$src1),
Vincent Lejeunef49cf1c2013-03-05 15:04:37 +00001380 (MUL_IEEE R600_Reg32:$src0, (recip_ieee R600_Reg32:$src1))
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001381>;
1382}
1383
1384class TGSI_LIT_Z_Common <InstR600 mul_lit, InstR600 log_clamped, InstR600 exp_ieee> : Pat <
1385 (int_TGSI_lit_z R600_Reg32:$src_x, R600_Reg32:$src_y, R600_Reg32:$src_w),
1386 (exp_ieee (mul_lit (log_clamped (MAX R600_Reg32:$src_y, (f32 ZERO))), R600_Reg32:$src_w, R600_Reg32:$src_x))
1387>;
1388
1389//===----------------------------------------------------------------------===//
1390// R600 / R700 Instructions
1391//===----------------------------------------------------------------------===//
1392
1393let Predicates = [isR600] in {
1394
1395 def MUL_LIT_r600 : MUL_LIT_Common<0x0C>;
1396 def MULADD_r600 : MULADD_Common<0x10>;
Vincent Lejeunee3111962013-02-18 14:11:28 +00001397 def MULADD_IEEE_r600 : MULADD_IEEE_Common<0x14>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001398 def CNDE_r600 : CNDE_Common<0x18>;
1399 def CNDGT_r600 : CNDGT_Common<0x19>;
1400 def CNDGE_r600 : CNDGE_Common<0x1A>;
1401 defm DOT4_r600 : DOT4_Common<0x50>;
1402 defm CUBE_r600 : CUBE_Common<0x52>;
1403 def EXP_IEEE_r600 : EXP_IEEE_Common<0x61>;
1404 def LOG_CLAMPED_r600 : LOG_CLAMPED_Common<0x62>;
1405 def LOG_IEEE_r600 : LOG_IEEE_Common<0x63>;
1406 def RECIP_CLAMPED_r600 : RECIP_CLAMPED_Common<0x64>;
1407 def RECIP_IEEE_r600 : RECIP_IEEE_Common<0x66>;
1408 def RECIPSQRT_CLAMPED_r600 : RECIPSQRT_CLAMPED_Common<0x67>;
1409 def RECIPSQRT_IEEE_r600 : RECIPSQRT_IEEE_Common<0x69>;
1410 def FLT_TO_INT_r600 : FLT_TO_INT_Common<0x6b>;
1411 def INT_TO_FLT_r600 : INT_TO_FLT_Common<0x6c>;
1412 def FLT_TO_UINT_r600 : FLT_TO_UINT_Common<0x79>;
1413 def UINT_TO_FLT_r600 : UINT_TO_FLT_Common<0x6d>;
1414 def SIN_r600 : SIN_Common<0x6E>;
1415 def COS_r600 : COS_Common<0x6F>;
1416 def ASHR_r600 : ASHR_Common<0x70>;
1417 def LSHR_r600 : LSHR_Common<0x71>;
1418 def LSHL_r600 : LSHL_Common<0x72>;
1419 def MULLO_INT_r600 : MULLO_INT_Common<0x73>;
1420 def MULHI_INT_r600 : MULHI_INT_Common<0x74>;
1421 def MULLO_UINT_r600 : MULLO_UINT_Common<0x75>;
1422 def MULHI_UINT_r600 : MULHI_UINT_Common<0x76>;
1423 def RECIP_UINT_r600 : RECIP_UINT_Common <0x78>;
1424
1425 defm DIV_r600 : DIV_Common<RECIP_IEEE_r600>;
Michel Danzerc446baa2013-03-22 14:09:10 +00001426 def : POW_Common <LOG_IEEE_r600, EXP_IEEE_r600, MUL, R600_Reg32>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001427 def TGSI_LIT_Z_r600 : TGSI_LIT_Z_Common<MUL_LIT_r600, LOG_CLAMPED_r600, EXP_IEEE_r600>;
1428
1429 def : Pat<(fsqrt R600_Reg32:$src),
1430 (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_r600 R600_Reg32:$src))>;
1431
1432 def R600_ExportSwz : ExportSwzInst {
Vincent Lejeune58df1692013-04-17 15:17:32 +00001433 let Word1{20-17} = 0; // BURST_COUNT
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001434 let Word1{21} = eop;
1435 let Word1{22} = 1; // VALID_PIXEL_MODE
1436 let Word1{30-23} = inst;
1437 let Word1{31} = 1; // BARRIER
1438 }
1439 defm : ExportPattern<R600_ExportSwz, 39>;
1440
1441 def R600_ExportBuf : ExportBufInst {
Vincent Lejeune58df1692013-04-17 15:17:32 +00001442 let Word1{20-17} = 0; // BURST_COUNT
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001443 let Word1{21} = eop;
1444 let Word1{22} = 1; // VALID_PIXEL_MODE
1445 let Word1{30-23} = inst;
1446 let Word1{31} = 1; // BARRIER
1447 }
1448 defm : SteamOutputExportPattern<R600_ExportBuf, 0x20, 0x21, 0x22, 0x23>;
Vincent Lejeunebd7c6342013-04-08 13:05:49 +00001449
1450 def CF_TC_R600 : CF_CLAUSE_R600<1, (ins i32imm:$ADDR, i32imm:$COUNT),
1451 "TEX $COUNT @$ADDR"> {
1452 let POP_COUNT = 0;
1453 }
1454 def CF_VC_R600 : CF_CLAUSE_R600<2, (ins i32imm:$ADDR, i32imm:$COUNT),
1455 "VTX $COUNT @$ADDR"> {
1456 let POP_COUNT = 0;
1457 }
1458 def WHILE_LOOP_R600 : CF_CLAUSE_R600<6, (ins i32imm:$ADDR),
1459 "LOOP_START_DX10 @$ADDR"> {
1460 let POP_COUNT = 0;
1461 let COUNT = 0;
1462 }
1463 def END_LOOP_R600 : CF_CLAUSE_R600<5, (ins i32imm:$ADDR), "END_LOOP @$ADDR"> {
1464 let POP_COUNT = 0;
1465 let COUNT = 0;
1466 }
1467 def LOOP_BREAK_R600 : CF_CLAUSE_R600<9, (ins i32imm:$ADDR),
1468 "LOOP_BREAK @$ADDR"> {
1469 let POP_COUNT = 0;
1470 let COUNT = 0;
1471 }
1472 def CF_CONTINUE_R600 : CF_CLAUSE_R600<8, (ins i32imm:$ADDR),
1473 "CONTINUE @$ADDR"> {
1474 let POP_COUNT = 0;
1475 let COUNT = 0;
1476 }
1477 def CF_JUMP_R600 : CF_CLAUSE_R600<10, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
1478 "JUMP @$ADDR POP:$POP_COUNT"> {
1479 let COUNT = 0;
1480 }
1481 def CF_ELSE_R600 : CF_CLAUSE_R600<13, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
1482 "ELSE @$ADDR POP:$POP_COUNT"> {
1483 let COUNT = 0;
1484 }
1485 def CF_CALL_FS_R600 : CF_CLAUSE_R600<19, (ins), "CALL_FS"> {
1486 let ADDR = 0;
1487 let COUNT = 0;
1488 let POP_COUNT = 0;
1489 }
1490 def POP_R600 : CF_CLAUSE_R600<14, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
1491 "POP @$ADDR POP:$POP_COUNT"> {
1492 let COUNT = 0;
1493 }
Vincent Lejeune7a28d8a2013-04-23 17:34:00 +00001494 def CF_END_R600 : CF_CLAUSE_R600<0, (ins), "CF_END"> {
1495 let COUNT = 0;
1496 let POP_COUNT = 0;
1497 let ADDR = 0;
1498 let END_OF_PROGRAM = 1;
1499 }
Vincent Lejeunebd7c6342013-04-08 13:05:49 +00001500
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001501}
1502
1503// Helper pattern for normalizing inputs to triginomic instructions for R700+
1504// cards.
1505class COS_PAT <InstR600 trig> : Pat<
1506 (fcos R600_Reg32:$src),
Vincent Lejeunef49cf1c2013-03-05 15:04:37 +00001507 (trig (MUL_IEEE (MOV_IMM_I32 CONST.TWO_PI_INV), R600_Reg32:$src))
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001508>;
1509
1510class SIN_PAT <InstR600 trig> : Pat<
1511 (fsin R600_Reg32:$src),
Vincent Lejeunef49cf1c2013-03-05 15:04:37 +00001512 (trig (MUL_IEEE (MOV_IMM_I32 CONST.TWO_PI_INV), R600_Reg32:$src))
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001513>;
1514
1515//===----------------------------------------------------------------------===//
1516// R700 Only instructions
1517//===----------------------------------------------------------------------===//
1518
1519let Predicates = [isR700] in {
1520 def SIN_r700 : SIN_Common<0x6E>;
1521 def COS_r700 : COS_Common<0x6F>;
1522
1523 // R700 normalizes inputs to SIN/COS the same as EG
1524 def : SIN_PAT <SIN_r700>;
1525 def : COS_PAT <COS_r700>;
1526}
1527
1528//===----------------------------------------------------------------------===//
1529// Evergreen Only instructions
1530//===----------------------------------------------------------------------===//
1531
1532let Predicates = [isEG] in {
Vincent Lejeunea311c5262013-02-10 17:57:33 +00001533
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001534def RECIP_IEEE_eg : RECIP_IEEE_Common<0x86>;
1535defm DIV_eg : DIV_Common<RECIP_IEEE_eg>;
1536
1537def MULLO_INT_eg : MULLO_INT_Common<0x8F>;
1538def MULHI_INT_eg : MULHI_INT_Common<0x90>;
1539def MULLO_UINT_eg : MULLO_UINT_Common<0x91>;
1540def MULHI_UINT_eg : MULHI_UINT_Common<0x92>;
1541def RECIP_UINT_eg : RECIP_UINT_Common<0x94>;
1542def RECIPSQRT_CLAMPED_eg : RECIPSQRT_CLAMPED_Common<0x87>;
1543def EXP_IEEE_eg : EXP_IEEE_Common<0x81>;
1544def LOG_IEEE_eg : LOG_IEEE_Common<0x83>;
1545def RECIP_CLAMPED_eg : RECIP_CLAMPED_Common<0x84>;
1546def RECIPSQRT_IEEE_eg : RECIPSQRT_IEEE_Common<0x89>;
1547def SIN_eg : SIN_Common<0x8D>;
1548def COS_eg : COS_Common<0x8E>;
1549
Michel Danzerc446baa2013-03-22 14:09:10 +00001550def : POW_Common <LOG_IEEE_eg, EXP_IEEE_eg, MUL, R600_Reg32>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001551def : SIN_PAT <SIN_eg>;
1552def : COS_PAT <COS_eg>;
1553def : Pat<(fsqrt R600_Reg32:$src),
1554 (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_eg R600_Reg32:$src))>;
1555} // End Predicates = [isEG]
1556
1557//===----------------------------------------------------------------------===//
1558// Evergreen / Cayman Instructions
1559//===----------------------------------------------------------------------===//
1560
1561let Predicates = [isEGorCayman] in {
1562
1563 // BFE_UINT - bit_extract, an optimization for mask and shift
1564 // Src0 = Input
1565 // Src1 = Offset
1566 // Src2 = Width
1567 //
1568 // bit_extract = (Input << (32 - Offset - Width)) >> (32 - Width)
1569 //
1570 // Example Usage:
1571 // (Offset, Width)
1572 //
1573 // (0, 8) = (Input << 24) >> 24 = (Input & 0xff) >> 0
1574 // (8, 8) = (Input << 16) >> 24 = (Input & 0xffff) >> 8
1575 // (16,8) = (Input << 8) >> 24 = (Input & 0xffffff) >> 16
1576 // (24,8) = (Input << 0) >> 24 = (Input & 0xffffffff) >> 24
1577 def BFE_UINT_eg : R600_3OP <0x4, "BFE_UINT",
1578 [(set R600_Reg32:$dst, (int_AMDIL_bit_extract_u32 R600_Reg32:$src0,
1579 R600_Reg32:$src1,
1580 R600_Reg32:$src2))],
1581 VecALU
1582 >;
1583
Tom Stellard48b809e2013-04-19 02:11:06 +00001584 def BFI_INT_eg : R600_3OP <0x06, "BFI_INT", []>;
1585 defm : BFIPatterns <BFI_INT_eg>;
1586
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001587 def BIT_ALIGN_INT_eg : R600_3OP <0xC, "BIT_ALIGN_INT",
1588 [(set R600_Reg32:$dst, (AMDGPUbitalign R600_Reg32:$src0, R600_Reg32:$src1,
1589 R600_Reg32:$src2))],
1590 VecALU
1591 >;
1592
1593 def MULADD_eg : MULADD_Common<0x14>;
Vincent Lejeunee3111962013-02-18 14:11:28 +00001594 def MULADD_IEEE_eg : MULADD_IEEE_Common<0x18>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001595 def ASHR_eg : ASHR_Common<0x15>;
1596 def LSHR_eg : LSHR_Common<0x16>;
1597 def LSHL_eg : LSHL_Common<0x17>;
1598 def CNDE_eg : CNDE_Common<0x19>;
1599 def CNDGT_eg : CNDGT_Common<0x1A>;
1600 def CNDGE_eg : CNDGE_Common<0x1B>;
1601 def MUL_LIT_eg : MUL_LIT_Common<0x1F>;
1602 def LOG_CLAMPED_eg : LOG_CLAMPED_Common<0x82>;
1603 defm DOT4_eg : DOT4_Common<0xBE>;
1604 defm CUBE_eg : CUBE_Common<0xC0>;
1605
Tom Stellardc0b0c672013-02-06 17:32:29 +00001606let hasSideEffects = 1 in {
1607 def MOVA_INT_eg : R600_1OP <0xCC, "MOVA_INT", []>;
1608}
1609
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001610 def TGSI_LIT_Z_eg : TGSI_LIT_Z_Common<MUL_LIT_eg, LOG_CLAMPED_eg, EXP_IEEE_eg>;
1611
1612 def FLT_TO_INT_eg : FLT_TO_INT_Common<0x50> {
1613 let Pattern = [];
1614 }
1615
1616 def INT_TO_FLT_eg : INT_TO_FLT_Common<0x9B>;
1617
1618 def FLT_TO_UINT_eg : FLT_TO_UINT_Common<0x9A> {
1619 let Pattern = [];
1620 }
1621
1622 def UINT_TO_FLT_eg : UINT_TO_FLT_Common<0x9C>;
1623
1624 // TRUNC is used for the FLT_TO_INT instructions to work around a
1625 // perceived problem where the rounding modes are applied differently
1626 // depending on the instruction and the slot they are in.
1627 // See:
1628 // https://bugs.freedesktop.org/show_bug.cgi?id=50232
1629 // Mesa commit: a1a0974401c467cb86ef818f22df67c21774a38c
1630 //
1631 // XXX: Lowering SELECT_CC will sometimes generate fp_to_[su]int nodes,
1632 // which do not need to be truncated since the fp values are 0.0f or 1.0f.
1633 // We should look into handling these cases separately.
1634 def : Pat<(fp_to_sint R600_Reg32:$src0),
1635 (FLT_TO_INT_eg (TRUNC R600_Reg32:$src0))>;
1636
1637 def : Pat<(fp_to_uint R600_Reg32:$src0),
1638 (FLT_TO_UINT_eg (TRUNC R600_Reg32:$src0))>;
1639
1640 def EG_ExportSwz : ExportSwzInst {
Vincent Lejeune58df1692013-04-17 15:17:32 +00001641 let Word1{19-16} = 0; // BURST_COUNT
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001642 let Word1{20} = 1; // VALID_PIXEL_MODE
1643 let Word1{21} = eop;
1644 let Word1{29-22} = inst;
1645 let Word1{30} = 0; // MARK
1646 let Word1{31} = 1; // BARRIER
1647 }
1648 defm : ExportPattern<EG_ExportSwz, 83>;
1649
1650 def EG_ExportBuf : ExportBufInst {
Vincent Lejeune58df1692013-04-17 15:17:32 +00001651 let Word1{19-16} = 0; // BURST_COUNT
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001652 let Word1{20} = 1; // VALID_PIXEL_MODE
1653 let Word1{21} = eop;
1654 let Word1{29-22} = inst;
1655 let Word1{30} = 0; // MARK
1656 let Word1{31} = 1; // BARRIER
1657 }
1658 defm : SteamOutputExportPattern<EG_ExportBuf, 0x40, 0x41, 0x42, 0x43>;
1659
Vincent Lejeunebd7c6342013-04-08 13:05:49 +00001660 def CF_TC_EG : CF_CLAUSE_EG<1, (ins i32imm:$ADDR, i32imm:$COUNT),
1661 "TEX $COUNT @$ADDR"> {
1662 let POP_COUNT = 0;
1663 }
1664 def CF_VC_EG : CF_CLAUSE_EG<2, (ins i32imm:$ADDR, i32imm:$COUNT),
1665 "VTX $COUNT @$ADDR"> {
1666 let POP_COUNT = 0;
1667 }
1668 def WHILE_LOOP_EG : CF_CLAUSE_EG<6, (ins i32imm:$ADDR),
1669 "LOOP_START_DX10 @$ADDR"> {
1670 let POP_COUNT = 0;
1671 let COUNT = 0;
1672 }
1673 def END_LOOP_EG : CF_CLAUSE_EG<5, (ins i32imm:$ADDR), "END_LOOP @$ADDR"> {
1674 let POP_COUNT = 0;
1675 let COUNT = 0;
1676 }
1677 def LOOP_BREAK_EG : CF_CLAUSE_EG<9, (ins i32imm:$ADDR),
1678 "LOOP_BREAK @$ADDR"> {
1679 let POP_COUNT = 0;
1680 let COUNT = 0;
1681 }
1682 def CF_CONTINUE_EG : CF_CLAUSE_EG<8, (ins i32imm:$ADDR),
1683 "CONTINUE @$ADDR"> {
1684 let POP_COUNT = 0;
1685 let COUNT = 0;
1686 }
1687 def CF_JUMP_EG : CF_CLAUSE_EG<10, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
1688 "JUMP @$ADDR POP:$POP_COUNT"> {
1689 let COUNT = 0;
1690 }
1691 def CF_ELSE_EG : CF_CLAUSE_EG<13, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
1692 "ELSE @$ADDR POP:$POP_COUNT"> {
1693 let COUNT = 0;
1694 }
1695 def CF_CALL_FS_EG : CF_CLAUSE_EG<19, (ins), "CALL_FS"> {
1696 let ADDR = 0;
1697 let COUNT = 0;
1698 let POP_COUNT = 0;
1699 }
1700 def POP_EG : CF_CLAUSE_EG<14, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
1701 "POP @$ADDR POP:$POP_COUNT"> {
1702 let COUNT = 0;
1703 }
Vincent Lejeune7a28d8a2013-04-23 17:34:00 +00001704 def CF_END_EG : CF_CLAUSE_EG<0, (ins), "CF_END"> {
1705 let COUNT = 0;
1706 let POP_COUNT = 0;
1707 let ADDR = 0;
1708 let END_OF_PROGRAM = 1;
1709 }
Vincent Lejeunebd7c6342013-04-08 13:05:49 +00001710
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001711//===----------------------------------------------------------------------===//
1712// Memory read/write instructions
1713//===----------------------------------------------------------------------===//
1714let usesCustomInserter = 1 in {
1715
1716class RAT_WRITE_CACHELESS_eg <dag ins, bits<4> comp_mask, string name,
1717 list<dag> pattern>
1718 : EG_CF_RAT <0x57, 0x2, 0, (outs), ins,
1719 !strconcat(name, " $rw_gpr, $index_gpr, $eop"), pattern> {
1720 let RIM = 0;
1721 // XXX: Have a separate instruction for non-indexed writes.
1722 let TYPE = 1;
1723 let RW_REL = 0;
1724 let ELEM_SIZE = 0;
1725
1726 let ARRAY_SIZE = 0;
1727 let COMP_MASK = comp_mask;
1728 let BURST_COUNT = 0;
1729 let VPM = 0;
1730 let MARK = 0;
1731 let BARRIER = 1;
1732}
1733
1734} // End usesCustomInserter = 1
1735
1736// 32-bit store
1737def RAT_WRITE_CACHELESS_32_eg : RAT_WRITE_CACHELESS_eg <
1738 (ins R600_TReg32_X:$rw_gpr, R600_TReg32_X:$index_gpr, InstFlag:$eop),
1739 0x1, "RAT_WRITE_CACHELESS_32_eg",
1740 [(global_store (i32 R600_TReg32_X:$rw_gpr), R600_TReg32_X:$index_gpr)]
1741>;
1742
1743//128-bit store
1744def RAT_WRITE_CACHELESS_128_eg : RAT_WRITE_CACHELESS_eg <
1745 (ins R600_Reg128:$rw_gpr, R600_TReg32_X:$index_gpr, InstFlag:$eop),
1746 0xf, "RAT_WRITE_CACHELESS_128",
1747 [(global_store (v4i32 R600_Reg128:$rw_gpr), R600_TReg32_X:$index_gpr)]
1748>;
1749
1750class VTX_READ_eg <string name, bits<8> buffer_id, dag outs, list<dag> pattern>
Tom Stellard80537b92013-01-23 02:09:01 +00001751 : InstR600ISA <outs, (ins MEMxi:$ptr), name#" $dst, $ptr", pattern>,
1752 VTX_WORD1_GPR, VTX_WORD0 {
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001753
1754 // Static fields
Tom Stellard80537b92013-01-23 02:09:01 +00001755 let VC_INST = 0;
1756 let FETCH_TYPE = 2;
1757 let FETCH_WHOLE_QUAD = 0;
1758 let BUFFER_ID = buffer_id;
1759 let SRC_REL = 0;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001760 // XXX: We can infer this field based on the SRC_GPR. This would allow us
1761 // to store vertex addresses in any channel, not just X.
Tom Stellard80537b92013-01-23 02:09:01 +00001762 let SRC_SEL_X = 0;
1763 let DST_REL = 0;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001764 // The docs say that if this bit is set, then DATA_FORMAT, NUM_FORMAT_ALL,
1765 // FORMAT_COMP_ALL, SRF_MODE_ALL, and ENDIAN_SWAP fields will be ignored,
1766 // however, based on my testing if USE_CONST_FIELDS is set, then all
1767 // these fields need to be set to 0.
Tom Stellard80537b92013-01-23 02:09:01 +00001768 let USE_CONST_FIELDS = 0;
1769 let NUM_FORMAT_ALL = 1;
1770 let FORMAT_COMP_ALL = 0;
1771 let SRF_MODE_ALL = 0;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001772
Tom Stellard80537b92013-01-23 02:09:01 +00001773 let Inst{31-0} = Word0;
1774 let Inst{63-32} = Word1;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001775 // LLVM can only encode 64-bit instructions, so these fields are manually
1776 // encoded in R600CodeEmitter
1777 //
1778 // bits<16> OFFSET;
1779 // bits<2> ENDIAN_SWAP = 0;
1780 // bits<1> CONST_BUF_NO_STRIDE = 0;
1781 // bits<1> MEGA_FETCH = 0;
1782 // bits<1> ALT_CONST = 0;
1783 // bits<2> BUFFER_INDEX_MODE = 0;
1784
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001785
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001786
1787 // VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
1788 // is done in R600CodeEmitter
1789 //
1790 // Inst{79-64} = OFFSET;
1791 // Inst{81-80} = ENDIAN_SWAP;
1792 // Inst{82} = CONST_BUF_NO_STRIDE;
1793 // Inst{83} = MEGA_FETCH;
1794 // Inst{84} = ALT_CONST;
1795 // Inst{86-85} = BUFFER_INDEX_MODE;
1796 // Inst{95-86} = 0; Reserved
1797
1798 // VTX_WORD3 (Padding)
1799 //
1800 // Inst{127-96} = 0;
Vincent Lejeune631591e2013-04-30 00:13:39 +00001801
1802 let VTXInst = 1;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001803}
1804
1805class VTX_READ_8_eg <bits<8> buffer_id, list<dag> pattern>
1806 : VTX_READ_eg <"VTX_READ_8", buffer_id, (outs R600_TReg32_X:$dst),
1807 pattern> {
1808
1809 let MEGA_FETCH_COUNT = 1;
1810 let DST_SEL_X = 0;
1811 let DST_SEL_Y = 7; // Masked
1812 let DST_SEL_Z = 7; // Masked
1813 let DST_SEL_W = 7; // Masked
1814 let DATA_FORMAT = 1; // FMT_8
1815}
1816
1817class VTX_READ_16_eg <bits<8> buffer_id, list<dag> pattern>
1818 : VTX_READ_eg <"VTX_READ_16", buffer_id, (outs R600_TReg32_X:$dst),
1819 pattern> {
1820 let MEGA_FETCH_COUNT = 2;
1821 let DST_SEL_X = 0;
1822 let DST_SEL_Y = 7; // Masked
1823 let DST_SEL_Z = 7; // Masked
1824 let DST_SEL_W = 7; // Masked
1825 let DATA_FORMAT = 5; // FMT_16
1826
1827}
1828
1829class VTX_READ_32_eg <bits<8> buffer_id, list<dag> pattern>
1830 : VTX_READ_eg <"VTX_READ_32", buffer_id, (outs R600_TReg32_X:$dst),
1831 pattern> {
1832
1833 let MEGA_FETCH_COUNT = 4;
1834 let DST_SEL_X = 0;
1835 let DST_SEL_Y = 7; // Masked
1836 let DST_SEL_Z = 7; // Masked
1837 let DST_SEL_W = 7; // Masked
1838 let DATA_FORMAT = 0xD; // COLOR_32
1839
1840 // This is not really necessary, but there were some GPU hangs that appeared
1841 // to be caused by ALU instructions in the next instruction group that wrote
Vincent Lejeunea311c5262013-02-10 17:57:33 +00001842 // to the $ptr registers of the VTX_READ.
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001843 // e.g.
1844 // %T3_X<def> = VTX_READ_PARAM_32_eg %T2_X<kill>, 24
1845 // %T2_X<def> = MOV %ZERO
1846 //Adding this constraint prevents this from happening.
1847 let Constraints = "$ptr.ptr = $dst";
1848}
1849
1850class VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern>
1851 : VTX_READ_eg <"VTX_READ_128", buffer_id, (outs R600_Reg128:$dst),
1852 pattern> {
1853
1854 let MEGA_FETCH_COUNT = 16;
1855 let DST_SEL_X = 0;
1856 let DST_SEL_Y = 1;
1857 let DST_SEL_Z = 2;
1858 let DST_SEL_W = 3;
1859 let DATA_FORMAT = 0x22; // COLOR_32_32_32_32
1860
1861 // XXX: Need to force VTX_READ_128 instructions to write to the same register
1862 // that holds its buffer address to avoid potential hangs. We can't use
1863 // the same constraint as VTX_READ_32_eg, because the $ptr.ptr and $dst
1864 // registers are different sizes.
1865}
1866
1867//===----------------------------------------------------------------------===//
1868// VTX Read from parameter memory space
1869//===----------------------------------------------------------------------===//
1870
1871def VTX_READ_PARAM_8_eg : VTX_READ_8_eg <0,
1872 [(set (i32 R600_TReg32_X:$dst), (load_param_zexti8 ADDRVTX_READ:$ptr))]
1873>;
1874
1875def VTX_READ_PARAM_16_eg : VTX_READ_16_eg <0,
1876 [(set (i32 R600_TReg32_X:$dst), (load_param_zexti16 ADDRVTX_READ:$ptr))]
1877>;
1878
1879def VTX_READ_PARAM_32_eg : VTX_READ_32_eg <0,
1880 [(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))]
1881>;
1882
Tom Stellard76308d82013-02-13 22:05:20 +00001883def VTX_READ_PARAM_128_eg : VTX_READ_128_eg <0,
1884 [(set (v4i32 R600_Reg128:$dst), (load_param ADDRVTX_READ:$ptr))]
1885>;
1886
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001887//===----------------------------------------------------------------------===//
1888// VTX Read from global memory space
1889//===----------------------------------------------------------------------===//
1890
1891// 8-bit reads
1892def VTX_READ_GLOBAL_8_eg : VTX_READ_8_eg <1,
1893 [(set (i32 R600_TReg32_X:$dst), (zextloadi8_global ADDRVTX_READ:$ptr))]
1894>;
1895
1896// 32-bit reads
1897def VTX_READ_GLOBAL_32_eg : VTX_READ_32_eg <1,
1898 [(set (i32 R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))]
1899>;
1900
1901// 128-bit reads
1902def VTX_READ_GLOBAL_128_eg : VTX_READ_128_eg <1,
1903 [(set (v4i32 R600_Reg128:$dst), (global_load ADDRVTX_READ:$ptr))]
1904>;
1905
1906//===----------------------------------------------------------------------===//
1907// Constant Loads
1908// XXX: We are currently storing all constants in the global address space.
1909//===----------------------------------------------------------------------===//
1910
1911def CONSTANT_LOAD_eg : VTX_READ_32_eg <1,
1912 [(set (i32 R600_TReg32_X:$dst), (constant_load ADDRVTX_READ:$ptr))]
1913>;
1914
1915}
1916
Tom Stellardc0b0c672013-02-06 17:32:29 +00001917//===----------------------------------------------------------------------===//
1918// Regist loads and stores - for indirect addressing
1919//===----------------------------------------------------------------------===//
1920
1921defm R600_ : RegisterLoadStore <R600_Reg32, FRAMEri, ADDRIndirect>;
1922
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001923let Predicates = [isCayman] in {
1924
Vincent Lejeunea311c5262013-02-10 17:57:33 +00001925let isVector = 1 in {
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001926
1927def RECIP_IEEE_cm : RECIP_IEEE_Common<0x86>;
1928
1929def MULLO_INT_cm : MULLO_INT_Common<0x8F>;
1930def MULHI_INT_cm : MULHI_INT_Common<0x90>;
1931def MULLO_UINT_cm : MULLO_UINT_Common<0x91>;
1932def MULHI_UINT_cm : MULHI_UINT_Common<0x92>;
1933def RECIPSQRT_CLAMPED_cm : RECIPSQRT_CLAMPED_Common<0x87>;
1934def EXP_IEEE_cm : EXP_IEEE_Common<0x81>;
Michel Danzerc446baa2013-03-22 14:09:10 +00001935def LOG_IEEE_cm : LOG_IEEE_Common<0x83>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001936def RECIP_CLAMPED_cm : RECIP_CLAMPED_Common<0x84>;
1937def RECIPSQRT_IEEE_cm : RECIPSQRT_IEEE_Common<0x89>;
1938def SIN_cm : SIN_Common<0x8D>;
1939def COS_cm : COS_Common<0x8E>;
1940} // End isVector = 1
1941
Michel Danzerc446baa2013-03-22 14:09:10 +00001942def : POW_Common <LOG_IEEE_cm, EXP_IEEE_cm, MUL, R600_Reg32>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001943def : SIN_PAT <SIN_cm>;
1944def : COS_PAT <COS_cm>;
1945
1946defm DIV_cm : DIV_Common<RECIP_IEEE_cm>;
1947
1948// RECIP_UINT emulation for Cayman
Michel Danzerb187f8c2013-04-10 17:17:56 +00001949// The multiplication scales from [0,1] to the unsigned integer range
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001950def : Pat <
1951 (AMDGPUurecip R600_Reg32:$src0),
1952 (FLT_TO_UINT_eg (MUL_IEEE (RECIP_IEEE_cm (UINT_TO_FLT_eg R600_Reg32:$src0)),
Michel Danzerb187f8c2013-04-10 17:17:56 +00001953 (MOV_IMM_I32 CONST.FP_UINT_MAX_PLUS_1)))
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001954>;
1955
Vincent Lejeune7a28d8a2013-04-23 17:34:00 +00001956 def CF_END_CM : CF_CLAUSE_EG<32, (ins), "CF_END"> {
1957 let ADDR = 0;
1958 let POP_COUNT = 0;
1959 let COUNT = 0;
1960 }
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001961
1962def : Pat<(fsqrt R600_Reg32:$src),
1963 (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_cm R600_Reg32:$src))>;
1964
1965} // End isCayman
1966
1967//===----------------------------------------------------------------------===//
1968// Branch Instructions
1969//===----------------------------------------------------------------------===//
1970
1971
1972def IF_PREDICATE_SET : ILFormat<(outs), (ins GPRI32:$src),
1973 "IF_PREDICATE_SET $src", []>;
1974
1975def PREDICATED_BREAK : ILFormat<(outs), (ins GPRI32:$src),
1976 "PREDICATED_BREAK $src", []>;
1977
1978//===----------------------------------------------------------------------===//
1979// Pseudo instructions
1980//===----------------------------------------------------------------------===//
1981
1982let isPseudo = 1 in {
1983
1984def PRED_X : InstR600 <
Vincent Lejeune8723c9e2013-04-30 00:13:20 +00001985 (outs R600_Predicate_Bit:$dst),
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001986 (ins R600_Reg32:$src0, i32imm:$src1, i32imm:$flags),
1987 "", [], NullALU> {
1988 let FlagOperandIdx = 3;
1989}
1990
Vincent Lejeunefd49dac2013-03-11 18:15:06 +00001991let isTerminator = 1, isBranch = 1 in {
Vincent Lejeune8723c9e2013-04-30 00:13:20 +00001992def JUMP_COND : InstR600 <
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001993 (outs),
Vincent Lejeunefd49dac2013-03-11 18:15:06 +00001994 (ins brtarget:$target, R600_Predicate_Bit:$p),
Tom Stellardf98f2ce2012-12-11 21:25:42 +00001995 "JUMP $target ($p)",
1996 [], AnyALU
1997 >;
1998
Vincent Lejeune8723c9e2013-04-30 00:13:20 +00001999def JUMP : InstR600 <
Vincent Lejeunefd49dac2013-03-11 18:15:06 +00002000 (outs),
2001 (ins brtarget:$target),
2002 "JUMP $target",
2003 [], AnyALU
2004 >
2005{
2006 let isPredicable = 1;
2007 let isBarrier = 1;
2008}
2009
2010} // End isTerminator = 1, isBranch = 1
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002011
2012let usesCustomInserter = 1 in {
2013
2014let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in {
2015
2016def MASK_WRITE : AMDGPUShaderInst <
2017 (outs),
2018 (ins R600_Reg32:$src),
2019 "MASK_WRITE $src",
2020 []
2021>;
2022
2023} // End mayLoad = 0, mayStore = 0, hasSideEffects = 1
2024
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002025
Vincent Lejeune8723c9e2013-04-30 00:13:20 +00002026def TXD: InstR600 <
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002027 (outs R600_Reg128:$dst),
2028 (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
2029 "TXD $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget",
Vincent Lejeune8723c9e2013-04-30 00:13:20 +00002030 [(set R600_Reg128:$dst, (int_AMDGPU_txd R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, imm:$resourceId, imm:$samplerId, imm:$textureTarget))], NullALU> {
Vincent Lejeune631591e2013-04-30 00:13:39 +00002031 let TEXInst = 1;
2032}
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002033
Vincent Lejeune8723c9e2013-04-30 00:13:20 +00002034def TXD_SHADOW: InstR600 <
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002035 (outs R600_Reg128:$dst),
2036 (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
2037 "TXD_SHADOW $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget",
Vincent Lejeune8723c9e2013-04-30 00:13:20 +00002038 [(set R600_Reg128:$dst, (int_AMDGPU_txd R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, imm:$resourceId, imm:$samplerId, TEX_SHADOW:$textureTarget))], NullALU
Vincent Lejeune631591e2013-04-30 00:13:39 +00002039> {
2040 let TEXInst = 1;
2041}
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002042} // End isPseudo = 1
2043} // End usesCustomInserter = 1
2044
2045def CLAMP_R600 : CLAMP <R600_Reg32>;
2046def FABS_R600 : FABS<R600_Reg32>;
2047def FNEG_R600 : FNEG<R600_Reg32>;
2048
2049//===---------------------------------------------------------------------===//
2050// Return instruction
2051//===---------------------------------------------------------------------===//
Vincent Lejeunefd49dac2013-03-11 18:15:06 +00002052let isTerminator = 1, isReturn = 1, hasCtrlDep = 1,
Jakob Stoklund Olesena499d2b2013-02-05 17:53:52 +00002053 usesCustomInserter = 1 in {
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002054 def RETURN : ILFormat<(outs), (ins variable_ops),
2055 "RETURN", [(IL_retflag)]>;
2056}
2057
Tom Stellard9f7818d2013-01-23 02:09:06 +00002058
2059//===----------------------------------------------------------------------===//
2060// Constant Buffer Addressing Support
2061//===----------------------------------------------------------------------===//
2062
Vincent Lejeuned4c3e562013-03-05 15:04:55 +00002063let usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU" in {
Tom Stellard9f7818d2013-01-23 02:09:06 +00002064def CONST_COPY : Instruction {
2065 let OutOperandList = (outs R600_Reg32:$dst);
2066 let InOperandList = (ins i32imm:$src);
Vincent Lejeuned4c3e562013-03-05 15:04:55 +00002067 let Pattern =
2068 [(set R600_Reg32:$dst, (CONST_ADDRESS ADDRGA_CONST_OFFSET:$src))];
Tom Stellard9f7818d2013-01-23 02:09:06 +00002069 let AsmString = "CONST_COPY";
2070 let neverHasSideEffects = 1;
2071 let isAsCheapAsAMove = 1;
2072 let Itinerary = NullALU;
2073}
Vincent Lejeuned4c3e562013-03-05 15:04:55 +00002074} // end usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU"
Tom Stellard9f7818d2013-01-23 02:09:06 +00002075
2076def TEX_VTX_CONSTBUF :
Vincent Lejeune3f7f8e82013-03-05 15:04:29 +00002077 InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr, i32imm:$BUFFER_ID), "VTX_READ_eg $dst, $ptr",
2078 [(set R600_Reg128:$dst, (CONST_ADDRESS ADDRGA_VAR_OFFSET:$ptr, (i32 imm:$BUFFER_ID)))]>,
Tom Stellard9f7818d2013-01-23 02:09:06 +00002079 VTX_WORD1_GPR, VTX_WORD0 {
2080
2081 let VC_INST = 0;
2082 let FETCH_TYPE = 2;
2083 let FETCH_WHOLE_QUAD = 0;
Tom Stellard9f7818d2013-01-23 02:09:06 +00002084 let SRC_REL = 0;
2085 let SRC_SEL_X = 0;
2086 let DST_REL = 0;
2087 let USE_CONST_FIELDS = 0;
2088 let NUM_FORMAT_ALL = 2;
2089 let FORMAT_COMP_ALL = 1;
2090 let SRF_MODE_ALL = 1;
2091 let MEGA_FETCH_COUNT = 16;
2092 let DST_SEL_X = 0;
2093 let DST_SEL_Y = 1;
2094 let DST_SEL_Z = 2;
2095 let DST_SEL_W = 3;
2096 let DATA_FORMAT = 35;
2097
2098 let Inst{31-0} = Word0;
2099 let Inst{63-32} = Word1;
2100
2101// LLVM can only encode 64-bit instructions, so these fields are manually
2102// encoded in R600CodeEmitter
2103//
2104// bits<16> OFFSET;
2105// bits<2> ENDIAN_SWAP = 0;
2106// bits<1> CONST_BUF_NO_STRIDE = 0;
2107// bits<1> MEGA_FETCH = 0;
2108// bits<1> ALT_CONST = 0;
2109// bits<2> BUFFER_INDEX_MODE = 0;
2110
2111
2112
2113// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
2114// is done in R600CodeEmitter
2115//
2116// Inst{79-64} = OFFSET;
2117// Inst{81-80} = ENDIAN_SWAP;
2118// Inst{82} = CONST_BUF_NO_STRIDE;
2119// Inst{83} = MEGA_FETCH;
2120// Inst{84} = ALT_CONST;
2121// Inst{86-85} = BUFFER_INDEX_MODE;
2122// Inst{95-86} = 0; Reserved
2123
2124// VTX_WORD3 (Padding)
2125//
2126// Inst{127-96} = 0;
Vincent Lejeune631591e2013-04-30 00:13:39 +00002127 let VTXInst = 1;
Tom Stellard9f7818d2013-01-23 02:09:06 +00002128}
2129
Vincent Lejeunebbbef492013-02-18 14:11:19 +00002130def TEX_VTX_TEXBUF:
2131 InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr, i32imm:$BUFFER_ID), "TEX_VTX_EXPLICIT_READ $dst, $ptr",
2132 [(set R600_Reg128:$dst, (int_R600_load_texbuf ADDRGA_VAR_OFFSET:$ptr, imm:$BUFFER_ID))]>,
2133VTX_WORD1_GPR, VTX_WORD0 {
2134
2135let VC_INST = 0;
2136let FETCH_TYPE = 2;
2137let FETCH_WHOLE_QUAD = 0;
2138let SRC_REL = 0;
2139let SRC_SEL_X = 0;
2140let DST_REL = 0;
2141let USE_CONST_FIELDS = 1;
2142let NUM_FORMAT_ALL = 0;
2143let FORMAT_COMP_ALL = 0;
2144let SRF_MODE_ALL = 1;
2145let MEGA_FETCH_COUNT = 16;
2146let DST_SEL_X = 0;
2147let DST_SEL_Y = 1;
2148let DST_SEL_Z = 2;
2149let DST_SEL_W = 3;
2150let DATA_FORMAT = 0;
2151
2152let Inst{31-0} = Word0;
2153let Inst{63-32} = Word1;
2154
2155// LLVM can only encode 64-bit instructions, so these fields are manually
2156// encoded in R600CodeEmitter
2157//
2158// bits<16> OFFSET;
2159// bits<2> ENDIAN_SWAP = 0;
2160// bits<1> CONST_BUF_NO_STRIDE = 0;
2161// bits<1> MEGA_FETCH = 0;
2162// bits<1> ALT_CONST = 0;
2163// bits<2> BUFFER_INDEX_MODE = 0;
2164
2165
2166
2167// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
2168// is done in R600CodeEmitter
2169//
2170// Inst{79-64} = OFFSET;
2171// Inst{81-80} = ENDIAN_SWAP;
2172// Inst{82} = CONST_BUF_NO_STRIDE;
2173// Inst{83} = MEGA_FETCH;
2174// Inst{84} = ALT_CONST;
2175// Inst{86-85} = BUFFER_INDEX_MODE;
2176// Inst{95-86} = 0; Reserved
2177
2178// VTX_WORD3 (Padding)
2179//
2180// Inst{127-96} = 0;
Vincent Lejeune631591e2013-04-30 00:13:39 +00002181 let VTXInst = 1;
Vincent Lejeunebbbef492013-02-18 14:11:19 +00002182}
2183
2184
Tom Stellard9f7818d2013-01-23 02:09:06 +00002185
Tom Stellard6b7d99d2012-12-19 22:10:31 +00002186//===--------------------------------------------------------------------===//
2187// Instructions support
2188//===--------------------------------------------------------------------===//
2189//===---------------------------------------------------------------------===//
2190// Custom Inserter for Branches and returns, this eventually will be a
2191// seperate pass
2192//===---------------------------------------------------------------------===//
2193let isTerminator = 1, usesCustomInserter = 1, isBranch = 1, isBarrier = 1 in {
2194 def BRANCH : ILFormat<(outs), (ins brtarget:$target),
2195 "; Pseudo unconditional branch instruction",
2196 [(br bb:$target)]>;
2197 defm BRANCH_COND : BranchConditional<IL_brcond>;
2198}
2199
2200//===---------------------------------------------------------------------===//
2201// Flow and Program control Instructions
2202//===---------------------------------------------------------------------===//
2203let isTerminator=1 in {
2204 def SWITCH : ILFormat< (outs), (ins GPRI32:$src),
2205 !strconcat("SWITCH", " $src"), []>;
2206 def CASE : ILFormat< (outs), (ins GPRI32:$src),
2207 !strconcat("CASE", " $src"), []>;
2208 def BREAK : ILFormat< (outs), (ins),
2209 "BREAK", []>;
2210 def CONTINUE : ILFormat< (outs), (ins),
2211 "CONTINUE", []>;
2212 def DEFAULT : ILFormat< (outs), (ins),
2213 "DEFAULT", []>;
2214 def ELSE : ILFormat< (outs), (ins),
2215 "ELSE", []>;
2216 def ENDSWITCH : ILFormat< (outs), (ins),
2217 "ENDSWITCH", []>;
2218 def ENDMAIN : ILFormat< (outs), (ins),
2219 "ENDMAIN", []>;
2220 def END : ILFormat< (outs), (ins),
2221 "END", []>;
2222 def ENDFUNC : ILFormat< (outs), (ins),
2223 "ENDFUNC", []>;
2224 def ENDIF : ILFormat< (outs), (ins),
2225 "ENDIF", []>;
2226 def WHILELOOP : ILFormat< (outs), (ins),
2227 "WHILE", []>;
2228 def ENDLOOP : ILFormat< (outs), (ins),
2229 "ENDLOOP", []>;
2230 def FUNC : ILFormat< (outs), (ins),
2231 "FUNC", []>;
2232 def RETDYN : ILFormat< (outs), (ins),
2233 "RET_DYN", []>;
2234 // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2235 defm IF_LOGICALNZ : BranchInstr<"IF_LOGICALNZ">;
2236 // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2237 defm IF_LOGICALZ : BranchInstr<"IF_LOGICALZ">;
2238 // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2239 defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">;
2240 // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2241 defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">;
2242 // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2243 defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">;
2244 // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2245 defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">;
2246 defm IFC : BranchInstr2<"IFC">;
2247 defm BREAKC : BranchInstr2<"BREAKC">;
2248 defm CONTINUEC : BranchInstr2<"CONTINUEC">;
2249}
2250
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002251//===----------------------------------------------------------------------===//
2252// ISel Patterns
2253//===----------------------------------------------------------------------===//
2254
Tom Stellard1454cb82013-03-08 15:37:09 +00002255// CND*_INT Pattterns for f32 True / False values
2256
2257class CND_INT_f32 <InstR600 cnd, CondCode cc> : Pat <
2258 (selectcc (i32 R600_Reg32:$src0), 0, (f32 R600_Reg32:$src1),
2259 R600_Reg32:$src2, cc),
2260 (cnd R600_Reg32:$src0, R600_Reg32:$src1, R600_Reg32:$src2)
2261>;
2262
2263def : CND_INT_f32 <CNDE_INT, SETEQ>;
2264def : CND_INT_f32 <CNDGT_INT, SETGT>;
2265def : CND_INT_f32 <CNDGE_INT, SETGE>;
2266
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002267//CNDGE_INT extra pattern
2268def : Pat <
2269 (selectcc (i32 R600_Reg32:$src0), -1, (i32 R600_Reg32:$src1),
2270 (i32 R600_Reg32:$src2), COND_GT),
2271 (CNDGE_INT R600_Reg32:$src0, R600_Reg32:$src1, R600_Reg32:$src2)
2272>;
2273
2274// KIL Patterns
2275def KILP : Pat <
2276 (int_AMDGPU_kilp),
2277 (MASK_WRITE (KILLGT (f32 ONE), (f32 ZERO)))
2278>;
2279
2280def KIL : Pat <
2281 (int_AMDGPU_kill R600_Reg32:$src0),
2282 (MASK_WRITE (KILLGT (f32 ZERO), (f32 R600_Reg32:$src0)))
2283>;
2284
2285// SGT Reverse args
2286def : Pat <
2287 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, COND_LT),
2288 (SGT R600_Reg32:$src1, R600_Reg32:$src0)
2289>;
2290
2291// SGE Reverse args
2292def : Pat <
2293 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, COND_LE),
Vincent Lejeunea311c5262013-02-10 17:57:33 +00002294 (SGE R600_Reg32:$src1, R600_Reg32:$src0)
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002295>;
2296
Tom Stellard1234c9b2013-02-07 14:02:35 +00002297// SETGT_DX10 reverse args
2298def : Pat <
2299 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, COND_LT),
2300 (SETGT_DX10 R600_Reg32:$src1, R600_Reg32:$src0)
2301>;
2302
2303// SETGE_DX10 reverse args
2304def : Pat <
2305 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, COND_LE),
2306 (SETGE_DX10 R600_Reg32:$src1, R600_Reg32:$src0)
2307>;
2308
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002309// SETGT_INT reverse args
2310def : Pat <
2311 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETLT),
2312 (SETGT_INT R600_Reg32:$src1, R600_Reg32:$src0)
2313>;
2314
2315// SETGE_INT reverse args
2316def : Pat <
2317 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETLE),
2318 (SETGE_INT R600_Reg32:$src1, R600_Reg32:$src0)
2319>;
2320
2321// SETGT_UINT reverse args
2322def : Pat <
2323 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETULT),
2324 (SETGT_UINT R600_Reg32:$src1, R600_Reg32:$src0)
2325>;
2326
2327// SETGE_UINT reverse args
2328def : Pat <
2329 (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETULE),
2330 (SETGE_UINT R600_Reg32:$src1, R600_Reg32:$src0)
2331>;
2332
2333// The next two patterns are special cases for handling 'true if ordered' and
2334// 'true if unordered' conditionals. The assumption here is that the behavior of
2335// SETE and SNE conforms to the Direct3D 10 rules for floating point values
2336// described here:
2337// http://msdn.microsoft.com/en-us/library/windows/desktop/cc308050.aspx#alpha_32_bit
2338// We assume that SETE returns false when one of the operands is NAN and
2339// SNE returns true when on of the operands is NAN
2340
2341//SETE - 'true if ordered'
2342def : Pat <
2343 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, SETO),
2344 (SETE R600_Reg32:$src0, R600_Reg32:$src1)
2345>;
2346
Tom Stellard1234c9b2013-02-07 14:02:35 +00002347//SETE_DX10 - 'true if ordered'
2348def : Pat <
2349 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETO),
2350 (SETE_DX10 R600_Reg32:$src0, R600_Reg32:$src1)
2351>;
2352
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002353//SNE - 'true if unordered'
2354def : Pat <
2355 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, SETUO),
2356 (SNE R600_Reg32:$src0, R600_Reg32:$src1)
2357>;
2358
Tom Stellard1234c9b2013-02-07 14:02:35 +00002359//SETNE_DX10 - 'true if ordered'
2360def : Pat <
2361 (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUO),
2362 (SETNE_DX10 R600_Reg32:$src0, R600_Reg32:$src1)
2363>;
2364
Tom Stellard07b59ba2013-02-07 14:02:37 +00002365def : Extract_Element <f32, v4f32, R600_Reg128, 0, sub0>;
2366def : Extract_Element <f32, v4f32, R600_Reg128, 1, sub1>;
2367def : Extract_Element <f32, v4f32, R600_Reg128, 2, sub2>;
2368def : Extract_Element <f32, v4f32, R600_Reg128, 3, sub3>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002369
Tom Stellard07b59ba2013-02-07 14:02:37 +00002370def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 0, sub0>;
2371def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 1, sub1>;
2372def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 2, sub2>;
2373def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 3, sub3>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002374
Tom Stellard07b59ba2013-02-07 14:02:37 +00002375def : Extract_Element <i32, v4i32, R600_Reg128, 0, sub0>;
2376def : Extract_Element <i32, v4i32, R600_Reg128, 1, sub1>;
2377def : Extract_Element <i32, v4i32, R600_Reg128, 2, sub2>;
2378def : Extract_Element <i32, v4i32, R600_Reg128, 3, sub3>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002379
Tom Stellard07b59ba2013-02-07 14:02:37 +00002380def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 0, sub0>;
2381def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 1, sub1>;
2382def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 2, sub2>;
2383def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 3, sub3>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002384
Christian Konig2d7f19e2013-03-18 11:34:10 +00002385def : Vector4_Build <v4f32, R600_Reg128, f32, R600_Reg32>;
2386def : Vector4_Build <v4i32, R600_Reg128, i32, R600_Reg32>;
Tom Stellardf98f2ce2012-12-11 21:25:42 +00002387
2388// bitconvert patterns
2389
2390def : BitConvert <i32, f32, R600_Reg32>;
2391def : BitConvert <f32, i32, R600_Reg32>;
2392def : BitConvert <v4f32, v4i32, R600_Reg128>;
2393def : BitConvert <v4i32, v4f32, R600_Reg128>;
2394
2395// DWORDADDR pattern
2396def : DwordAddrPat <i32, R600_Reg32>;
2397
2398} // End isR600toCayman Predicate