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