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