R600Instructions.td revision 249259
1249259Sdim//===-- R600Instructions.td - R600 Instruction defs  -------*- tablegen -*-===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim// R600 Tablegen instruction definitions
11249259Sdim//
12249259Sdim//===----------------------------------------------------------------------===//
13249259Sdim
14249259Sdiminclude "R600Intrinsics.td"
15249259Sdim
16249259Sdimclass InstR600 <bits<11> inst, dag outs, dag ins, string asm, list<dag> pattern,
17249259Sdim                InstrItinClass itin>
18249259Sdim    : AMDGPUInst <outs, ins, asm, pattern> {
19249259Sdim
20249259Sdim  field bits<64> Inst;
21249259Sdim  bit Trig = 0;
22249259Sdim  bit Op3 = 0;
23249259Sdim  bit isVector = 0;
24249259Sdim  bits<2> FlagOperandIdx = 0;
25249259Sdim  bit Op1 = 0;
26249259Sdim  bit Op2 = 0;
27249259Sdim  bit HasNativeOperands = 0;
28249259Sdim
29249259Sdim  bits<11> op_code = inst;
30249259Sdim  //let Inst = inst;
31249259Sdim  let Namespace = "AMDGPU";
32249259Sdim  let OutOperandList = outs;
33249259Sdim  let InOperandList = ins;
34249259Sdim  let AsmString = asm;
35249259Sdim  let Pattern = pattern;
36249259Sdim  let Itinerary = itin;
37249259Sdim
38249259Sdim  let TSFlags{4} = Trig;
39249259Sdim  let TSFlags{5} = Op3;
40249259Sdim
41249259Sdim  // Vector instructions are instructions that must fill all slots in an
42249259Sdim  // instruction group
43249259Sdim  let TSFlags{6} = isVector;
44249259Sdim  let TSFlags{8-7} = FlagOperandIdx;
45249259Sdim  let TSFlags{9} = HasNativeOperands;
46249259Sdim  let TSFlags{10} = Op1;
47249259Sdim  let TSFlags{11} = Op2;
48249259Sdim}
49249259Sdim
50249259Sdimclass InstR600ISA <dag outs, dag ins, string asm, list<dag> pattern> :
51249259Sdim    AMDGPUInst <outs, ins, asm, pattern> {
52249259Sdim  field bits<64> Inst;
53249259Sdim
54249259Sdim  let Namespace = "AMDGPU";
55249259Sdim}
56249259Sdim
57249259Sdimdef MEMxi : Operand<iPTR> {
58249259Sdim  let MIOperandInfo = (ops R600_TReg32_X:$ptr, i32imm:$index);
59249259Sdim  let PrintMethod = "printMemOperand";
60249259Sdim}
61249259Sdim
62249259Sdimdef MEMrr : Operand<iPTR> {
63249259Sdim  let MIOperandInfo = (ops R600_Reg32:$ptr, R600_Reg32:$index);
64249259Sdim}
65249259Sdim
66249259Sdim// Operands for non-registers
67249259Sdim
68249259Sdimclass InstFlag<string PM = "printOperand", int Default = 0>
69249259Sdim    : OperandWithDefaultOps <i32, (ops (i32 Default))> {
70249259Sdim  let PrintMethod = PM;
71249259Sdim}
72249259Sdim
73249259Sdim// src_sel for ALU src operands, see also ALU_CONST, ALU_PARAM registers
74249259Sdimdef SEL : OperandWithDefaultOps <i32, (ops (i32 -1))> {
75249259Sdim  let PrintMethod = "printSel";
76249259Sdim}
77249259Sdim
78249259Sdimdef LITERAL : InstFlag<"printLiteral">;
79249259Sdim
80249259Sdimdef WRITE : InstFlag <"printWrite", 1>;
81249259Sdimdef OMOD : InstFlag <"printOMOD">;
82249259Sdimdef REL : InstFlag <"printRel">;
83249259Sdimdef CLAMP : InstFlag <"printClamp">;
84249259Sdimdef NEG : InstFlag <"printNeg">;
85249259Sdimdef ABS : InstFlag <"printAbs">;
86249259Sdimdef UEM : InstFlag <"printUpdateExecMask">;
87249259Sdimdef UP : InstFlag <"printUpdatePred">;
88249259Sdim
89249259Sdim// XXX: The r600g finalizer in Mesa expects last to be one in most cases.
90249259Sdim// Once we start using the packetizer in this backend we should have this
91249259Sdim// default to 0.
92249259Sdimdef LAST : InstFlag<"printLast", 1>;
93249259Sdim
94249259Sdimdef FRAMEri : Operand<iPTR> {
95249259Sdim  let MIOperandInfo = (ops R600_Reg32:$ptr, i32imm:$index);
96249259Sdim}
97249259Sdim
98249259Sdimdef ADDRParam : ComplexPattern<i32, 2, "SelectADDRParam", [], []>;
99249259Sdimdef ADDRDWord : ComplexPattern<i32, 1, "SelectADDRDWord", [], []>;
100249259Sdimdef ADDRVTX_READ : ComplexPattern<i32, 2, "SelectADDRVTX_READ", [], []>;
101249259Sdimdef ADDRGA_CONST_OFFSET : ComplexPattern<i32, 1, "SelectGlobalValueConstantOffset", [], []>;
102249259Sdimdef ADDRGA_VAR_OFFSET : ComplexPattern<i32, 2, "SelectGlobalValueVariableOffset", [], []>;
103249259Sdimdef ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>;
104249259Sdim
105249259Sdimclass R600ALU_Word0 {
106249259Sdim  field bits<32> Word0;
107249259Sdim
108249259Sdim  bits<11> src0;
109249259Sdim  bits<1>  src0_neg;
110249259Sdim  bits<1>  src0_rel;
111249259Sdim  bits<11> src1;
112249259Sdim  bits<1>  src1_rel;
113249259Sdim  bits<1>  src1_neg;
114249259Sdim  bits<3>  index_mode = 0;
115249259Sdim  bits<2>  pred_sel;
116249259Sdim  bits<1>  last;
117249259Sdim
118249259Sdim  bits<9>  src0_sel  = src0{8-0};
119249259Sdim  bits<2>  src0_chan = src0{10-9};
120249259Sdim  bits<9>  src1_sel  = src1{8-0};
121249259Sdim  bits<2>  src1_chan = src1{10-9};
122249259Sdim
123249259Sdim  let Word0{8-0}   = src0_sel;
124249259Sdim  let Word0{9}     = src0_rel;
125249259Sdim  let Word0{11-10} = src0_chan;
126249259Sdim  let Word0{12}    = src0_neg;
127249259Sdim  let Word0{21-13} = src1_sel;
128249259Sdim  let Word0{22}    = src1_rel;
129249259Sdim  let Word0{24-23} = src1_chan;
130249259Sdim  let Word0{25}    = src1_neg;
131249259Sdim  let Word0{28-26} = index_mode;
132249259Sdim  let Word0{30-29} = pred_sel;
133249259Sdim  let Word0{31}    = last;
134249259Sdim}
135249259Sdim
136249259Sdimclass R600ALU_Word1 {
137249259Sdim  field bits<32> Word1;
138249259Sdim
139249259Sdim  bits<11> dst;
140249259Sdim  bits<3>  bank_swizzle = 0;
141249259Sdim  bits<1>  dst_rel;
142249259Sdim  bits<1>  clamp;
143249259Sdim
144249259Sdim  bits<7>  dst_sel  = dst{6-0};
145249259Sdim  bits<2>  dst_chan = dst{10-9};
146249259Sdim
147249259Sdim  let Word1{20-18} = bank_swizzle;
148249259Sdim  let Word1{27-21} = dst_sel;
149249259Sdim  let Word1{28}    = dst_rel;
150249259Sdim  let Word1{30-29} = dst_chan;
151249259Sdim  let Word1{31}    = clamp;
152249259Sdim}
153249259Sdim
154249259Sdimclass R600ALU_Word1_OP2 <bits<11> alu_inst> : R600ALU_Word1{
155249259Sdim
156249259Sdim  bits<1>  src0_abs;
157249259Sdim  bits<1>  src1_abs;
158249259Sdim  bits<1>  update_exec_mask;
159249259Sdim  bits<1>  update_pred;
160249259Sdim  bits<1>  write;
161249259Sdim  bits<2>  omod;
162249259Sdim
163249259Sdim  let Word1{0}     = src0_abs;
164249259Sdim  let Word1{1}     = src1_abs;
165249259Sdim  let Word1{2}     = update_exec_mask;
166249259Sdim  let Word1{3}     = update_pred;
167249259Sdim  let Word1{4}     = write;
168249259Sdim  let Word1{6-5}   = omod;
169249259Sdim  let Word1{17-7}  = alu_inst;
170249259Sdim}
171249259Sdim
172249259Sdimclass R600ALU_Word1_OP3 <bits<5> alu_inst> : R600ALU_Word1{
173249259Sdim
174249259Sdim  bits<11> src2;
175249259Sdim  bits<1>  src2_rel;
176249259Sdim  bits<1>  src2_neg;
177249259Sdim
178249259Sdim  bits<9>  src2_sel = src2{8-0};
179249259Sdim  bits<2>  src2_chan = src2{10-9};
180249259Sdim
181249259Sdim  let Word1{8-0}   = src2_sel;
182249259Sdim  let Word1{9}     = src2_rel;
183249259Sdim  let Word1{11-10} = src2_chan;
184249259Sdim  let Word1{12}    = src2_neg;
185249259Sdim  let Word1{17-13} = alu_inst;
186249259Sdim}
187249259Sdim
188249259Sdimclass VTX_WORD0 {
189249259Sdim  field bits<32> Word0;
190249259Sdim  bits<7> SRC_GPR;
191249259Sdim  bits<5> VC_INST;
192249259Sdim  bits<2> FETCH_TYPE;
193249259Sdim  bits<1> FETCH_WHOLE_QUAD;
194249259Sdim  bits<8> BUFFER_ID;
195249259Sdim  bits<1> SRC_REL;
196249259Sdim  bits<2> SRC_SEL_X;
197249259Sdim  bits<6> MEGA_FETCH_COUNT;
198249259Sdim
199249259Sdim  let Word0{4-0}   = VC_INST;
200249259Sdim  let Word0{6-5}   = FETCH_TYPE;
201249259Sdim  let Word0{7}     = FETCH_WHOLE_QUAD;
202249259Sdim  let Word0{15-8}  = BUFFER_ID;
203249259Sdim  let Word0{22-16} = SRC_GPR;
204249259Sdim  let Word0{23}    = SRC_REL;
205249259Sdim  let Word0{25-24} = SRC_SEL_X;
206249259Sdim  let Word0{31-26} = MEGA_FETCH_COUNT;
207249259Sdim}
208249259Sdim
209249259Sdimclass VTX_WORD1_GPR {
210249259Sdim  field bits<32> Word1;
211249259Sdim  bits<7> DST_GPR;
212249259Sdim  bits<1> DST_REL;
213249259Sdim  bits<3> DST_SEL_X;
214249259Sdim  bits<3> DST_SEL_Y;
215249259Sdim  bits<3> DST_SEL_Z;
216249259Sdim  bits<3> DST_SEL_W;
217249259Sdim  bits<1> USE_CONST_FIELDS;
218249259Sdim  bits<6> DATA_FORMAT;
219249259Sdim  bits<2> NUM_FORMAT_ALL;
220249259Sdim  bits<1> FORMAT_COMP_ALL;
221249259Sdim  bits<1> SRF_MODE_ALL;
222249259Sdim
223249259Sdim  let Word1{6-0} = DST_GPR;
224249259Sdim  let Word1{7}    = DST_REL;
225249259Sdim  let Word1{8}    = 0; // Reserved
226249259Sdim  let Word1{11-9} = DST_SEL_X;
227249259Sdim  let Word1{14-12} = DST_SEL_Y;
228249259Sdim  let Word1{17-15} = DST_SEL_Z;
229249259Sdim  let Word1{20-18} = DST_SEL_W;
230249259Sdim  let Word1{21}    = USE_CONST_FIELDS;
231249259Sdim  let Word1{27-22} = DATA_FORMAT;
232249259Sdim  let Word1{29-28} = NUM_FORMAT_ALL;
233249259Sdim  let Word1{30}    = FORMAT_COMP_ALL;
234249259Sdim  let Word1{31}    = SRF_MODE_ALL;
235249259Sdim}
236249259Sdim
237249259Sdimclass TEX_WORD0 {
238249259Sdim  field bits<32> Word0;
239249259Sdim
240249259Sdim  bits<5> TEX_INST;
241249259Sdim  bits<2> INST_MOD;
242249259Sdim  bits<1> FETCH_WHOLE_QUAD;
243249259Sdim  bits<8> RESOURCE_ID;
244249259Sdim  bits<7> SRC_GPR;
245249259Sdim  bits<1> SRC_REL;
246249259Sdim  bits<1> ALT_CONST;
247249259Sdim  bits<2> RESOURCE_INDEX_MODE;
248249259Sdim  bits<2> SAMPLER_INDEX_MODE;
249249259Sdim
250249259Sdim  let Word0{4-0} = TEX_INST;
251249259Sdim  let Word0{6-5} = INST_MOD;
252249259Sdim  let Word0{7} = FETCH_WHOLE_QUAD;
253249259Sdim  let Word0{15-8} = RESOURCE_ID;
254249259Sdim  let Word0{22-16} = SRC_GPR;
255249259Sdim  let Word0{23} = SRC_REL;
256249259Sdim  let Word0{24} = ALT_CONST;
257249259Sdim  let Word0{26-25} = RESOURCE_INDEX_MODE;
258249259Sdim  let Word0{28-27} = SAMPLER_INDEX_MODE;
259249259Sdim}
260249259Sdim
261249259Sdimclass TEX_WORD1 {
262249259Sdim  field bits<32> Word1;
263249259Sdim
264249259Sdim  bits<7> DST_GPR;
265249259Sdim  bits<1> DST_REL;
266249259Sdim  bits<3> DST_SEL_X;
267249259Sdim  bits<3> DST_SEL_Y;
268249259Sdim  bits<3> DST_SEL_Z;
269249259Sdim  bits<3> DST_SEL_W;
270249259Sdim  bits<7> LOD_BIAS;
271249259Sdim  bits<1> COORD_TYPE_X;
272249259Sdim  bits<1> COORD_TYPE_Y;
273249259Sdim  bits<1> COORD_TYPE_Z;
274249259Sdim  bits<1> COORD_TYPE_W;
275249259Sdim
276249259Sdim  let Word1{6-0} = DST_GPR;
277249259Sdim  let Word1{7} = DST_REL;
278249259Sdim  let Word1{11-9} = DST_SEL_X;
279249259Sdim  let Word1{14-12} = DST_SEL_Y;
280249259Sdim  let Word1{17-15} = DST_SEL_Z;
281249259Sdim  let Word1{20-18} = DST_SEL_W;
282249259Sdim  let Word1{27-21} = LOD_BIAS;
283249259Sdim  let Word1{28} = COORD_TYPE_X;
284249259Sdim  let Word1{29} = COORD_TYPE_Y;
285249259Sdim  let Word1{30} = COORD_TYPE_Z;
286249259Sdim  let Word1{31} = COORD_TYPE_W;
287249259Sdim}
288249259Sdim
289249259Sdimclass TEX_WORD2 {
290249259Sdim  field bits<32> Word2;
291249259Sdim
292249259Sdim  bits<5> OFFSET_X;
293249259Sdim  bits<5> OFFSET_Y;
294249259Sdim  bits<5> OFFSET_Z;
295249259Sdim  bits<5> SAMPLER_ID;
296249259Sdim  bits<3> SRC_SEL_X;
297249259Sdim  bits<3> SRC_SEL_Y;
298249259Sdim  bits<3> SRC_SEL_Z;
299249259Sdim  bits<3> SRC_SEL_W;
300249259Sdim
301249259Sdim  let Word2{4-0} = OFFSET_X;
302249259Sdim  let Word2{9-5} = OFFSET_Y;
303249259Sdim  let Word2{14-10} = OFFSET_Z;
304249259Sdim  let Word2{19-15} = SAMPLER_ID;
305249259Sdim  let Word2{22-20} = SRC_SEL_X;
306249259Sdim  let Word2{25-23} = SRC_SEL_Y;
307249259Sdim  let Word2{28-26} = SRC_SEL_Z;
308249259Sdim  let Word2{31-29} = SRC_SEL_W;
309249259Sdim}
310249259Sdim
311249259Sdim/*
312249259SdimXXX: R600 subtarget uses a slightly different encoding than the other
313249259Sdimsubtargets.  We currently handle this in R600MCCodeEmitter, but we may
314249259Sdimwant to use these instruction classes in the future.
315249259Sdim
316249259Sdimclass R600ALU_Word1_OP2_r600 : R600ALU_Word1_OP2 {
317249259Sdim
318249259Sdim  bits<1>  fog_merge;
319249259Sdim  bits<10> alu_inst;
320249259Sdim
321249259Sdim  let Inst{37}    = fog_merge;
322249259Sdim  let Inst{39-38} = omod;
323249259Sdim  let Inst{49-40} = alu_inst;
324249259Sdim}
325249259Sdim
326249259Sdimclass R600ALU_Word1_OP2_r700 : R600ALU_Word1_OP2 {
327249259Sdim
328249259Sdim  bits<11> alu_inst;
329249259Sdim
330249259Sdim  let Inst{38-37} = omod;
331249259Sdim  let Inst{49-39} = alu_inst;
332249259Sdim}
333249259Sdim*/
334249259Sdim
335249259Sdimdef R600_Pred : PredicateOperand<i32, (ops R600_Predicate),
336249259Sdim                                     (ops PRED_SEL_OFF)>;
337249259Sdim
338249259Sdim
339249259Sdimlet mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
340249259Sdim
341249259Sdim// Class for instructions with only one source register.
342249259Sdim// If you add new ins to this instruction, make sure they are listed before
343249259Sdim// $literal, because the backend currently assumes that the last operand is
344249259Sdim// a literal.  Also be sure to update the enum R600Op1OperandIndex::ROI in
345249259Sdim// R600Defines.h, R600InstrInfo::buildDefaultInstruction(),
346249259Sdim// and R600InstrInfo::getOperandIdx().
347249259Sdimclass R600_1OP <bits<11> inst, string opName, list<dag> pattern,
348249259Sdim                InstrItinClass itin = AnyALU> :
349249259Sdim    InstR600 <0,
350249259Sdim              (outs R600_Reg32:$dst),
351249259Sdim              (ins WRITE:$write, OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
352249259Sdim                   R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel,
353249259Sdim                   LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
354249259Sdim              !strconcat("  ", opName,
355249259Sdim                   "$clamp $dst$write$dst_rel$omod, "
356249259Sdim                   "$src0_neg$src0_abs$src0$src0_abs$src0_rel, "
357249259Sdim                   "$literal $pred_sel$last"),
358249259Sdim              pattern,
359249259Sdim              itin>,
360249259Sdim    R600ALU_Word0,
361249259Sdim    R600ALU_Word1_OP2 <inst> {
362249259Sdim
363249259Sdim  let src1 = 0;
364249259Sdim  let src1_rel = 0;
365249259Sdim  let src1_neg = 0;
366249259Sdim  let src1_abs = 0;
367249259Sdim  let update_exec_mask = 0;
368249259Sdim  let update_pred = 0;
369249259Sdim  let HasNativeOperands = 1;
370249259Sdim  let Op1 = 1;
371249259Sdim  let DisableEncoding = "$literal";
372249259Sdim
373249259Sdim  let Inst{31-0}  = Word0;
374249259Sdim  let Inst{63-32} = Word1;
375249259Sdim}
376249259Sdim
377249259Sdimclass R600_1OP_Helper <bits<11> inst, string opName, SDPatternOperator node,
378249259Sdim                    InstrItinClass itin = AnyALU> :
379249259Sdim    R600_1OP <inst, opName,
380249259Sdim              [(set R600_Reg32:$dst, (node R600_Reg32:$src0))]
381249259Sdim>;
382249259Sdim
383249259Sdim// If you add our change the operands for R600_2OP instructions, you must
384249259Sdim// also update the R600Op2OperandIndex::ROI enum in R600Defines.h,
385249259Sdim// R600InstrInfo::buildDefaultInstruction(), and R600InstrInfo::getOperandIdx().
386249259Sdimclass R600_2OP <bits<11> inst, string opName, list<dag> pattern,
387249259Sdim                InstrItinClass itin = AnyALU> :
388249259Sdim  InstR600 <inst,
389249259Sdim          (outs R600_Reg32:$dst),
390249259Sdim          (ins UEM:$update_exec_mask, UP:$update_pred, WRITE:$write,
391249259Sdim               OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
392249259Sdim               R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel,
393249259Sdim               R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, ABS:$src1_abs, SEL:$src1_sel,
394249259Sdim               LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
395249259Sdim          !strconcat("  ", opName,
396249259Sdim                "$clamp $update_exec_mask$update_pred$dst$write$dst_rel$omod, "
397249259Sdim                "$src0_neg$src0_abs$src0$src0_abs$src0_rel, "
398249259Sdim                "$src1_neg$src1_abs$src1$src1_abs$src1_rel, "
399249259Sdim                "$literal $pred_sel$last"),
400249259Sdim          pattern,
401249259Sdim          itin>,
402249259Sdim    R600ALU_Word0,
403249259Sdim    R600ALU_Word1_OP2 <inst> {
404249259Sdim
405249259Sdim  let HasNativeOperands = 1;
406249259Sdim  let Op2 = 1;
407249259Sdim  let DisableEncoding = "$literal";
408249259Sdim
409249259Sdim  let Inst{31-0}  = Word0;
410249259Sdim  let Inst{63-32} = Word1;
411249259Sdim}
412249259Sdim
413249259Sdimclass R600_2OP_Helper <bits<11> inst, string opName, SDPatternOperator node,
414249259Sdim                       InstrItinClass itim = AnyALU> :
415249259Sdim    R600_2OP <inst, opName,
416249259Sdim              [(set R600_Reg32:$dst, (node R600_Reg32:$src0,
417249259Sdim                                           R600_Reg32:$src1))]
418249259Sdim>;
419249259Sdim
420249259Sdim// If you add our change the operands for R600_3OP instructions, you must
421249259Sdim// also update the R600Op3OperandIndex::ROI enum in R600Defines.h,
422249259Sdim// R600InstrInfo::buildDefaultInstruction(), and
423249259Sdim// R600InstrInfo::getOperandIdx().
424249259Sdimclass R600_3OP <bits<5> inst, string opName, list<dag> pattern,
425249259Sdim                InstrItinClass itin = AnyALU> :
426249259Sdim  InstR600 <0,
427249259Sdim          (outs R600_Reg32:$dst),
428249259Sdim          (ins REL:$dst_rel, CLAMP:$clamp,
429249259Sdim               R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, SEL:$src0_sel,
430249259Sdim               R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, SEL:$src1_sel,
431249259Sdim               R600_Reg32:$src2, NEG:$src2_neg, REL:$src2_rel, SEL:$src2_sel,
432249259Sdim               LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
433249259Sdim          !strconcat("  ", opName, "$clamp $dst$dst_rel, "
434249259Sdim                             "$src0_neg$src0$src0_rel, "
435249259Sdim                             "$src1_neg$src1$src1_rel, "
436249259Sdim                             "$src2_neg$src2$src2_rel, "
437249259Sdim                             "$literal $pred_sel$last"),
438249259Sdim          pattern,
439249259Sdim          itin>,
440249259Sdim    R600ALU_Word0,
441249259Sdim    R600ALU_Word1_OP3<inst>{
442249259Sdim
443249259Sdim  let HasNativeOperands = 1;
444249259Sdim  let DisableEncoding = "$literal";
445249259Sdim  let Op3 = 1;
446249259Sdim
447249259Sdim  let Inst{31-0}  = Word0;
448249259Sdim  let Inst{63-32} = Word1;
449249259Sdim}
450249259Sdim
451249259Sdimclass R600_REDUCTION <bits<11> inst, dag ins, string asm, list<dag> pattern,
452249259Sdim                      InstrItinClass itin = VecALU> :
453249259Sdim  InstR600 <inst,
454249259Sdim          (outs R600_Reg32:$dst),
455249259Sdim          ins,
456249259Sdim          asm,
457249259Sdim          pattern,
458249259Sdim          itin>;
459249259Sdim
460249259Sdimclass R600_TEX <bits<11> inst, string opName, list<dag> pattern,
461249259Sdim                InstrItinClass itin = AnyALU> :
462249259Sdim  InstR600 <inst,
463249259Sdim          (outs R600_Reg128:$DST_GPR),
464249259Sdim          (ins R600_Reg128:$SRC_GPR, i32imm:$RESOURCE_ID, i32imm:$SAMPLER_ID, i32imm:$textureTarget),
465249259Sdim          !strconcat(opName, "$DST_GPR, $SRC_GPR, $RESOURCE_ID, $SAMPLER_ID, $textureTarget"),
466249259Sdim          pattern,
467249259Sdim          itin>, TEX_WORD0, TEX_WORD1, TEX_WORD2 {
468249259Sdim    let Inst{31-0} = Word0;
469249259Sdim    let Inst{63-32} = Word1;
470249259Sdim
471249259Sdim    let TEX_INST = inst{4-0};
472249259Sdim    let SRC_REL = 0;
473249259Sdim    let DST_REL = 0;
474249259Sdim    let DST_SEL_X = 0;
475249259Sdim    let DST_SEL_Y = 1;
476249259Sdim    let DST_SEL_Z = 2;
477249259Sdim    let DST_SEL_W = 3;
478249259Sdim    let LOD_BIAS = 0;
479249259Sdim
480249259Sdim    let INST_MOD = 0;
481249259Sdim    let FETCH_WHOLE_QUAD = 0;
482249259Sdim    let ALT_CONST = 0;
483249259Sdim    let SAMPLER_INDEX_MODE = 0;
484249259Sdim
485249259Sdim    let COORD_TYPE_X = 0;
486249259Sdim    let COORD_TYPE_Y = 0;
487249259Sdim    let COORD_TYPE_Z = 0;
488249259Sdim    let COORD_TYPE_W = 0;
489249259Sdim  }
490249259Sdim
491249259Sdim} // End mayLoad = 1, mayStore = 0, hasSideEffects = 0
492249259Sdim
493249259Sdimdef TEX_SHADOW : PatLeaf<
494249259Sdim  (imm),
495249259Sdim  [{uint32_t TType = (uint32_t)N->getZExtValue();
496249259Sdim    return (TType >= 6 && TType <= 8) || (TType >= 11 && TType <= 13);
497249259Sdim  }]
498249259Sdim>;
499249259Sdim
500249259Sdimdef TEX_RECT : PatLeaf<
501249259Sdim  (imm),
502249259Sdim  [{uint32_t TType = (uint32_t)N->getZExtValue();
503249259Sdim    return TType == 5;
504249259Sdim  }]
505249259Sdim>;
506249259Sdim
507249259Sdimdef TEX_ARRAY : PatLeaf<
508249259Sdim  (imm),
509249259Sdim  [{uint32_t TType = (uint32_t)N->getZExtValue();
510249259Sdim    return TType == 9 || TType == 10 || TType == 15 || TType == 16;
511249259Sdim  }]
512249259Sdim>;
513249259Sdim
514249259Sdimdef TEX_SHADOW_ARRAY : PatLeaf<
515249259Sdim  (imm),
516249259Sdim  [{uint32_t TType = (uint32_t)N->getZExtValue();
517249259Sdim    return TType == 11 || TType == 12 || TType == 17;
518249259Sdim  }]
519249259Sdim>;
520249259Sdim
521249259Sdimclass EG_CF_RAT <bits <8> cf_inst, bits <6> rat_inst, bits<4> rat_id, dag outs,
522249259Sdim                 dag ins, string asm, list<dag> pattern> :
523249259Sdim    InstR600ISA <outs, ins, asm, pattern> {
524249259Sdim  bits<7>  RW_GPR;
525249259Sdim  bits<7>  INDEX_GPR;
526249259Sdim
527249259Sdim  bits<2>  RIM;
528249259Sdim  bits<2>  TYPE;
529249259Sdim  bits<1>  RW_REL;
530249259Sdim  bits<2>  ELEM_SIZE;
531249259Sdim
532249259Sdim  bits<12> ARRAY_SIZE;
533249259Sdim  bits<4>  COMP_MASK;
534249259Sdim  bits<4>  BURST_COUNT;
535249259Sdim  bits<1>  VPM;
536249259Sdim  bits<1>  eop;
537249259Sdim  bits<1>  MARK;
538249259Sdim  bits<1>  BARRIER;
539249259Sdim
540249259Sdim  // CF_ALLOC_EXPORT_WORD0_RAT
541249259Sdim  let Inst{3-0}   = rat_id;
542249259Sdim  let Inst{9-4}   = rat_inst;
543249259Sdim  let Inst{10}    = 0; // Reserved
544249259Sdim  let Inst{12-11} = RIM;
545249259Sdim  let Inst{14-13} = TYPE;
546249259Sdim  let Inst{21-15} = RW_GPR;
547249259Sdim  let Inst{22}    = RW_REL;
548249259Sdim  let Inst{29-23} = INDEX_GPR;
549249259Sdim  let Inst{31-30} = ELEM_SIZE;
550249259Sdim
551249259Sdim  // CF_ALLOC_EXPORT_WORD1_BUF
552249259Sdim  let Inst{43-32} = ARRAY_SIZE;
553249259Sdim  let Inst{47-44} = COMP_MASK;
554249259Sdim  let Inst{51-48} = BURST_COUNT;
555249259Sdim  let Inst{52}    = VPM;
556249259Sdim  let Inst{53}    = eop;
557249259Sdim  let Inst{61-54} = cf_inst;
558249259Sdim  let Inst{62}    = MARK;
559249259Sdim  let Inst{63}    = BARRIER;
560249259Sdim}
561249259Sdim
562249259Sdimclass LoadParamFrag <PatFrag load_type> : PatFrag <
563249259Sdim  (ops node:$ptr), (load_type node:$ptr),
564249259Sdim  [{ return isParamLoad(dyn_cast<LoadSDNode>(N)); }]
565249259Sdim>;
566249259Sdim
567249259Sdimdef load_param : LoadParamFrag<load>;
568249259Sdimdef load_param_zexti8 : LoadParamFrag<zextloadi8>;
569249259Sdimdef load_param_zexti16 : LoadParamFrag<zextloadi16>;
570249259Sdim
571249259Sdimdef isR600 : Predicate<"Subtarget.device()"
572249259Sdim                            "->getGeneration() == AMDGPUDeviceInfo::HD4XXX">;
573249259Sdimdef isR700 : Predicate<"Subtarget.device()"
574249259Sdim                            "->getGeneration() == AMDGPUDeviceInfo::HD4XXX &&"
575249259Sdim                            "Subtarget.device()->getDeviceFlag()"
576249259Sdim                            ">= OCL_DEVICE_RV710">;
577249259Sdimdef isEG : Predicate<
578249259Sdim  "Subtarget.device()->getGeneration() >= AMDGPUDeviceInfo::HD5XXX && "
579249259Sdim  "Subtarget.device()->getGeneration() < AMDGPUDeviceInfo::HD7XXX && "
580249259Sdim  "Subtarget.device()->getDeviceFlag() != OCL_DEVICE_CAYMAN">;
581249259Sdim
582249259Sdimdef isCayman : Predicate<"Subtarget.device()"
583249259Sdim                            "->getDeviceFlag() == OCL_DEVICE_CAYMAN">;
584249259Sdimdef isEGorCayman : Predicate<"Subtarget.device()"
585249259Sdim                            "->getGeneration() == AMDGPUDeviceInfo::HD5XXX"
586249259Sdim                            "|| Subtarget.device()->getGeneration() =="
587249259Sdim                            "AMDGPUDeviceInfo::HD6XXX">;
588249259Sdim
589249259Sdimdef isR600toCayman : Predicate<
590249259Sdim                     "Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX">;
591249259Sdim
592249259Sdim//===----------------------------------------------------------------------===//
593249259Sdim// R600 SDNodes
594249259Sdim//===----------------------------------------------------------------------===//
595249259Sdim
596249259Sdimdef INTERP_PAIR_XY :  AMDGPUShaderInst <
597249259Sdim  (outs R600_TReg32_X:$dst0, R600_TReg32_Y:$dst1),
598249259Sdim  (ins i32imm:$src0, R600_Reg32:$src1, R600_Reg32:$src2),
599249259Sdim  "INTERP_PAIR_XY $src0 $src1 $src2 : $dst0 dst1",
600249259Sdim  []>;
601249259Sdim
602249259Sdimdef INTERP_PAIR_ZW :  AMDGPUShaderInst <
603249259Sdim  (outs R600_TReg32_Z:$dst0, R600_TReg32_W:$dst1),
604249259Sdim  (ins i32imm:$src0, R600_Reg32:$src1, R600_Reg32:$src2),
605249259Sdim  "INTERP_PAIR_ZW $src0 $src1 $src2 : $dst0 dst1",
606249259Sdim  []>;
607249259Sdim
608249259Sdimdef CONST_ADDRESS: SDNode<"AMDGPUISD::CONST_ADDRESS",
609249259Sdim  SDTypeProfile<1, -1, [SDTCisInt<0>, SDTCisPtrTy<1>]>,
610249259Sdim  [SDNPVariadic]
611249259Sdim>;
612249259Sdim
613249259Sdim//===----------------------------------------------------------------------===//
614249259Sdim// Interpolation Instructions
615249259Sdim//===----------------------------------------------------------------------===//
616249259Sdim
617249259Sdimdef INTERP_VEC_LOAD :  AMDGPUShaderInst <
618249259Sdim  (outs R600_Reg128:$dst),
619249259Sdim  (ins i32imm:$src0),
620249259Sdim  "INTERP_LOAD $src0 : $dst",
621249259Sdim  []>;
622249259Sdim
623249259Sdimdef INTERP_XY : R600_2OP <0xD6, "INTERP_XY", []> {
624249259Sdim  let bank_swizzle = 5;
625249259Sdim}
626249259Sdim
627249259Sdimdef INTERP_ZW : R600_2OP <0xD7, "INTERP_ZW", []> {
628249259Sdim  let bank_swizzle = 5;
629249259Sdim}
630249259Sdim
631249259Sdimdef INTERP_LOAD_P0 : R600_1OP <0xE0, "INTERP_LOAD_P0", []>;
632249259Sdim
633249259Sdim//===----------------------------------------------------------------------===//
634249259Sdim// Export Instructions
635249259Sdim//===----------------------------------------------------------------------===//
636249259Sdim
637249259Sdimdef ExportType : SDTypeProfile<0, 7, [SDTCisFP<0>, SDTCisInt<1>]>;
638249259Sdim
639249259Sdimdef EXPORT: SDNode<"AMDGPUISD::EXPORT", ExportType,
640249259Sdim  [SDNPHasChain, SDNPSideEffect]>;
641249259Sdim
642249259Sdimclass ExportWord0 {
643249259Sdim  field bits<32> Word0;
644249259Sdim
645249259Sdim  bits<13> arraybase;
646249259Sdim  bits<2> type;
647249259Sdim  bits<7> gpr;
648249259Sdim  bits<2> elem_size;
649249259Sdim
650249259Sdim  let Word0{12-0} = arraybase;
651249259Sdim  let Word0{14-13} = type;
652249259Sdim  let Word0{21-15} = gpr;
653249259Sdim  let Word0{22} = 0; // RW_REL
654249259Sdim  let Word0{29-23} = 0; // INDEX_GPR
655249259Sdim  let Word0{31-30} = elem_size;
656249259Sdim}
657249259Sdim
658249259Sdimclass ExportSwzWord1 {
659249259Sdim  field bits<32> Word1;
660249259Sdim
661249259Sdim  bits<3> sw_x;
662249259Sdim  bits<3> sw_y;
663249259Sdim  bits<3> sw_z;
664249259Sdim  bits<3> sw_w;
665249259Sdim  bits<1> eop;
666249259Sdim  bits<8> inst;
667249259Sdim
668249259Sdim  let Word1{2-0} = sw_x;
669249259Sdim  let Word1{5-3} = sw_y;
670249259Sdim  let Word1{8-6} = sw_z;
671249259Sdim  let Word1{11-9} = sw_w;
672249259Sdim}
673249259Sdim
674249259Sdimclass ExportBufWord1 {
675249259Sdim  field bits<32> Word1;
676249259Sdim
677249259Sdim  bits<12> arraySize;
678249259Sdim  bits<4> compMask;
679249259Sdim  bits<1> eop;
680249259Sdim  bits<8> inst;
681249259Sdim
682249259Sdim  let Word1{11-0} = arraySize;
683249259Sdim  let Word1{15-12} = compMask;
684249259Sdim}
685249259Sdim
686249259Sdimmulticlass ExportPattern<Instruction ExportInst, bits<8> cf_inst> {
687249259Sdim  def : Pat<(int_R600_store_pixel_depth R600_Reg32:$reg),
688249259Sdim    (ExportInst
689249259Sdim        (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), R600_Reg32:$reg, sub0),
690249259Sdim        0, 61, 0, 7, 7, 7, cf_inst, 0)
691249259Sdim  >;
692249259Sdim
693249259Sdim  def : Pat<(int_R600_store_pixel_stencil R600_Reg32:$reg),
694249259Sdim    (ExportInst
695249259Sdim        (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), R600_Reg32:$reg, sub0),
696249259Sdim        0, 61, 7, 0, 7, 7, cf_inst, 0)
697249259Sdim  >;
698249259Sdim
699249259Sdim  def : Pat<(int_R600_store_dummy (i32 imm:$type)),
700249259Sdim    (ExportInst
701249259Sdim        (v4f32 (IMPLICIT_DEF)), imm:$type, 0, 7, 7, 7, 7, cf_inst, 0)
702249259Sdim  >;
703249259Sdim
704249259Sdim  def : Pat<(int_R600_store_dummy 1),
705249259Sdim    (ExportInst
706249259Sdim        (v4f32 (IMPLICIT_DEF)), 1, 60, 7, 7, 7, 7, cf_inst, 0)
707249259Sdim  >;
708249259Sdim
709249259Sdim  def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 imm:$base), (i32 imm:$type),
710249259Sdim    (i32 imm:$swz_x), (i32 imm:$swz_y), (i32 imm:$swz_z), (i32 imm:$swz_w)),
711249259Sdim        (ExportInst R600_Reg128:$src, imm:$type, imm:$base,
712249259Sdim        imm:$swz_x, imm:$swz_y, imm:$swz_z, imm:$swz_w, cf_inst, 0)
713249259Sdim  >;
714249259Sdim
715249259Sdim}
716249259Sdim
717249259Sdimmulticlass SteamOutputExportPattern<Instruction ExportInst,
718249259Sdim    bits<8> buf0inst, bits<8> buf1inst, bits<8> buf2inst, bits<8> buf3inst> {
719249259Sdim// Stream0
720249259Sdim  def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src),
721249259Sdim      (i32 imm:$arraybase), (i32 0), (i32 imm:$mask)),
722249259Sdim      (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
723249259Sdim      4095, imm:$mask, buf0inst, 0)>;
724249259Sdim// Stream1
725249259Sdim  def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src),
726249259Sdim      (i32 imm:$arraybase), (i32 1), (i32 imm:$mask)),
727249259Sdim      (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
728249259Sdim      4095, imm:$mask, buf1inst, 0)>;
729249259Sdim// Stream2
730249259Sdim  def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src),
731249259Sdim      (i32 imm:$arraybase), (i32 2), (i32 imm:$mask)),
732249259Sdim      (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
733249259Sdim      4095, imm:$mask, buf2inst, 0)>;
734249259Sdim// Stream3
735249259Sdim  def : Pat<(int_R600_store_stream_output (v4f32 R600_Reg128:$src),
736249259Sdim      (i32 imm:$arraybase), (i32 3), (i32 imm:$mask)),
737249259Sdim      (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
738249259Sdim      4095, imm:$mask, buf3inst, 0)>;
739249259Sdim}
740249259Sdim
741249259Sdimlet usesCustomInserter = 1 in {
742249259Sdim
743249259Sdimclass ExportSwzInst : InstR600ISA<(
744249259Sdim    outs),
745249259Sdim    (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase,
746249259Sdim    i32imm:$sw_x, i32imm:$sw_y, i32imm:$sw_z, i32imm:$sw_w, i32imm:$inst,
747249259Sdim    i32imm:$eop),
748249259Sdim    !strconcat("EXPORT", " $gpr"),
749249259Sdim    []>, ExportWord0, ExportSwzWord1 {
750249259Sdim  let elem_size = 3;
751249259Sdim  let Inst{31-0} = Word0;
752249259Sdim  let Inst{63-32} = Word1;
753249259Sdim}
754249259Sdim
755249259Sdim} // End usesCustomInserter = 1
756249259Sdim
757249259Sdimclass ExportBufInst : InstR600ISA<(
758249259Sdim    outs),
759249259Sdim    (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase,
760249259Sdim    i32imm:$arraySize, i32imm:$compMask, i32imm:$inst, i32imm:$eop),
761249259Sdim    !strconcat("EXPORT", " $gpr"),
762249259Sdim    []>, ExportWord0, ExportBufWord1 {
763249259Sdim  let elem_size = 0;
764249259Sdim  let Inst{31-0} = Word0;
765249259Sdim  let Inst{63-32} = Word1;
766249259Sdim}
767249259Sdim
768249259Sdim//===----------------------------------------------------------------------===//
769249259Sdim// Control Flow Instructions
770249259Sdim//===----------------------------------------------------------------------===//
771249259Sdim
772249259Sdimclass CF_ALU_WORD0 {
773249259Sdim  field bits<32> Word0;
774249259Sdim
775249259Sdim  bits<22> ADDR;
776249259Sdim  bits<4> KCACHE_BANK0;
777249259Sdim  bits<4> KCACHE_BANK1;
778249259Sdim  bits<2> KCACHE_MODE0;
779249259Sdim
780249259Sdim  let Word0{21-0} = ADDR;
781249259Sdim  let Word0{25-22} = KCACHE_BANK0;
782249259Sdim  let Word0{29-26} = KCACHE_BANK1;
783249259Sdim  let Word0{31-30} = KCACHE_MODE0;
784249259Sdim}
785249259Sdim
786249259Sdimclass CF_ALU_WORD1 {
787249259Sdim  field bits<32> Word1;
788249259Sdim
789249259Sdim  bits<2> KCACHE_MODE1;
790249259Sdim  bits<8> KCACHE_ADDR0;
791249259Sdim  bits<8> KCACHE_ADDR1;
792249259Sdim  bits<7> COUNT;
793249259Sdim  bits<1> ALT_CONST;
794249259Sdim  bits<4> CF_INST;
795249259Sdim  bits<1> WHOLE_QUAD_MODE;
796249259Sdim  bits<1> BARRIER;
797249259Sdim
798249259Sdim  let Word1{1-0} = KCACHE_MODE1;
799249259Sdim  let Word1{9-2} = KCACHE_ADDR0;
800249259Sdim  let Word1{17-10} = KCACHE_ADDR1;
801249259Sdim  let Word1{24-18} = COUNT;
802249259Sdim  let Word1{25} = ALT_CONST;
803249259Sdim  let Word1{29-26} = CF_INST;
804249259Sdim  let Word1{30} = WHOLE_QUAD_MODE;
805249259Sdim  let Word1{31} = BARRIER;
806249259Sdim}
807249259Sdim
808249259Sdimclass ALU_CLAUSE<bits<4> inst, string OpName> : AMDGPUInst <(outs),
809249259Sdim(ins i32imm:$ADDR, i32imm:$KCACHE_BANK0, i32imm:$KCACHE_BANK1, i32imm:$KCACHE_MODE0, i32imm:$KCACHE_MODE1,
810249259Sdimi32imm:$KCACHE_ADDR0, i32imm:$KCACHE_ADDR1, i32imm:$COUNT),
811249259Sdim!strconcat(OpName, " $COUNT, @$ADDR, "
812249259Sdim"KC0[CB$KCACHE_BANK0:$KCACHE_ADDR0-$KCACHE_ADDR0+32]"
813249259Sdim", KC1[CB$KCACHE_BANK1:$KCACHE_ADDR1-$KCACHE_ADDR1+32]"),
814249259Sdim[] >, CF_ALU_WORD0, CF_ALU_WORD1 {
815249259Sdim  field bits<64> Inst;
816249259Sdim
817249259Sdim  let CF_INST = inst;
818249259Sdim  let ALT_CONST = 0;
819249259Sdim  let WHOLE_QUAD_MODE = 0;
820249259Sdim  let BARRIER = 1;
821249259Sdim
822249259Sdim  let Inst{31-0} = Word0;
823249259Sdim  let Inst{63-32} = Word1;
824249259Sdim}
825249259Sdim
826249259Sdimclass CF_WORD0 {
827249259Sdim  field bits<32> Word0;
828249259Sdim
829249259Sdim  bits<24> ADDR;
830249259Sdim  bits<3> JUMPTABLE_SEL;
831249259Sdim
832249259Sdim  let Word0{23-0} = ADDR;
833249259Sdim  let Word0{26-24} = JUMPTABLE_SEL;
834249259Sdim}
835249259Sdim
836249259Sdimclass CF_WORD1 {
837249259Sdim  field bits<32> Word1;
838249259Sdim
839249259Sdim  bits<3> POP_COUNT;
840249259Sdim  bits<5> CF_CONST;
841249259Sdim  bits<2> COND;
842249259Sdim  bits<6> COUNT;
843249259Sdim  bits<1> VALID_PIXEL_MODE;
844249259Sdim  bits<8> CF_INST;
845249259Sdim  bits<1> BARRIER;
846249259Sdim
847249259Sdim  let Word1{2-0} = POP_COUNT;
848249259Sdim  let Word1{7-3} = CF_CONST;
849249259Sdim  let Word1{9-8} = COND;
850249259Sdim  let Word1{15-10} = COUNT;
851249259Sdim  let Word1{20} = VALID_PIXEL_MODE;
852249259Sdim  let Word1{29-22} = CF_INST;
853249259Sdim  let Word1{31} = BARRIER;
854249259Sdim}
855249259Sdim
856249259Sdimclass CF_CLAUSE <bits<8> inst, dag ins, string AsmPrint> : AMDGPUInst <(outs),
857249259Sdimins, AsmPrint, [] >, CF_WORD0, CF_WORD1 {
858249259Sdim  field bits<64> Inst;
859249259Sdim
860249259Sdim  let CF_INST = inst;
861249259Sdim  let BARRIER = 1;
862249259Sdim  let JUMPTABLE_SEL = 0;
863249259Sdim  let CF_CONST = 0;
864249259Sdim  let VALID_PIXEL_MODE = 0;
865249259Sdim  let COND = 0;
866249259Sdim
867249259Sdim  let Inst{31-0} = Word0;
868249259Sdim  let Inst{63-32} = Word1;
869249259Sdim}
870249259Sdim
871249259Sdimdef CF_TC : CF_CLAUSE<1, (ins i32imm:$ADDR, i32imm:$COUNT),
872249259Sdim"TEX $COUNT @$ADDR"> {
873249259Sdim  let POP_COUNT = 0;
874249259Sdim}
875249259Sdim
876249259Sdimdef CF_VC : CF_CLAUSE<2, (ins i32imm:$ADDR, i32imm:$COUNT),
877249259Sdim"VTX $COUNT @$ADDR"> {
878249259Sdim  let POP_COUNT = 0;
879249259Sdim}
880249259Sdim
881249259Sdimdef WHILE_LOOP : CF_CLAUSE<6, (ins i32imm:$ADDR), "LOOP_START_DX10 @$ADDR"> {
882249259Sdim  let POP_COUNT = 0;
883249259Sdim  let COUNT = 0;
884249259Sdim}
885249259Sdim
886249259Sdimdef END_LOOP : CF_CLAUSE<5, (ins i32imm:$ADDR), "END_LOOP @$ADDR"> {
887249259Sdim  let POP_COUNT = 0;
888249259Sdim  let COUNT = 0;
889249259Sdim}
890249259Sdim
891249259Sdimdef LOOP_BREAK : CF_CLAUSE<9, (ins i32imm:$ADDR), "LOOP_BREAK @$ADDR"> {
892249259Sdim  let POP_COUNT = 0;
893249259Sdim  let COUNT = 0;
894249259Sdim}
895249259Sdim
896249259Sdimdef CF_CONTINUE : CF_CLAUSE<8, (ins i32imm:$ADDR), "CONTINUE @$ADDR"> {
897249259Sdim  let POP_COUNT = 0;
898249259Sdim  let COUNT = 0;
899249259Sdim}
900249259Sdim
901249259Sdimdef CF_JUMP : CF_CLAUSE<10, (ins i32imm:$ADDR, i32imm:$POP_COUNT), "JUMP @$ADDR POP:$POP_COUNT"> {
902249259Sdim  let COUNT = 0;
903249259Sdim}
904249259Sdim
905249259Sdimdef CF_ELSE : CF_CLAUSE<13, (ins i32imm:$ADDR, i32imm:$POP_COUNT), "ELSE @$ADDR POP:$POP_COUNT"> {
906249259Sdim  let COUNT = 0;
907249259Sdim}
908249259Sdim
909249259Sdimdef CF_CALL_FS : CF_CLAUSE<19, (ins), "CALL_FS"> {
910249259Sdim  let ADDR = 0;
911249259Sdim  let COUNT = 0;
912249259Sdim  let POP_COUNT = 0;
913249259Sdim}
914249259Sdim
915249259Sdimdef POP : CF_CLAUSE<14, (ins i32imm:$ADDR, i32imm:$POP_COUNT), "POP @$ADDR POP:$POP_COUNT"> {
916249259Sdim  let COUNT = 0;
917249259Sdim}
918249259Sdim
919249259Sdimdef CF_ALU : ALU_CLAUSE<8, "ALU">;
920249259Sdimdef CF_ALU_PUSH_BEFORE : ALU_CLAUSE<9, "ALU_PUSH_BEFORE">;
921249259Sdim
922249259Sdimdef STACK_SIZE : AMDGPUInst <(outs),
923249259Sdim(ins i32imm:$num), "nstack $num", [] > {
924249259Sdim  field bits<8> Inst;
925249259Sdim  bits<8> num;
926249259Sdim  let Inst = num;
927249259Sdim}
928249259Sdim
929249259Sdimlet Predicates = [isR600toCayman] in {
930249259Sdim
931249259Sdim//===----------------------------------------------------------------------===//
932249259Sdim// Common Instructions R600, R700, Evergreen, Cayman
933249259Sdim//===----------------------------------------------------------------------===//
934249259Sdim
935249259Sdimdef ADD : R600_2OP_Helper <0x0, "ADD", fadd>;
936249259Sdim// Non-IEEE MUL: 0 * anything = 0
937249259Sdimdef MUL : R600_2OP_Helper <0x1, "MUL NON-IEEE", int_AMDGPU_mul>;
938249259Sdimdef MUL_IEEE : R600_2OP_Helper <0x2, "MUL_IEEE", fmul>;
939249259Sdimdef MAX : R600_2OP_Helper <0x3, "MAX", AMDGPUfmax>;
940249259Sdimdef MIN : R600_2OP_Helper <0x4, "MIN", AMDGPUfmin>;
941249259Sdim
942249259Sdim// For the SET* instructions there is a naming conflict in TargetSelectionDAG.td,
943249259Sdim// so some of the instruction names don't match the asm string.
944249259Sdim// XXX: Use the defs in TargetSelectionDAG.td instead of intrinsics.
945249259Sdimdef SETE : R600_2OP <
946249259Sdim  0x08, "SETE",
947249259Sdim  [(set R600_Reg32:$dst,
948249259Sdim   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
949249259Sdim             COND_EQ))]
950249259Sdim>;
951249259Sdim
952249259Sdimdef SGT : R600_2OP <
953249259Sdim  0x09, "SETGT",
954249259Sdim  [(set R600_Reg32:$dst,
955249259Sdim   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
956249259Sdim              COND_GT))]
957249259Sdim>;
958249259Sdim
959249259Sdimdef SGE : R600_2OP <
960249259Sdim  0xA, "SETGE",
961249259Sdim  [(set R600_Reg32:$dst,
962249259Sdim   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
963249259Sdim              COND_GE))]
964249259Sdim>;
965249259Sdim
966249259Sdimdef SNE : R600_2OP <
967249259Sdim  0xB, "SETNE",
968249259Sdim  [(set R600_Reg32:$dst,
969249259Sdim   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
970249259Sdim    COND_NE))]
971249259Sdim>;
972249259Sdim
973249259Sdimdef SETE_DX10 : R600_2OP <
974249259Sdim  0xC, "SETE_DX10",
975249259Sdim  [(set R600_Reg32:$dst,
976249259Sdim   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0),
977249259Sdim    COND_EQ))]
978249259Sdim>;
979249259Sdim
980249259Sdimdef SETGT_DX10 : R600_2OP <
981249259Sdim  0xD, "SETGT_DX10",
982249259Sdim  [(set R600_Reg32:$dst,
983249259Sdim   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0),
984249259Sdim    COND_GT))]
985249259Sdim>;
986249259Sdim
987249259Sdimdef SETGE_DX10 : R600_2OP <
988249259Sdim  0xE, "SETGE_DX10",
989249259Sdim  [(set R600_Reg32:$dst,
990249259Sdim   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0),
991249259Sdim    COND_GE))]
992249259Sdim>;
993249259Sdim
994249259Sdimdef SETNE_DX10 : R600_2OP <
995249259Sdim  0xF, "SETNE_DX10",
996249259Sdim  [(set R600_Reg32:$dst,
997249259Sdim    (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, (i32 -1), (i32 0),
998249259Sdim     COND_NE))]
999249259Sdim>;
1000249259Sdim
1001249259Sdimdef FRACT : R600_1OP_Helper <0x10, "FRACT", AMDGPUfract>;
1002249259Sdimdef TRUNC : R600_1OP_Helper <0x11, "TRUNC", int_AMDGPU_trunc>;
1003249259Sdimdef CEIL : R600_1OP_Helper <0x12, "CEIL", fceil>;
1004249259Sdimdef RNDNE : R600_1OP_Helper <0x13, "RNDNE", frint>;
1005249259Sdimdef FLOOR : R600_1OP_Helper <0x14, "FLOOR", ffloor>;
1006249259Sdim
1007249259Sdimdef MOV : R600_1OP <0x19, "MOV", []>;
1008249259Sdim
1009249259Sdimlet isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in {
1010249259Sdim
1011249259Sdimclass MOV_IMM <ValueType vt, Operand immType> : AMDGPUInst <
1012249259Sdim  (outs R600_Reg32:$dst),
1013249259Sdim  (ins immType:$imm),
1014249259Sdim  "",
1015249259Sdim  []
1016249259Sdim>;
1017249259Sdim
1018249259Sdim} // end let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1
1019249259Sdim
1020249259Sdimdef MOV_IMM_I32 : MOV_IMM<i32, i32imm>;
1021249259Sdimdef : Pat <
1022249259Sdim  (imm:$val),
1023249259Sdim  (MOV_IMM_I32 imm:$val)
1024249259Sdim>;
1025249259Sdim
1026249259Sdimdef MOV_IMM_F32 : MOV_IMM<f32, f32imm>;
1027249259Sdimdef : Pat <
1028249259Sdim  (fpimm:$val),
1029249259Sdim  (MOV_IMM_F32  fpimm:$val)
1030249259Sdim>;
1031249259Sdim
1032249259Sdimdef PRED_SETE : R600_2OP <0x20, "PRED_SETE", []>;
1033249259Sdimdef PRED_SETGT : R600_2OP <0x21, "PRED_SETGT", []>;
1034249259Sdimdef PRED_SETGE : R600_2OP <0x22, "PRED_SETGE", []>;
1035249259Sdimdef PRED_SETNE : R600_2OP <0x23, "PRED_SETNE", []>;
1036249259Sdim
1037249259Sdimlet hasSideEffects = 1 in {
1038249259Sdim
1039249259Sdimdef KILLGT : R600_2OP <0x2D, "KILLGT", []>;
1040249259Sdim
1041249259Sdim} // end hasSideEffects
1042249259Sdim
1043249259Sdimdef AND_INT : R600_2OP_Helper <0x30, "AND_INT", and>;
1044249259Sdimdef OR_INT : R600_2OP_Helper <0x31, "OR_INT", or>;
1045249259Sdimdef XOR_INT : R600_2OP_Helper <0x32, "XOR_INT", xor>;
1046249259Sdimdef NOT_INT : R600_1OP_Helper <0x33, "NOT_INT", not>;
1047249259Sdimdef ADD_INT : R600_2OP_Helper <0x34, "ADD_INT", add>;
1048249259Sdimdef SUB_INT : R600_2OP_Helper <0x35, "SUB_INT", sub>;
1049249259Sdimdef MAX_INT : R600_2OP_Helper <0x36, "MAX_INT", AMDGPUsmax>;
1050249259Sdimdef MIN_INT : R600_2OP_Helper <0x37, "MIN_INT", AMDGPUsmin>;
1051249259Sdimdef MAX_UINT : R600_2OP_Helper <0x38, "MAX_UINT", AMDGPUumax>;
1052249259Sdimdef MIN_UINT : R600_2OP_Helper <0x39, "MIN_UINT", AMDGPUumin>;
1053249259Sdim
1054249259Sdimdef SETE_INT : R600_2OP <
1055249259Sdim  0x3A, "SETE_INT",
1056249259Sdim  [(set (i32 R600_Reg32:$dst),
1057249259Sdim   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETEQ))]
1058249259Sdim>;
1059249259Sdim
1060249259Sdimdef SETGT_INT : R600_2OP <
1061249259Sdim  0x3B, "SETGT_INT",
1062249259Sdim  [(set (i32 R600_Reg32:$dst),
1063249259Sdim   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETGT))]
1064249259Sdim>;
1065249259Sdim
1066249259Sdimdef SETGE_INT : R600_2OP <
1067249259Sdim  0x3C, "SETGE_INT",
1068249259Sdim  [(set (i32 R600_Reg32:$dst),
1069249259Sdim   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETGE))]
1070249259Sdim>;
1071249259Sdim
1072249259Sdimdef SETNE_INT : R600_2OP <
1073249259Sdim  0x3D, "SETNE_INT",
1074249259Sdim  [(set (i32 R600_Reg32:$dst),
1075249259Sdim   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETNE))]
1076249259Sdim>;
1077249259Sdim
1078249259Sdimdef SETGT_UINT : R600_2OP <
1079249259Sdim  0x3E, "SETGT_UINT",
1080249259Sdim  [(set (i32 R600_Reg32:$dst),
1081249259Sdim   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGT))]
1082249259Sdim>;
1083249259Sdim
1084249259Sdimdef SETGE_UINT : R600_2OP <
1085249259Sdim  0x3F, "SETGE_UINT",
1086249259Sdim  [(set (i32 R600_Reg32:$dst),
1087249259Sdim    (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGE))]
1088249259Sdim>;
1089249259Sdim
1090249259Sdimdef PRED_SETE_INT : R600_2OP <0x42, "PRED_SETE_INT", []>;
1091249259Sdimdef PRED_SETGT_INT : R600_2OP <0x43, "PRED_SETGE_INT", []>;
1092249259Sdimdef PRED_SETGE_INT : R600_2OP <0x44, "PRED_SETGE_INT", []>;
1093249259Sdimdef PRED_SETNE_INT : R600_2OP <0x45, "PRED_SETNE_INT", []>;
1094249259Sdim
1095249259Sdimdef CNDE_INT : R600_3OP <
1096249259Sdim  0x1C, "CNDE_INT",
1097249259Sdim  [(set (i32 R600_Reg32:$dst),
1098249259Sdim   (selectcc (i32 R600_Reg32:$src0), 0,
1099249259Sdim       (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
1100249259Sdim       COND_EQ))]
1101249259Sdim>;
1102249259Sdim
1103249259Sdimdef CNDGE_INT : R600_3OP <
1104249259Sdim  0x1E, "CNDGE_INT",
1105249259Sdim  [(set (i32 R600_Reg32:$dst),
1106249259Sdim   (selectcc (i32 R600_Reg32:$src0), 0,
1107249259Sdim       (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
1108249259Sdim       COND_GE))]
1109249259Sdim>;
1110249259Sdim
1111249259Sdimdef CNDGT_INT : R600_3OP <
1112249259Sdim  0x1D, "CNDGT_INT",
1113249259Sdim  [(set (i32 R600_Reg32:$dst),
1114249259Sdim   (selectcc (i32 R600_Reg32:$src0), 0,
1115249259Sdim       (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
1116249259Sdim       COND_GT))]
1117249259Sdim>;
1118249259Sdim
1119249259Sdim//===----------------------------------------------------------------------===//
1120249259Sdim// Texture instructions
1121249259Sdim//===----------------------------------------------------------------------===//
1122249259Sdim
1123249259Sdimdef TEX_LD : R600_TEX <
1124249259Sdim  0x03, "TEX_LD",
1125249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txf R600_Reg128:$SRC_GPR,
1126249259Sdim      imm:$OFFSET_X, imm:$OFFSET_Y, imm:$OFFSET_Z, imm:$RESOURCE_ID,
1127249259Sdim      imm:$SAMPLER_ID, imm:$textureTarget))]
1128249259Sdim> {
1129249259Sdimlet AsmString = "TEX_LD $DST_GPR, $SRC_GPR, $OFFSET_X, $OFFSET_Y, $OFFSET_Z,"
1130249259Sdim    "$RESOURCE_ID, $SAMPLER_ID, $textureTarget";
1131249259Sdimlet InOperandList = (ins R600_Reg128:$SRC_GPR, i32imm:$OFFSET_X,
1132249259Sdim    i32imm:$OFFSET_Y, i32imm:$OFFSET_Z, i32imm:$RESOURCE_ID, i32imm:$SAMPLER_ID,
1133249259Sdim    i32imm:$textureTarget);
1134249259Sdim}
1135249259Sdim
1136249259Sdimdef TEX_GET_TEXTURE_RESINFO : R600_TEX <
1137249259Sdim  0x04, "TEX_GET_TEXTURE_RESINFO",
1138249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txq R600_Reg128:$SRC_GPR,
1139249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
1140249259Sdim>;
1141249259Sdim
1142249259Sdimdef TEX_GET_GRADIENTS_H : R600_TEX <
1143249259Sdim  0x07, "TEX_GET_GRADIENTS_H",
1144249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_ddx R600_Reg128:$SRC_GPR,
1145249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
1146249259Sdim>;
1147249259Sdim
1148249259Sdimdef TEX_GET_GRADIENTS_V : R600_TEX <
1149249259Sdim  0x08, "TEX_GET_GRADIENTS_V",
1150249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_ddy R600_Reg128:$SRC_GPR,
1151249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
1152249259Sdim>;
1153249259Sdim
1154249259Sdimdef TEX_SET_GRADIENTS_H : R600_TEX <
1155249259Sdim  0x0B, "TEX_SET_GRADIENTS_H",
1156249259Sdim  []
1157249259Sdim>;
1158249259Sdim
1159249259Sdimdef TEX_SET_GRADIENTS_V : R600_TEX <
1160249259Sdim  0x0C, "TEX_SET_GRADIENTS_V",
1161249259Sdim  []
1162249259Sdim>;
1163249259Sdim
1164249259Sdimdef TEX_SAMPLE : R600_TEX <
1165249259Sdim  0x10, "TEX_SAMPLE",
1166249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_tex R600_Reg128:$SRC_GPR,
1167249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
1168249259Sdim>;
1169249259Sdim
1170249259Sdimdef TEX_SAMPLE_C : R600_TEX <
1171249259Sdim  0x18, "TEX_SAMPLE_C",
1172249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_tex R600_Reg128:$SRC_GPR,
1173249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))]
1174249259Sdim>;
1175249259Sdim
1176249259Sdimdef TEX_SAMPLE_L : R600_TEX <
1177249259Sdim  0x11, "TEX_SAMPLE_L",
1178249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txl R600_Reg128:$SRC_GPR,
1179249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
1180249259Sdim>;
1181249259Sdim
1182249259Sdimdef TEX_SAMPLE_C_L : R600_TEX <
1183249259Sdim  0x19, "TEX_SAMPLE_C_L",
1184249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txl R600_Reg128:$SRC_GPR,
1185249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))]
1186249259Sdim>;
1187249259Sdim
1188249259Sdimdef TEX_SAMPLE_LB : R600_TEX <
1189249259Sdim  0x12, "TEX_SAMPLE_LB",
1190249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txb R600_Reg128:$SRC_GPR,
1191249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, imm:$textureTarget))]
1192249259Sdim>;
1193249259Sdim
1194249259Sdimdef TEX_SAMPLE_C_LB : R600_TEX <
1195249259Sdim  0x1A, "TEX_SAMPLE_C_LB",
1196249259Sdim  [(set R600_Reg128:$DST_GPR, (int_AMDGPU_txb R600_Reg128:$SRC_GPR,
1197249259Sdim      imm:$RESOURCE_ID, imm:$SAMPLER_ID, TEX_SHADOW:$textureTarget))]
1198249259Sdim>;
1199249259Sdim
1200249259Sdimdef TEX_SAMPLE_G : R600_TEX <
1201249259Sdim  0x14, "TEX_SAMPLE_G",
1202249259Sdim  []
1203249259Sdim>;
1204249259Sdim
1205249259Sdimdef TEX_SAMPLE_C_G : R600_TEX <
1206249259Sdim  0x1C, "TEX_SAMPLE_C_G",
1207249259Sdim  []
1208249259Sdim>;
1209249259Sdim
1210249259Sdim//===----------------------------------------------------------------------===//
1211249259Sdim// Helper classes for common instructions
1212249259Sdim//===----------------------------------------------------------------------===//
1213249259Sdim
1214249259Sdimclass MUL_LIT_Common <bits<5> inst> : R600_3OP <
1215249259Sdim  inst, "MUL_LIT",
1216249259Sdim  []
1217249259Sdim>;
1218249259Sdim
1219249259Sdimclass MULADD_Common <bits<5> inst> : R600_3OP <
1220249259Sdim  inst, "MULADD",
1221249259Sdim  []
1222249259Sdim>;
1223249259Sdim
1224249259Sdimclass MULADD_IEEE_Common <bits<5> inst> : R600_3OP <
1225249259Sdim  inst, "MULADD_IEEE",
1226249259Sdim  [(set (f32 R600_Reg32:$dst),
1227249259Sdim   (fadd (fmul R600_Reg32:$src0, R600_Reg32:$src1), R600_Reg32:$src2))]
1228249259Sdim>;
1229249259Sdim
1230249259Sdimclass CNDE_Common <bits<5> inst> : R600_3OP <
1231249259Sdim  inst, "CNDE",
1232249259Sdim  [(set R600_Reg32:$dst,
1233249259Sdim   (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
1234249259Sdim       (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
1235249259Sdim       COND_EQ))]
1236249259Sdim>;
1237249259Sdim
1238249259Sdimclass CNDGT_Common <bits<5> inst> : R600_3OP <
1239249259Sdim  inst, "CNDGT",
1240249259Sdim  [(set R600_Reg32:$dst,
1241249259Sdim   (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
1242249259Sdim       (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
1243249259Sdim       COND_GT))]
1244249259Sdim>;
1245249259Sdim
1246249259Sdimclass CNDGE_Common <bits<5> inst> : R600_3OP <
1247249259Sdim  inst, "CNDGE",
1248249259Sdim  [(set R600_Reg32:$dst,
1249249259Sdim   (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
1250249259Sdim       (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
1251249259Sdim       COND_GE))]
1252249259Sdim>;
1253249259Sdim
1254249259Sdimmulticlass DOT4_Common <bits<11> inst> {
1255249259Sdim
1256249259Sdim  def _pseudo : R600_REDUCTION <inst,
1257249259Sdim    (ins R600_Reg128:$src0, R600_Reg128:$src1),
1258249259Sdim    "DOT4 $dst $src0, $src1",
1259249259Sdim    [(set R600_Reg32:$dst, (int_AMDGPU_dp4 R600_Reg128:$src0, R600_Reg128:$src1))]
1260249259Sdim  >;
1261249259Sdim
1262249259Sdim  def _real : R600_2OP <inst, "DOT4", []>;
1263249259Sdim}
1264249259Sdim
1265249259Sdimlet mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
1266249259Sdimmulticlass CUBE_Common <bits<11> inst> {
1267249259Sdim
1268249259Sdim  def _pseudo : InstR600 <
1269249259Sdim    inst,
1270249259Sdim    (outs R600_Reg128:$dst),
1271249259Sdim    (ins R600_Reg128:$src),
1272249259Sdim    "CUBE $dst $src",
1273249259Sdim    [(set R600_Reg128:$dst, (int_AMDGPU_cube R600_Reg128:$src))],
1274249259Sdim    VecALU
1275249259Sdim  > {
1276249259Sdim    let isPseudo = 1;
1277249259Sdim  }
1278249259Sdim
1279249259Sdim  def _real : R600_2OP <inst, "CUBE", []>;
1280249259Sdim}
1281249259Sdim} // End mayLoad = 0, mayStore = 0, hasSideEffects = 0
1282249259Sdim
1283249259Sdimclass EXP_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
1284249259Sdim  inst, "EXP_IEEE", fexp2
1285249259Sdim>;
1286249259Sdim
1287249259Sdimclass FLT_TO_INT_Common <bits<11> inst> : R600_1OP_Helper <
1288249259Sdim  inst, "FLT_TO_INT", fp_to_sint
1289249259Sdim>;
1290249259Sdim
1291249259Sdimclass INT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
1292249259Sdim  inst, "INT_TO_FLT", sint_to_fp
1293249259Sdim>;
1294249259Sdim
1295249259Sdimclass FLT_TO_UINT_Common <bits<11> inst> : R600_1OP_Helper <
1296249259Sdim  inst, "FLT_TO_UINT", fp_to_uint
1297249259Sdim>;
1298249259Sdim
1299249259Sdimclass UINT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
1300249259Sdim  inst, "UINT_TO_FLT", uint_to_fp
1301249259Sdim>;
1302249259Sdim
1303249259Sdimclass LOG_CLAMPED_Common <bits<11> inst> : R600_1OP <
1304249259Sdim  inst, "LOG_CLAMPED", []
1305249259Sdim>;
1306249259Sdim
1307249259Sdimclass LOG_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
1308249259Sdim  inst, "LOG_IEEE", flog2
1309249259Sdim>;
1310249259Sdim
1311249259Sdimclass LSHL_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHL", shl>;
1312249259Sdimclass LSHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHR", srl>;
1313249259Sdimclass ASHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "ASHR", sra>;
1314249259Sdimclass MULHI_INT_Common <bits<11> inst> : R600_2OP_Helper <
1315249259Sdim  inst, "MULHI_INT", mulhs
1316249259Sdim>;
1317249259Sdimclass MULHI_UINT_Common <bits<11> inst> : R600_2OP_Helper <
1318249259Sdim  inst, "MULHI", mulhu
1319249259Sdim>;
1320249259Sdimclass MULLO_INT_Common <bits<11> inst> : R600_2OP_Helper <
1321249259Sdim  inst, "MULLO_INT", mul
1322249259Sdim>;
1323249259Sdimclass MULLO_UINT_Common <bits<11> inst> : R600_2OP <inst, "MULLO_UINT", []>;
1324249259Sdim
1325249259Sdimclass RECIP_CLAMPED_Common <bits<11> inst> : R600_1OP <
1326249259Sdim  inst, "RECIP_CLAMPED", []
1327249259Sdim>;
1328249259Sdim
1329249259Sdimclass RECIP_IEEE_Common <bits<11> inst> : R600_1OP <
1330249259Sdim  inst, "RECIP_IEEE", [(set R600_Reg32:$dst, (fdiv FP_ONE, R600_Reg32:$src0))]
1331249259Sdim>;
1332249259Sdim
1333249259Sdimclass RECIP_UINT_Common <bits<11> inst> : R600_1OP_Helper <
1334249259Sdim  inst, "RECIP_UINT", AMDGPUurecip
1335249259Sdim>;
1336249259Sdim
1337249259Sdimclass RECIPSQRT_CLAMPED_Common <bits<11> inst> : R600_1OP_Helper <
1338249259Sdim  inst, "RECIPSQRT_CLAMPED", int_AMDGPU_rsq
1339249259Sdim>;
1340249259Sdim
1341249259Sdimclass RECIPSQRT_IEEE_Common <bits<11> inst> : R600_1OP <
1342249259Sdim  inst, "RECIPSQRT_IEEE", []
1343249259Sdim>;
1344249259Sdim
1345249259Sdimclass SIN_Common <bits<11> inst> : R600_1OP <
1346249259Sdim  inst, "SIN", []>{
1347249259Sdim  let Trig = 1;
1348249259Sdim}
1349249259Sdim
1350249259Sdimclass COS_Common <bits<11> inst> : R600_1OP <
1351249259Sdim  inst, "COS", []> {
1352249259Sdim  let Trig = 1;
1353249259Sdim}
1354249259Sdim
1355249259Sdim//===----------------------------------------------------------------------===//
1356249259Sdim// Helper patterns for complex intrinsics
1357249259Sdim//===----------------------------------------------------------------------===//
1358249259Sdim
1359249259Sdimmulticlass DIV_Common <InstR600 recip_ieee> {
1360249259Sdimdef : Pat<
1361249259Sdim  (int_AMDGPU_div R600_Reg32:$src0, R600_Reg32:$src1),
1362249259Sdim  (MUL_IEEE R600_Reg32:$src0, (recip_ieee R600_Reg32:$src1))
1363249259Sdim>;
1364249259Sdim
1365249259Sdimdef : Pat<
1366249259Sdim  (fdiv R600_Reg32:$src0, R600_Reg32:$src1),
1367249259Sdim  (MUL_IEEE R600_Reg32:$src0, (recip_ieee R600_Reg32:$src1))
1368249259Sdim>;
1369249259Sdim}
1370249259Sdim
1371249259Sdimclass TGSI_LIT_Z_Common <InstR600 mul_lit, InstR600 log_clamped, InstR600 exp_ieee> : Pat <
1372249259Sdim  (int_TGSI_lit_z R600_Reg32:$src_x, R600_Reg32:$src_y, R600_Reg32:$src_w),
1373249259Sdim  (exp_ieee (mul_lit (log_clamped (MAX R600_Reg32:$src_y, (f32 ZERO))), R600_Reg32:$src_w, R600_Reg32:$src_x))
1374249259Sdim>;
1375249259Sdim
1376249259Sdim//===----------------------------------------------------------------------===//
1377249259Sdim// R600 / R700 Instructions
1378249259Sdim//===----------------------------------------------------------------------===//
1379249259Sdim
1380249259Sdimlet Predicates = [isR600] in {
1381249259Sdim
1382249259Sdim  def MUL_LIT_r600 : MUL_LIT_Common<0x0C>;
1383249259Sdim  def MULADD_r600 : MULADD_Common<0x10>;
1384249259Sdim  def MULADD_IEEE_r600 : MULADD_IEEE_Common<0x14>;
1385249259Sdim  def CNDE_r600 : CNDE_Common<0x18>;
1386249259Sdim  def CNDGT_r600 : CNDGT_Common<0x19>;
1387249259Sdim  def CNDGE_r600 : CNDGE_Common<0x1A>;
1388249259Sdim  defm DOT4_r600 : DOT4_Common<0x50>;
1389249259Sdim  defm CUBE_r600 : CUBE_Common<0x52>;
1390249259Sdim  def EXP_IEEE_r600 : EXP_IEEE_Common<0x61>;
1391249259Sdim  def LOG_CLAMPED_r600 : LOG_CLAMPED_Common<0x62>;
1392249259Sdim  def LOG_IEEE_r600 : LOG_IEEE_Common<0x63>;
1393249259Sdim  def RECIP_CLAMPED_r600 : RECIP_CLAMPED_Common<0x64>;
1394249259Sdim  def RECIP_IEEE_r600 : RECIP_IEEE_Common<0x66>;
1395249259Sdim  def RECIPSQRT_CLAMPED_r600 : RECIPSQRT_CLAMPED_Common<0x67>;
1396249259Sdim  def RECIPSQRT_IEEE_r600 : RECIPSQRT_IEEE_Common<0x69>;
1397249259Sdim  def FLT_TO_INT_r600 : FLT_TO_INT_Common<0x6b>;
1398249259Sdim  def INT_TO_FLT_r600 : INT_TO_FLT_Common<0x6c>;
1399249259Sdim  def FLT_TO_UINT_r600 : FLT_TO_UINT_Common<0x79>;
1400249259Sdim  def UINT_TO_FLT_r600 : UINT_TO_FLT_Common<0x6d>;
1401249259Sdim  def SIN_r600 : SIN_Common<0x6E>;
1402249259Sdim  def COS_r600 : COS_Common<0x6F>;
1403249259Sdim  def ASHR_r600 : ASHR_Common<0x70>;
1404249259Sdim  def LSHR_r600 : LSHR_Common<0x71>;
1405249259Sdim  def LSHL_r600 : LSHL_Common<0x72>;
1406249259Sdim  def MULLO_INT_r600 : MULLO_INT_Common<0x73>;
1407249259Sdim  def MULHI_INT_r600 : MULHI_INT_Common<0x74>;
1408249259Sdim  def MULLO_UINT_r600 : MULLO_UINT_Common<0x75>;
1409249259Sdim  def MULHI_UINT_r600 : MULHI_UINT_Common<0x76>;
1410249259Sdim  def RECIP_UINT_r600 : RECIP_UINT_Common <0x78>;
1411249259Sdim
1412249259Sdim  defm DIV_r600 : DIV_Common<RECIP_IEEE_r600>;
1413249259Sdim  def : POW_Common <LOG_IEEE_r600, EXP_IEEE_r600, MUL, R600_Reg32>;
1414249259Sdim  def TGSI_LIT_Z_r600 : TGSI_LIT_Z_Common<MUL_LIT_r600, LOG_CLAMPED_r600, EXP_IEEE_r600>;
1415249259Sdim
1416249259Sdim  def : Pat<(fsqrt R600_Reg32:$src),
1417249259Sdim    (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_r600 R600_Reg32:$src))>;
1418249259Sdim
1419249259Sdim  def R600_ExportSwz : ExportSwzInst {
1420249259Sdim    let Word1{20-17} = 1; // BURST_COUNT
1421249259Sdim    let Word1{21} = eop;
1422249259Sdim    let Word1{22} = 1; // VALID_PIXEL_MODE
1423249259Sdim    let Word1{30-23} = inst;
1424249259Sdim    let Word1{31} = 1; // BARRIER
1425249259Sdim  }
1426249259Sdim  defm : ExportPattern<R600_ExportSwz, 39>;
1427249259Sdim
1428249259Sdim  def R600_ExportBuf : ExportBufInst {
1429249259Sdim    let Word1{20-17} = 1; // BURST_COUNT
1430249259Sdim    let Word1{21} = eop;
1431249259Sdim    let Word1{22} = 1; // VALID_PIXEL_MODE
1432249259Sdim    let Word1{30-23} = inst;
1433249259Sdim    let Word1{31} = 1; // BARRIER
1434249259Sdim  }
1435249259Sdim  defm : SteamOutputExportPattern<R600_ExportBuf, 0x20, 0x21, 0x22, 0x23>;
1436249259Sdim}
1437249259Sdim
1438249259Sdim// Helper pattern for normalizing inputs to triginomic instructions for R700+
1439249259Sdim// cards.
1440249259Sdimclass COS_PAT <InstR600 trig> : Pat<
1441249259Sdim  (fcos R600_Reg32:$src),
1442249259Sdim  (trig (MUL_IEEE (MOV_IMM_I32 CONST.TWO_PI_INV), R600_Reg32:$src))
1443249259Sdim>;
1444249259Sdim
1445249259Sdimclass SIN_PAT <InstR600 trig> : Pat<
1446249259Sdim  (fsin R600_Reg32:$src),
1447249259Sdim  (trig (MUL_IEEE (MOV_IMM_I32 CONST.TWO_PI_INV), R600_Reg32:$src))
1448249259Sdim>;
1449249259Sdim
1450249259Sdim//===----------------------------------------------------------------------===//
1451249259Sdim// R700 Only instructions
1452249259Sdim//===----------------------------------------------------------------------===//
1453249259Sdim
1454249259Sdimlet Predicates = [isR700] in {
1455249259Sdim  def SIN_r700 : SIN_Common<0x6E>;
1456249259Sdim  def COS_r700 : COS_Common<0x6F>;
1457249259Sdim
1458249259Sdim  // R700 normalizes inputs to SIN/COS the same as EG
1459249259Sdim  def : SIN_PAT <SIN_r700>;
1460249259Sdim  def : COS_PAT <COS_r700>;
1461249259Sdim}
1462249259Sdim
1463249259Sdim//===----------------------------------------------------------------------===//
1464249259Sdim// Evergreen Only instructions
1465249259Sdim//===----------------------------------------------------------------------===//
1466249259Sdim
1467249259Sdimlet Predicates = [isEG] in {
1468249259Sdim
1469249259Sdimdef RECIP_IEEE_eg : RECIP_IEEE_Common<0x86>;
1470249259Sdimdefm DIV_eg : DIV_Common<RECIP_IEEE_eg>;
1471249259Sdim
1472249259Sdimdef MULLO_INT_eg : MULLO_INT_Common<0x8F>;
1473249259Sdimdef MULHI_INT_eg : MULHI_INT_Common<0x90>;
1474249259Sdimdef MULLO_UINT_eg : MULLO_UINT_Common<0x91>;
1475249259Sdimdef MULHI_UINT_eg : MULHI_UINT_Common<0x92>;
1476249259Sdimdef RECIP_UINT_eg : RECIP_UINT_Common<0x94>;
1477249259Sdimdef RECIPSQRT_CLAMPED_eg : RECIPSQRT_CLAMPED_Common<0x87>;
1478249259Sdimdef EXP_IEEE_eg : EXP_IEEE_Common<0x81>;
1479249259Sdimdef LOG_IEEE_eg : LOG_IEEE_Common<0x83>;
1480249259Sdimdef RECIP_CLAMPED_eg : RECIP_CLAMPED_Common<0x84>;
1481249259Sdimdef RECIPSQRT_IEEE_eg : RECIPSQRT_IEEE_Common<0x89>;
1482249259Sdimdef SIN_eg : SIN_Common<0x8D>;
1483249259Sdimdef COS_eg : COS_Common<0x8E>;
1484249259Sdim
1485249259Sdimdef : POW_Common <LOG_IEEE_eg, EXP_IEEE_eg, MUL, R600_Reg32>;
1486249259Sdimdef : SIN_PAT <SIN_eg>;
1487249259Sdimdef : COS_PAT <COS_eg>;
1488249259Sdimdef : Pat<(fsqrt R600_Reg32:$src),
1489249259Sdim  (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_eg R600_Reg32:$src))>;
1490249259Sdim} // End Predicates = [isEG]
1491249259Sdim
1492249259Sdim//===----------------------------------------------------------------------===//
1493249259Sdim// Evergreen / Cayman Instructions
1494249259Sdim//===----------------------------------------------------------------------===//
1495249259Sdim
1496249259Sdimlet Predicates = [isEGorCayman] in {
1497249259Sdim
1498249259Sdim  // BFE_UINT - bit_extract, an optimization for mask and shift
1499249259Sdim  // Src0 = Input
1500249259Sdim  // Src1 = Offset
1501249259Sdim  // Src2 = Width
1502249259Sdim  //
1503249259Sdim  // bit_extract = (Input << (32 - Offset - Width)) >> (32 - Width)
1504249259Sdim  //
1505249259Sdim  // Example Usage:
1506249259Sdim  // (Offset, Width)
1507249259Sdim  //
1508249259Sdim  // (0, 8)           = (Input << 24) >> 24  = (Input &  0xff)       >> 0
1509249259Sdim  // (8, 8)           = (Input << 16) >> 24  = (Input &  0xffff)     >> 8
1510249259Sdim  // (16,8)           = (Input <<  8) >> 24  = (Input &  0xffffff)   >> 16
1511249259Sdim  // (24,8)           = (Input <<  0) >> 24  = (Input &  0xffffffff) >> 24
1512249259Sdim  def BFE_UINT_eg : R600_3OP <0x4, "BFE_UINT",
1513249259Sdim    [(set R600_Reg32:$dst, (int_AMDIL_bit_extract_u32 R600_Reg32:$src0,
1514249259Sdim                                                      R600_Reg32:$src1,
1515249259Sdim                                                      R600_Reg32:$src2))],
1516249259Sdim    VecALU
1517249259Sdim  >;
1518249259Sdim
1519249259Sdim  def BIT_ALIGN_INT_eg : R600_3OP <0xC, "BIT_ALIGN_INT",
1520249259Sdim    [(set R600_Reg32:$dst, (AMDGPUbitalign R600_Reg32:$src0, R600_Reg32:$src1,
1521249259Sdim                                          R600_Reg32:$src2))],
1522249259Sdim    VecALU
1523249259Sdim  >;
1524249259Sdim
1525249259Sdim  def MULADD_eg : MULADD_Common<0x14>;
1526249259Sdim  def MULADD_IEEE_eg : MULADD_IEEE_Common<0x18>;
1527249259Sdim  def ASHR_eg : ASHR_Common<0x15>;
1528249259Sdim  def LSHR_eg : LSHR_Common<0x16>;
1529249259Sdim  def LSHL_eg : LSHL_Common<0x17>;
1530249259Sdim  def CNDE_eg : CNDE_Common<0x19>;
1531249259Sdim  def CNDGT_eg : CNDGT_Common<0x1A>;
1532249259Sdim  def CNDGE_eg : CNDGE_Common<0x1B>;
1533249259Sdim  def MUL_LIT_eg : MUL_LIT_Common<0x1F>;
1534249259Sdim  def LOG_CLAMPED_eg : LOG_CLAMPED_Common<0x82>;
1535249259Sdim  defm DOT4_eg : DOT4_Common<0xBE>;
1536249259Sdim  defm CUBE_eg : CUBE_Common<0xC0>;
1537249259Sdim
1538249259Sdimlet hasSideEffects = 1 in {
1539249259Sdim  def MOVA_INT_eg : R600_1OP <0xCC, "MOVA_INT", []>;
1540249259Sdim}
1541249259Sdim
1542249259Sdim  def TGSI_LIT_Z_eg : TGSI_LIT_Z_Common<MUL_LIT_eg, LOG_CLAMPED_eg, EXP_IEEE_eg>;
1543249259Sdim
1544249259Sdim  def FLT_TO_INT_eg : FLT_TO_INT_Common<0x50> {
1545249259Sdim    let Pattern = [];
1546249259Sdim  }
1547249259Sdim
1548249259Sdim  def INT_TO_FLT_eg : INT_TO_FLT_Common<0x9B>;
1549249259Sdim
1550249259Sdim  def FLT_TO_UINT_eg : FLT_TO_UINT_Common<0x9A> {
1551249259Sdim    let Pattern = [];
1552249259Sdim  }
1553249259Sdim
1554249259Sdim  def UINT_TO_FLT_eg : UINT_TO_FLT_Common<0x9C>;
1555249259Sdim
1556249259Sdim  // TRUNC is used for the FLT_TO_INT instructions to work around a
1557249259Sdim  // perceived problem where the rounding modes are applied differently
1558249259Sdim  // depending on the instruction and the slot they are in.
1559249259Sdim  // See:
1560249259Sdim  // https://bugs.freedesktop.org/show_bug.cgi?id=50232
1561249259Sdim  // Mesa commit: a1a0974401c467cb86ef818f22df67c21774a38c
1562249259Sdim  //
1563249259Sdim  // XXX: Lowering SELECT_CC will sometimes generate fp_to_[su]int nodes,
1564249259Sdim  // which do not need to be truncated since the fp values are 0.0f or 1.0f.
1565249259Sdim  // We should look into handling these cases separately.
1566249259Sdim  def : Pat<(fp_to_sint R600_Reg32:$src0),
1567249259Sdim    (FLT_TO_INT_eg (TRUNC R600_Reg32:$src0))>;
1568249259Sdim
1569249259Sdim  def : Pat<(fp_to_uint R600_Reg32:$src0),
1570249259Sdim    (FLT_TO_UINT_eg (TRUNC R600_Reg32:$src0))>;
1571249259Sdim
1572249259Sdim  def EG_ExportSwz : ExportSwzInst {
1573249259Sdim    let Word1{19-16} = 1; // BURST_COUNT
1574249259Sdim    let Word1{20} = 1; // VALID_PIXEL_MODE
1575249259Sdim    let Word1{21} = eop;
1576249259Sdim    let Word1{29-22} = inst;
1577249259Sdim    let Word1{30} = 0; // MARK
1578249259Sdim    let Word1{31} = 1; // BARRIER
1579249259Sdim  }
1580249259Sdim  defm : ExportPattern<EG_ExportSwz, 83>;
1581249259Sdim
1582249259Sdim  def EG_ExportBuf : ExportBufInst {
1583249259Sdim    let Word1{19-16} = 1; // BURST_COUNT
1584249259Sdim    let Word1{20} = 1; // VALID_PIXEL_MODE
1585249259Sdim    let Word1{21} = eop;
1586249259Sdim    let Word1{29-22} = inst;
1587249259Sdim    let Word1{30} = 0; // MARK
1588249259Sdim    let Word1{31} = 1; // BARRIER
1589249259Sdim  }
1590249259Sdim  defm : SteamOutputExportPattern<EG_ExportBuf, 0x40, 0x41, 0x42, 0x43>;
1591249259Sdim
1592249259Sdim//===----------------------------------------------------------------------===//
1593249259Sdim// Memory read/write instructions
1594249259Sdim//===----------------------------------------------------------------------===//
1595249259Sdimlet usesCustomInserter = 1 in {
1596249259Sdim
1597249259Sdimclass RAT_WRITE_CACHELESS_eg <dag ins, bits<4> comp_mask, string name,
1598249259Sdim                              list<dag> pattern>
1599249259Sdim    : EG_CF_RAT <0x57, 0x2, 0, (outs), ins,
1600249259Sdim                 !strconcat(name, " $rw_gpr, $index_gpr, $eop"), pattern> {
1601249259Sdim  let RIM         = 0;
1602249259Sdim  // XXX: Have a separate instruction for non-indexed writes.
1603249259Sdim  let TYPE        = 1;
1604249259Sdim  let RW_REL      = 0;
1605249259Sdim  let ELEM_SIZE   = 0;
1606249259Sdim
1607249259Sdim  let ARRAY_SIZE  = 0;
1608249259Sdim  let COMP_MASK   = comp_mask;
1609249259Sdim  let BURST_COUNT = 0;
1610249259Sdim  let VPM         = 0;
1611249259Sdim  let MARK        = 0;
1612249259Sdim  let BARRIER     = 1;
1613249259Sdim}
1614249259Sdim
1615249259Sdim} // End usesCustomInserter = 1
1616249259Sdim
1617249259Sdim// 32-bit store
1618249259Sdimdef RAT_WRITE_CACHELESS_32_eg : RAT_WRITE_CACHELESS_eg <
1619249259Sdim  (ins R600_TReg32_X:$rw_gpr, R600_TReg32_X:$index_gpr, InstFlag:$eop),
1620249259Sdim  0x1, "RAT_WRITE_CACHELESS_32_eg",
1621249259Sdim  [(global_store (i32 R600_TReg32_X:$rw_gpr), R600_TReg32_X:$index_gpr)]
1622249259Sdim>;
1623249259Sdim
1624249259Sdim//128-bit store
1625249259Sdimdef RAT_WRITE_CACHELESS_128_eg : RAT_WRITE_CACHELESS_eg <
1626249259Sdim  (ins R600_Reg128:$rw_gpr, R600_TReg32_X:$index_gpr, InstFlag:$eop),
1627249259Sdim  0xf, "RAT_WRITE_CACHELESS_128",
1628249259Sdim  [(global_store (v4i32 R600_Reg128:$rw_gpr), R600_TReg32_X:$index_gpr)]
1629249259Sdim>;
1630249259Sdim
1631249259Sdimclass VTX_READ_eg <string name, bits<8> buffer_id, dag outs, list<dag> pattern>
1632249259Sdim    : InstR600ISA <outs, (ins MEMxi:$ptr), name#" $dst, $ptr", pattern>,
1633249259Sdim      VTX_WORD1_GPR, VTX_WORD0 {
1634249259Sdim
1635249259Sdim  // Static fields
1636249259Sdim  let VC_INST = 0;
1637249259Sdim  let FETCH_TYPE = 2;
1638249259Sdim  let FETCH_WHOLE_QUAD = 0;
1639249259Sdim  let BUFFER_ID = buffer_id;
1640249259Sdim  let SRC_REL = 0;
1641249259Sdim  // XXX: We can infer this field based on the SRC_GPR.  This would allow us
1642249259Sdim  // to store vertex addresses in any channel, not just X.
1643249259Sdim  let SRC_SEL_X = 0;
1644249259Sdim  let DST_REL = 0;
1645249259Sdim  // The docs say that if this bit is set, then DATA_FORMAT, NUM_FORMAT_ALL,
1646249259Sdim  // FORMAT_COMP_ALL, SRF_MODE_ALL, and ENDIAN_SWAP fields will be ignored,
1647249259Sdim  // however, based on my testing if USE_CONST_FIELDS is set, then all
1648249259Sdim  // these fields need to be set to 0.
1649249259Sdim  let USE_CONST_FIELDS = 0;
1650249259Sdim  let NUM_FORMAT_ALL = 1;
1651249259Sdim  let FORMAT_COMP_ALL = 0;
1652249259Sdim  let SRF_MODE_ALL = 0;
1653249259Sdim
1654249259Sdim  let Inst{31-0} = Word0;
1655249259Sdim  let Inst{63-32} = Word1;
1656249259Sdim  // LLVM can only encode 64-bit instructions, so these fields are manually
1657249259Sdim  // encoded in R600CodeEmitter
1658249259Sdim  //
1659249259Sdim  // bits<16> OFFSET;
1660249259Sdim  // bits<2>  ENDIAN_SWAP = 0;
1661249259Sdim  // bits<1>  CONST_BUF_NO_STRIDE = 0;
1662249259Sdim  // bits<1>  MEGA_FETCH = 0;
1663249259Sdim  // bits<1>  ALT_CONST = 0;
1664249259Sdim  // bits<2>  BUFFER_INDEX_MODE = 0;
1665249259Sdim
1666249259Sdim
1667249259Sdim
1668249259Sdim  // VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
1669249259Sdim  // is done in R600CodeEmitter
1670249259Sdim  //
1671249259Sdim  // Inst{79-64} = OFFSET;
1672249259Sdim  // Inst{81-80} = ENDIAN_SWAP;
1673249259Sdim  // Inst{82}    = CONST_BUF_NO_STRIDE;
1674249259Sdim  // Inst{83}    = MEGA_FETCH;
1675249259Sdim  // Inst{84}    = ALT_CONST;
1676249259Sdim  // Inst{86-85} = BUFFER_INDEX_MODE;
1677249259Sdim  // Inst{95-86} = 0; Reserved
1678249259Sdim
1679249259Sdim  // VTX_WORD3 (Padding)
1680249259Sdim  //
1681249259Sdim  // Inst{127-96} = 0;
1682249259Sdim}
1683249259Sdim
1684249259Sdimclass VTX_READ_8_eg <bits<8> buffer_id, list<dag> pattern>
1685249259Sdim    : VTX_READ_eg <"VTX_READ_8", buffer_id, (outs R600_TReg32_X:$dst),
1686249259Sdim                   pattern> {
1687249259Sdim
1688249259Sdim  let MEGA_FETCH_COUNT = 1;
1689249259Sdim  let DST_SEL_X = 0;
1690249259Sdim  let DST_SEL_Y = 7;   // Masked
1691249259Sdim  let DST_SEL_Z = 7;   // Masked
1692249259Sdim  let DST_SEL_W = 7;   // Masked
1693249259Sdim  let DATA_FORMAT = 1; // FMT_8
1694249259Sdim}
1695249259Sdim
1696249259Sdimclass VTX_READ_16_eg <bits<8> buffer_id, list<dag> pattern>
1697249259Sdim    : VTX_READ_eg <"VTX_READ_16", buffer_id, (outs R600_TReg32_X:$dst),
1698249259Sdim                    pattern> {
1699249259Sdim  let MEGA_FETCH_COUNT = 2;
1700249259Sdim  let DST_SEL_X = 0;
1701249259Sdim  let DST_SEL_Y = 7;   // Masked
1702249259Sdim  let DST_SEL_Z = 7;   // Masked
1703249259Sdim  let DST_SEL_W = 7;   // Masked
1704249259Sdim  let DATA_FORMAT = 5; // FMT_16
1705249259Sdim
1706249259Sdim}
1707249259Sdim
1708249259Sdimclass VTX_READ_32_eg <bits<8> buffer_id, list<dag> pattern>
1709249259Sdim    : VTX_READ_eg <"VTX_READ_32", buffer_id, (outs R600_TReg32_X:$dst),
1710249259Sdim                   pattern> {
1711249259Sdim
1712249259Sdim  let MEGA_FETCH_COUNT = 4;
1713249259Sdim  let DST_SEL_X        = 0;
1714249259Sdim  let DST_SEL_Y        = 7;   // Masked
1715249259Sdim  let DST_SEL_Z        = 7;   // Masked
1716249259Sdim  let DST_SEL_W        = 7;   // Masked
1717249259Sdim  let DATA_FORMAT      = 0xD; // COLOR_32
1718249259Sdim
1719249259Sdim  // This is not really necessary, but there were some GPU hangs that appeared
1720249259Sdim  // to be caused by ALU instructions in the next instruction group that wrote
1721249259Sdim  // to the $ptr registers of the VTX_READ.
1722249259Sdim  // e.g.
1723249259Sdim  // %T3_X<def> = VTX_READ_PARAM_32_eg %T2_X<kill>, 24
1724249259Sdim  // %T2_X<def> = MOV %ZERO
1725249259Sdim  //Adding this constraint prevents this from happening.
1726249259Sdim  let Constraints = "$ptr.ptr = $dst";
1727249259Sdim}
1728249259Sdim
1729249259Sdimclass VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern>
1730249259Sdim    : VTX_READ_eg <"VTX_READ_128", buffer_id, (outs R600_Reg128:$dst),
1731249259Sdim                   pattern> {
1732249259Sdim
1733249259Sdim  let MEGA_FETCH_COUNT = 16;
1734249259Sdim  let DST_SEL_X        =  0;
1735249259Sdim  let DST_SEL_Y        =  1;
1736249259Sdim  let DST_SEL_Z        =  2;
1737249259Sdim  let DST_SEL_W        =  3;
1738249259Sdim  let DATA_FORMAT      =  0x22; // COLOR_32_32_32_32
1739249259Sdim
1740249259Sdim  // XXX: Need to force VTX_READ_128 instructions to write to the same register
1741249259Sdim  // that holds its buffer address to avoid potential hangs.  We can't use
1742249259Sdim  // the same constraint as VTX_READ_32_eg, because the $ptr.ptr and $dst
1743249259Sdim  // registers are different sizes.
1744249259Sdim}
1745249259Sdim
1746249259Sdim//===----------------------------------------------------------------------===//
1747249259Sdim// VTX Read from parameter memory space
1748249259Sdim//===----------------------------------------------------------------------===//
1749249259Sdim
1750249259Sdimdef VTX_READ_PARAM_8_eg : VTX_READ_8_eg <0,
1751249259Sdim  [(set (i32 R600_TReg32_X:$dst), (load_param_zexti8 ADDRVTX_READ:$ptr))]
1752249259Sdim>;
1753249259Sdim
1754249259Sdimdef VTX_READ_PARAM_16_eg : VTX_READ_16_eg <0,
1755249259Sdim  [(set (i32 R600_TReg32_X:$dst), (load_param_zexti16 ADDRVTX_READ:$ptr))]
1756249259Sdim>;
1757249259Sdim
1758249259Sdimdef VTX_READ_PARAM_32_eg : VTX_READ_32_eg <0,
1759249259Sdim  [(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))]
1760249259Sdim>;
1761249259Sdim
1762249259Sdimdef VTX_READ_PARAM_128_eg : VTX_READ_128_eg <0,
1763249259Sdim  [(set (v4i32 R600_Reg128:$dst), (load_param ADDRVTX_READ:$ptr))]
1764249259Sdim>;
1765249259Sdim
1766249259Sdim//===----------------------------------------------------------------------===//
1767249259Sdim// VTX Read from global memory space
1768249259Sdim//===----------------------------------------------------------------------===//
1769249259Sdim
1770249259Sdim// 8-bit reads
1771249259Sdimdef VTX_READ_GLOBAL_8_eg : VTX_READ_8_eg <1,
1772249259Sdim  [(set (i32 R600_TReg32_X:$dst), (zextloadi8_global ADDRVTX_READ:$ptr))]
1773249259Sdim>;
1774249259Sdim
1775249259Sdim// 32-bit reads
1776249259Sdimdef VTX_READ_GLOBAL_32_eg : VTX_READ_32_eg <1,
1777249259Sdim  [(set (i32 R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))]
1778249259Sdim>;
1779249259Sdim
1780249259Sdim// 128-bit reads
1781249259Sdimdef VTX_READ_GLOBAL_128_eg : VTX_READ_128_eg <1,
1782249259Sdim  [(set (v4i32 R600_Reg128:$dst), (global_load ADDRVTX_READ:$ptr))]
1783249259Sdim>;
1784249259Sdim
1785249259Sdim//===----------------------------------------------------------------------===//
1786249259Sdim// Constant Loads
1787249259Sdim// XXX: We are currently storing all constants in the global address space.
1788249259Sdim//===----------------------------------------------------------------------===//
1789249259Sdim
1790249259Sdimdef CONSTANT_LOAD_eg : VTX_READ_32_eg <1,
1791249259Sdim  [(set (i32 R600_TReg32_X:$dst), (constant_load ADDRVTX_READ:$ptr))]
1792249259Sdim>;
1793249259Sdim
1794249259Sdim}
1795249259Sdim
1796249259Sdim//===----------------------------------------------------------------------===//
1797249259Sdim// Regist loads and stores - for indirect addressing
1798249259Sdim//===----------------------------------------------------------------------===//
1799249259Sdim
1800249259Sdimdefm R600_ : RegisterLoadStore <R600_Reg32, FRAMEri, ADDRIndirect>;
1801249259Sdim
1802249259Sdimlet Predicates = [isCayman] in {
1803249259Sdim
1804249259Sdimlet isVector = 1 in {
1805249259Sdim
1806249259Sdimdef RECIP_IEEE_cm : RECIP_IEEE_Common<0x86>;
1807249259Sdim
1808249259Sdimdef MULLO_INT_cm : MULLO_INT_Common<0x8F>;
1809249259Sdimdef MULHI_INT_cm : MULHI_INT_Common<0x90>;
1810249259Sdimdef MULLO_UINT_cm : MULLO_UINT_Common<0x91>;
1811249259Sdimdef MULHI_UINT_cm : MULHI_UINT_Common<0x92>;
1812249259Sdimdef RECIPSQRT_CLAMPED_cm : RECIPSQRT_CLAMPED_Common<0x87>;
1813249259Sdimdef EXP_IEEE_cm : EXP_IEEE_Common<0x81>;
1814249259Sdimdef LOG_IEEE_cm : LOG_IEEE_Common<0x83>;
1815249259Sdimdef RECIP_CLAMPED_cm : RECIP_CLAMPED_Common<0x84>;
1816249259Sdimdef RECIPSQRT_IEEE_cm : RECIPSQRT_IEEE_Common<0x89>;
1817249259Sdimdef SIN_cm : SIN_Common<0x8D>;
1818249259Sdimdef COS_cm : COS_Common<0x8E>;
1819249259Sdim} // End isVector = 1
1820249259Sdim
1821249259Sdimdef : POW_Common <LOG_IEEE_cm, EXP_IEEE_cm, MUL, R600_Reg32>;
1822249259Sdimdef : SIN_PAT <SIN_cm>;
1823249259Sdimdef : COS_PAT <COS_cm>;
1824249259Sdim
1825249259Sdimdefm DIV_cm : DIV_Common<RECIP_IEEE_cm>;
1826249259Sdim
1827249259Sdim// RECIP_UINT emulation for Cayman
1828249259Sdimdef : Pat <
1829249259Sdim  (AMDGPUurecip R600_Reg32:$src0),
1830249259Sdim  (FLT_TO_UINT_eg (MUL_IEEE (RECIP_IEEE_cm (UINT_TO_FLT_eg R600_Reg32:$src0)),
1831249259Sdim                            (MOV_IMM_I32 0x4f800000)))
1832249259Sdim>;
1833249259Sdim
1834249259Sdim
1835249259Sdimdef : Pat<(fsqrt R600_Reg32:$src),
1836249259Sdim  (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_cm R600_Reg32:$src))>;
1837249259Sdim
1838249259Sdim} // End isCayman
1839249259Sdim
1840249259Sdim//===----------------------------------------------------------------------===//
1841249259Sdim// Branch Instructions
1842249259Sdim//===----------------------------------------------------------------------===//
1843249259Sdim
1844249259Sdim
1845249259Sdimdef IF_PREDICATE_SET  : ILFormat<(outs), (ins GPRI32:$src),
1846249259Sdim  "IF_PREDICATE_SET $src", []>;
1847249259Sdim
1848249259Sdimdef PREDICATED_BREAK : ILFormat<(outs), (ins GPRI32:$src),
1849249259Sdim  "PREDICATED_BREAK $src", []>;
1850249259Sdim
1851249259Sdim//===----------------------------------------------------------------------===//
1852249259Sdim// Pseudo instructions
1853249259Sdim//===----------------------------------------------------------------------===//
1854249259Sdim
1855249259Sdimlet isPseudo = 1 in {
1856249259Sdim
1857249259Sdimdef PRED_X : InstR600 <
1858249259Sdim  0, (outs R600_Predicate_Bit:$dst),
1859249259Sdim  (ins R600_Reg32:$src0, i32imm:$src1, i32imm:$flags),
1860249259Sdim  "", [], NullALU> {
1861249259Sdim  let FlagOperandIdx = 3;
1862249259Sdim}
1863249259Sdim
1864249259Sdimlet isTerminator = 1, isBranch = 1 in {
1865249259Sdimdef JUMP_COND : InstR600 <0x10,
1866249259Sdim          (outs),
1867249259Sdim          (ins brtarget:$target, R600_Predicate_Bit:$p),
1868249259Sdim          "JUMP $target ($p)",
1869249259Sdim          [], AnyALU
1870249259Sdim  >;
1871249259Sdim
1872249259Sdimdef JUMP : InstR600 <0x10,
1873249259Sdim          (outs),
1874249259Sdim          (ins brtarget:$target),
1875249259Sdim          "JUMP $target",
1876249259Sdim          [], AnyALU
1877249259Sdim  >
1878249259Sdim{
1879249259Sdim  let isPredicable = 1;
1880249259Sdim  let isBarrier = 1;
1881249259Sdim}
1882249259Sdim
1883249259Sdim}  // End isTerminator = 1, isBranch = 1
1884249259Sdim
1885249259Sdimlet usesCustomInserter = 1 in {
1886249259Sdim
1887249259Sdimlet mayLoad = 0, mayStore = 0, hasSideEffects = 1 in {
1888249259Sdim
1889249259Sdimdef MASK_WRITE : AMDGPUShaderInst <
1890249259Sdim    (outs),
1891249259Sdim    (ins R600_Reg32:$src),
1892249259Sdim    "MASK_WRITE $src",
1893249259Sdim    []
1894249259Sdim>;
1895249259Sdim
1896249259Sdim} // End mayLoad = 0, mayStore = 0, hasSideEffects = 1
1897249259Sdim
1898249259Sdim
1899249259Sdimdef TXD: AMDGPUShaderInst <
1900249259Sdim  (outs R600_Reg128:$dst),
1901249259Sdim  (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
1902249259Sdim  "TXD $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget",
1903249259Sdim  [(set R600_Reg128:$dst, (int_AMDGPU_txd R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
1904249259Sdim>;
1905249259Sdim
1906249259Sdimdef TXD_SHADOW: AMDGPUShaderInst <
1907249259Sdim  (outs R600_Reg128:$dst),
1908249259Sdim  (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
1909249259Sdim  "TXD_SHADOW $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget",
1910249259Sdim  [(set R600_Reg128:$dst, (int_AMDGPU_txd R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, imm:$resourceId, imm:$samplerId, TEX_SHADOW:$textureTarget))]
1911249259Sdim>;
1912249259Sdim
1913249259Sdim} // End isPseudo = 1
1914249259Sdim} // End usesCustomInserter = 1
1915249259Sdim
1916249259Sdimdef CLAMP_R600 :  CLAMP <R600_Reg32>;
1917249259Sdimdef FABS_R600 : FABS<R600_Reg32>;
1918249259Sdimdef FNEG_R600 : FNEG<R600_Reg32>;
1919249259Sdim
1920249259Sdim//===---------------------------------------------------------------------===//
1921249259Sdim// Return instruction
1922249259Sdim//===---------------------------------------------------------------------===//
1923249259Sdimlet isTerminator = 1, isReturn = 1, hasCtrlDep = 1,
1924249259Sdim    usesCustomInserter = 1 in {
1925249259Sdim  def RETURN          : ILFormat<(outs), (ins variable_ops),
1926249259Sdim      "RETURN", [(IL_retflag)]>;
1927249259Sdim}
1928249259Sdim
1929249259Sdim
1930249259Sdim//===----------------------------------------------------------------------===//
1931249259Sdim// Constant Buffer Addressing Support
1932249259Sdim//===----------------------------------------------------------------------===//
1933249259Sdim
1934249259Sdimlet usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU"  in {
1935249259Sdimdef CONST_COPY : Instruction {
1936249259Sdim  let OutOperandList = (outs R600_Reg32:$dst);
1937249259Sdim  let InOperandList = (ins i32imm:$src);
1938249259Sdim  let Pattern =
1939249259Sdim      [(set R600_Reg32:$dst, (CONST_ADDRESS ADDRGA_CONST_OFFSET:$src))];
1940249259Sdim  let AsmString = "CONST_COPY";
1941249259Sdim  let neverHasSideEffects = 1;
1942249259Sdim  let isAsCheapAsAMove = 1;
1943249259Sdim  let Itinerary = NullALU;
1944249259Sdim}
1945249259Sdim} // end usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU"
1946249259Sdim
1947249259Sdimdef TEX_VTX_CONSTBUF :
1948249259Sdim  InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr, i32imm:$BUFFER_ID), "VTX_READ_eg $dst, $ptr",
1949249259Sdim      [(set R600_Reg128:$dst, (CONST_ADDRESS ADDRGA_VAR_OFFSET:$ptr, (i32 imm:$BUFFER_ID)))]>,
1950249259Sdim  VTX_WORD1_GPR, VTX_WORD0 {
1951249259Sdim
1952249259Sdim  let VC_INST = 0;
1953249259Sdim  let FETCH_TYPE = 2;
1954249259Sdim  let FETCH_WHOLE_QUAD = 0;
1955249259Sdim  let SRC_REL = 0;
1956249259Sdim  let SRC_SEL_X = 0;
1957249259Sdim  let DST_REL = 0;
1958249259Sdim  let USE_CONST_FIELDS = 0;
1959249259Sdim  let NUM_FORMAT_ALL = 2;
1960249259Sdim  let FORMAT_COMP_ALL = 1;
1961249259Sdim  let SRF_MODE_ALL = 1;
1962249259Sdim  let MEGA_FETCH_COUNT = 16;
1963249259Sdim  let DST_SEL_X        = 0;
1964249259Sdim  let DST_SEL_Y        = 1;
1965249259Sdim  let DST_SEL_Z        = 2;
1966249259Sdim  let DST_SEL_W        = 3;
1967249259Sdim  let DATA_FORMAT      = 35;
1968249259Sdim
1969249259Sdim  let Inst{31-0} = Word0;
1970249259Sdim  let Inst{63-32} = Word1;
1971249259Sdim
1972249259Sdim// LLVM can only encode 64-bit instructions, so these fields are manually
1973249259Sdim// encoded in R600CodeEmitter
1974249259Sdim//
1975249259Sdim// bits<16> OFFSET;
1976249259Sdim// bits<2>  ENDIAN_SWAP = 0;
1977249259Sdim// bits<1>  CONST_BUF_NO_STRIDE = 0;
1978249259Sdim// bits<1>  MEGA_FETCH = 0;
1979249259Sdim// bits<1>  ALT_CONST = 0;
1980249259Sdim// bits<2>  BUFFER_INDEX_MODE = 0;
1981249259Sdim
1982249259Sdim
1983249259Sdim
1984249259Sdim// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
1985249259Sdim// is done in R600CodeEmitter
1986249259Sdim//
1987249259Sdim// Inst{79-64} = OFFSET;
1988249259Sdim// Inst{81-80} = ENDIAN_SWAP;
1989249259Sdim// Inst{82}    = CONST_BUF_NO_STRIDE;
1990249259Sdim// Inst{83}    = MEGA_FETCH;
1991249259Sdim// Inst{84}    = ALT_CONST;
1992249259Sdim// Inst{86-85} = BUFFER_INDEX_MODE;
1993249259Sdim// Inst{95-86} = 0; Reserved
1994249259Sdim
1995249259Sdim// VTX_WORD3 (Padding)
1996249259Sdim//
1997249259Sdim// Inst{127-96} = 0;
1998249259Sdim}
1999249259Sdim
2000249259Sdimdef TEX_VTX_TEXBUF:
2001249259Sdim  InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr, i32imm:$BUFFER_ID), "TEX_VTX_EXPLICIT_READ $dst, $ptr",
2002249259Sdim      [(set R600_Reg128:$dst, (int_R600_load_texbuf ADDRGA_VAR_OFFSET:$ptr, imm:$BUFFER_ID))]>,
2003249259SdimVTX_WORD1_GPR, VTX_WORD0 {
2004249259Sdim
2005249259Sdimlet VC_INST = 0;
2006249259Sdimlet FETCH_TYPE = 2;
2007249259Sdimlet FETCH_WHOLE_QUAD = 0;
2008249259Sdimlet SRC_REL = 0;
2009249259Sdimlet SRC_SEL_X = 0;
2010249259Sdimlet DST_REL = 0;
2011249259Sdimlet USE_CONST_FIELDS = 1;
2012249259Sdimlet NUM_FORMAT_ALL = 0;
2013249259Sdimlet FORMAT_COMP_ALL = 0;
2014249259Sdimlet SRF_MODE_ALL = 1;
2015249259Sdimlet MEGA_FETCH_COUNT = 16;
2016249259Sdimlet DST_SEL_X        = 0;
2017249259Sdimlet DST_SEL_Y        = 1;
2018249259Sdimlet DST_SEL_Z        = 2;
2019249259Sdimlet DST_SEL_W        = 3;
2020249259Sdimlet DATA_FORMAT      = 0;
2021249259Sdim
2022249259Sdimlet Inst{31-0} = Word0;
2023249259Sdimlet Inst{63-32} = Word1;
2024249259Sdim
2025249259Sdim// LLVM can only encode 64-bit instructions, so these fields are manually
2026249259Sdim// encoded in R600CodeEmitter
2027249259Sdim//
2028249259Sdim// bits<16> OFFSET;
2029249259Sdim// bits<2>  ENDIAN_SWAP = 0;
2030249259Sdim// bits<1>  CONST_BUF_NO_STRIDE = 0;
2031249259Sdim// bits<1>  MEGA_FETCH = 0;
2032249259Sdim// bits<1>  ALT_CONST = 0;
2033249259Sdim// bits<2>  BUFFER_INDEX_MODE = 0;
2034249259Sdim
2035249259Sdim
2036249259Sdim
2037249259Sdim// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
2038249259Sdim// is done in R600CodeEmitter
2039249259Sdim//
2040249259Sdim// Inst{79-64} = OFFSET;
2041249259Sdim// Inst{81-80} = ENDIAN_SWAP;
2042249259Sdim// Inst{82}    = CONST_BUF_NO_STRIDE;
2043249259Sdim// Inst{83}    = MEGA_FETCH;
2044249259Sdim// Inst{84}    = ALT_CONST;
2045249259Sdim// Inst{86-85} = BUFFER_INDEX_MODE;
2046249259Sdim// Inst{95-86} = 0; Reserved
2047249259Sdim
2048249259Sdim// VTX_WORD3 (Padding)
2049249259Sdim//
2050249259Sdim// Inst{127-96} = 0;
2051249259Sdim}
2052249259Sdim
2053249259Sdim
2054249259Sdim
2055249259Sdim//===--------------------------------------------------------------------===//
2056249259Sdim// Instructions support
2057249259Sdim//===--------------------------------------------------------------------===//
2058249259Sdim//===---------------------------------------------------------------------===//
2059249259Sdim// Custom Inserter for Branches and returns, this eventually will be a
2060249259Sdim// seperate pass
2061249259Sdim//===---------------------------------------------------------------------===//
2062249259Sdimlet isTerminator = 1, usesCustomInserter = 1, isBranch = 1, isBarrier = 1 in {
2063249259Sdim  def BRANCH : ILFormat<(outs), (ins brtarget:$target),
2064249259Sdim      "; Pseudo unconditional branch instruction",
2065249259Sdim      [(br bb:$target)]>;
2066249259Sdim  defm BRANCH_COND : BranchConditional<IL_brcond>;
2067249259Sdim}
2068249259Sdim
2069249259Sdim//===---------------------------------------------------------------------===//
2070249259Sdim// Flow and Program control Instructions
2071249259Sdim//===---------------------------------------------------------------------===//
2072249259Sdimlet isTerminator=1 in {
2073249259Sdim  def SWITCH      : ILFormat< (outs), (ins GPRI32:$src),
2074249259Sdim  !strconcat("SWITCH", " $src"), []>;
2075249259Sdim  def CASE        : ILFormat< (outs), (ins GPRI32:$src),
2076249259Sdim      !strconcat("CASE", " $src"), []>;
2077249259Sdim  def BREAK       : ILFormat< (outs), (ins),
2078249259Sdim      "BREAK", []>;
2079249259Sdim  def CONTINUE    : ILFormat< (outs), (ins),
2080249259Sdim      "CONTINUE", []>;
2081249259Sdim  def DEFAULT     : ILFormat< (outs), (ins),
2082249259Sdim      "DEFAULT", []>;
2083249259Sdim  def ELSE        : ILFormat< (outs), (ins),
2084249259Sdim      "ELSE", []>;
2085249259Sdim  def ENDSWITCH   : ILFormat< (outs), (ins),
2086249259Sdim      "ENDSWITCH", []>;
2087249259Sdim  def ENDMAIN     : ILFormat< (outs), (ins),
2088249259Sdim      "ENDMAIN", []>;
2089249259Sdim  def END         : ILFormat< (outs), (ins),
2090249259Sdim      "END", []>;
2091249259Sdim  def ENDFUNC     : ILFormat< (outs), (ins),
2092249259Sdim      "ENDFUNC", []>;
2093249259Sdim  def ENDIF       : ILFormat< (outs), (ins),
2094249259Sdim      "ENDIF", []>;
2095249259Sdim  def WHILELOOP   : ILFormat< (outs), (ins),
2096249259Sdim      "WHILE", []>;
2097249259Sdim  def ENDLOOP     : ILFormat< (outs), (ins),
2098249259Sdim      "ENDLOOP", []>;
2099249259Sdim  def FUNC        : ILFormat< (outs), (ins),
2100249259Sdim      "FUNC", []>;
2101249259Sdim  def RETDYN      : ILFormat< (outs), (ins),
2102249259Sdim      "RET_DYN", []>;
2103249259Sdim  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2104249259Sdim  defm IF_LOGICALNZ  : BranchInstr<"IF_LOGICALNZ">;
2105249259Sdim  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2106249259Sdim  defm IF_LOGICALZ   : BranchInstr<"IF_LOGICALZ">;
2107249259Sdim  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2108249259Sdim  defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">;
2109249259Sdim  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2110249259Sdim  defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">;
2111249259Sdim  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2112249259Sdim  defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">;
2113249259Sdim  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
2114249259Sdim  defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">;
2115249259Sdim  defm IFC         : BranchInstr2<"IFC">;
2116249259Sdim  defm BREAKC      : BranchInstr2<"BREAKC">;
2117249259Sdim  defm CONTINUEC   : BranchInstr2<"CONTINUEC">;
2118249259Sdim}
2119249259Sdim
2120249259Sdim//===----------------------------------------------------------------------===//
2121249259Sdim// ISel Patterns
2122249259Sdim//===----------------------------------------------------------------------===//
2123249259Sdim
2124249259Sdim// CND*_INT Pattterns for f32 True / False values
2125249259Sdim
2126249259Sdimclass CND_INT_f32 <InstR600 cnd, CondCode cc> : Pat <
2127249259Sdim  (selectcc (i32 R600_Reg32:$src0), 0, (f32 R600_Reg32:$src1),
2128249259Sdim                                            R600_Reg32:$src2, cc),
2129249259Sdim  (cnd R600_Reg32:$src0, R600_Reg32:$src1, R600_Reg32:$src2)
2130249259Sdim>;
2131249259Sdim
2132249259Sdimdef : CND_INT_f32 <CNDE_INT,  SETEQ>;
2133249259Sdimdef : CND_INT_f32 <CNDGT_INT, SETGT>;
2134249259Sdimdef : CND_INT_f32 <CNDGE_INT, SETGE>;
2135249259Sdim
2136249259Sdim//CNDGE_INT extra pattern
2137249259Sdimdef : Pat <
2138249259Sdim  (selectcc (i32 R600_Reg32:$src0), -1, (i32 R600_Reg32:$src1),
2139249259Sdim                                        (i32 R600_Reg32:$src2), COND_GT),
2140249259Sdim  (CNDGE_INT R600_Reg32:$src0, R600_Reg32:$src1, R600_Reg32:$src2)
2141249259Sdim>;
2142249259Sdim
2143249259Sdim// KIL Patterns
2144249259Sdimdef KILP : Pat <
2145249259Sdim  (int_AMDGPU_kilp),
2146249259Sdim  (MASK_WRITE (KILLGT (f32 ONE), (f32 ZERO)))
2147249259Sdim>;
2148249259Sdim
2149249259Sdimdef KIL : Pat <
2150249259Sdim  (int_AMDGPU_kill R600_Reg32:$src0),
2151249259Sdim  (MASK_WRITE (KILLGT (f32 ZERO), (f32 R600_Reg32:$src0)))
2152249259Sdim>;
2153249259Sdim
2154249259Sdim// SGT Reverse args
2155249259Sdimdef : Pat <
2156249259Sdim  (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, COND_LT),
2157249259Sdim  (SGT R600_Reg32:$src1, R600_Reg32:$src0)
2158249259Sdim>;
2159249259Sdim
2160249259Sdim// SGE Reverse args
2161249259Sdimdef : Pat <
2162249259Sdim  (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, COND_LE),
2163249259Sdim  (SGE R600_Reg32:$src1, R600_Reg32:$src0)
2164249259Sdim>;
2165249259Sdim
2166249259Sdim// SETGT_DX10 reverse args
2167249259Sdimdef : Pat <
2168249259Sdim  (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, COND_LT),
2169249259Sdim  (SETGT_DX10 R600_Reg32:$src1, R600_Reg32:$src0)
2170249259Sdim>;
2171249259Sdim
2172249259Sdim// SETGE_DX10 reverse args
2173249259Sdimdef : Pat <
2174249259Sdim  (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, COND_LE),
2175249259Sdim  (SETGE_DX10 R600_Reg32:$src1, R600_Reg32:$src0)
2176249259Sdim>;
2177249259Sdim
2178249259Sdim// SETGT_INT reverse args
2179249259Sdimdef : Pat <
2180249259Sdim  (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETLT),
2181249259Sdim  (SETGT_INT R600_Reg32:$src1, R600_Reg32:$src0)
2182249259Sdim>;
2183249259Sdim
2184249259Sdim// SETGE_INT reverse args
2185249259Sdimdef : Pat <
2186249259Sdim  (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETLE),
2187249259Sdim  (SETGE_INT R600_Reg32:$src1, R600_Reg32:$src0)
2188249259Sdim>;
2189249259Sdim
2190249259Sdim// SETGT_UINT reverse args
2191249259Sdimdef : Pat <
2192249259Sdim  (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETULT),
2193249259Sdim  (SETGT_UINT R600_Reg32:$src1, R600_Reg32:$src0)
2194249259Sdim>;
2195249259Sdim
2196249259Sdim// SETGE_UINT reverse args
2197249259Sdimdef : Pat <
2198249259Sdim  (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETULE),
2199249259Sdim  (SETGE_UINT R600_Reg32:$src1, R600_Reg32:$src0)
2200249259Sdim>;
2201249259Sdim
2202249259Sdim// The next two patterns are special cases for handling 'true if ordered' and
2203249259Sdim// 'true if unordered' conditionals.  The assumption here is that the behavior of
2204249259Sdim// SETE and SNE conforms to the Direct3D 10 rules for floating point values
2205249259Sdim// described here:
2206249259Sdim// http://msdn.microsoft.com/en-us/library/windows/desktop/cc308050.aspx#alpha_32_bit
2207249259Sdim// We assume that  SETE returns false when one of the operands is NAN and
2208249259Sdim// SNE returns true when on of the operands is NAN
2209249259Sdim
2210249259Sdim//SETE - 'true if ordered'
2211249259Sdimdef : Pat <
2212249259Sdim  (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, SETO),
2213249259Sdim  (SETE R600_Reg32:$src0, R600_Reg32:$src1)
2214249259Sdim>;
2215249259Sdim
2216249259Sdim//SETE_DX10 - 'true if ordered'
2217249259Sdimdef : Pat <
2218249259Sdim  (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETO),
2219249259Sdim  (SETE_DX10 R600_Reg32:$src0, R600_Reg32:$src1)
2220249259Sdim>;
2221249259Sdim
2222249259Sdim//SNE - 'true if unordered'
2223249259Sdimdef : Pat <
2224249259Sdim  (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, SETUO),
2225249259Sdim  (SNE R600_Reg32:$src0, R600_Reg32:$src1)
2226249259Sdim>;
2227249259Sdim
2228249259Sdim//SETNE_DX10 - 'true if ordered'
2229249259Sdimdef : Pat <
2230249259Sdim  (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUO),
2231249259Sdim  (SETNE_DX10 R600_Reg32:$src0, R600_Reg32:$src1)
2232249259Sdim>;
2233249259Sdim
2234249259Sdimdef : Extract_Element <f32, v4f32, R600_Reg128, 0, sub0>;
2235249259Sdimdef : Extract_Element <f32, v4f32, R600_Reg128, 1, sub1>;
2236249259Sdimdef : Extract_Element <f32, v4f32, R600_Reg128, 2, sub2>;
2237249259Sdimdef : Extract_Element <f32, v4f32, R600_Reg128, 3, sub3>;
2238249259Sdim
2239249259Sdimdef : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 0, sub0>;
2240249259Sdimdef : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 1, sub1>;
2241249259Sdimdef : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 2, sub2>;
2242249259Sdimdef : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 3, sub3>;
2243249259Sdim
2244249259Sdimdef : Extract_Element <i32, v4i32, R600_Reg128, 0, sub0>;
2245249259Sdimdef : Extract_Element <i32, v4i32, R600_Reg128, 1, sub1>;
2246249259Sdimdef : Extract_Element <i32, v4i32, R600_Reg128, 2, sub2>;
2247249259Sdimdef : Extract_Element <i32, v4i32, R600_Reg128, 3, sub3>;
2248249259Sdim
2249249259Sdimdef : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 0, sub0>;
2250249259Sdimdef : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 1, sub1>;
2251249259Sdimdef : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 2, sub2>;
2252249259Sdimdef : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 3, sub3>;
2253249259Sdim
2254249259Sdimdef : Vector4_Build <v4f32, R600_Reg128, f32, R600_Reg32>;
2255249259Sdimdef : Vector4_Build <v4i32, R600_Reg128, i32, R600_Reg32>;
2256249259Sdim
2257249259Sdim// bitconvert patterns
2258249259Sdim
2259249259Sdimdef : BitConvert <i32, f32, R600_Reg32>;
2260249259Sdimdef : BitConvert <f32, i32, R600_Reg32>;
2261249259Sdimdef : BitConvert <v4f32, v4i32, R600_Reg128>;
2262249259Sdimdef : BitConvert <v4i32, v4f32, R600_Reg128>;
2263249259Sdim
2264249259Sdim// DWORDADDR pattern
2265249259Sdimdef : DwordAddrPat  <i32, R600_Reg32>;
2266249259Sdim
2267249259Sdim} // End isR600toCayman Predicate
2268