R600: rework handling of the constants
[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 <bits<11> inst, 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
29   bits<11> op_code = inst;
30   //let Inst = inst;
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 }
49
50 class InstR600ISA <dag outs, dag ins, string asm, list<dag> pattern> :
51     AMDGPUInst <outs, ins, asm, pattern> {
52   field bits<64> Inst;
53
54   let Namespace = "AMDGPU";
55 }
56
57 def MEMxi : Operand<iPTR> {
58   let MIOperandInfo = (ops R600_TReg32_X:$ptr, i32imm:$index);
59   let PrintMethod = "printMemOperand";
60 }
61
62 def MEMrr : Operand<iPTR> {
63   let MIOperandInfo = (ops R600_Reg32:$ptr, R600_Reg32:$index);
64 }
65
66 // Operands for non-registers
67
68 class InstFlag<string PM = "printOperand", int Default = 0>
69     : OperandWithDefaultOps <i32, (ops (i32 Default))> {
70   let PrintMethod = PM;
71 }
72
73 // src_sel for ALU src operands, see also ALU_CONST, ALU_PARAM registers 
74 def SEL : OperandWithDefaultOps <i32, (ops (i32 -1))> {
75   let PrintMethod = "printSel";
76 }
77
78 def LITERAL : InstFlag<"printLiteral">;
79
80 def WRITE : InstFlag <"printWrite", 1>;
81 def OMOD : InstFlag <"printOMOD">;
82 def REL : InstFlag <"printRel">;
83 def CLAMP : InstFlag <"printClamp">;
84 def NEG : InstFlag <"printNeg">;
85 def ABS : InstFlag <"printAbs">;
86 def UEM : InstFlag <"printUpdateExecMask">;
87 def UP : InstFlag <"printUpdatePred">;
88
89 // XXX: The r600g finalizer in Mesa expects last to be one in most cases.
90 // Once we start using the packetizer in this backend we should have this
91 // default to 0.
92 def LAST : InstFlag<"printLast", 1>;
93
94 def ADDRParam : ComplexPattern<i32, 2, "SelectADDRParam", [], []>;
95 def ADDRDWord : ComplexPattern<i32, 1, "SelectADDRDWord", [], []>;
96 def ADDRVTX_READ : ComplexPattern<i32, 2, "SelectADDRVTX_READ", [], []>;
97 def ADDRGA_CONST_OFFSET : ComplexPattern<i32, 1, "SelectGlobalValueConstantOffset", [], []>;
98 def ADDRGA_VAR_OFFSET : ComplexPattern<i32, 2, "SelectGlobalValueVariableOffset", [], []>;
99
100 class R600ALU_Word0 {
101   field bits<32> Word0;
102
103   bits<11> src0;
104   bits<1>  src0_neg;
105   bits<1>  src0_rel;
106   bits<11> src1;
107   bits<1>  src1_rel;
108   bits<1>  src1_neg;
109   bits<3>  index_mode = 0;
110   bits<2>  pred_sel;
111   bits<1>  last;
112
113   bits<9>  src0_sel  = src0{8-0};
114   bits<2>  src0_chan = src0{10-9};
115   bits<9>  src1_sel  = src1{8-0};
116   bits<2>  src1_chan = src1{10-9};
117
118   let Word0{8-0}   = src0_sel;
119   let Word0{9}     = src0_rel;
120   let Word0{11-10} = src0_chan;
121   let Word0{12}    = src0_neg;
122   let Word0{21-13} = src1_sel;
123   let Word0{22}    = src1_rel;
124   let Word0{24-23} = src1_chan;
125   let Word0{25}    = src1_neg;
126   let Word0{28-26} = index_mode;
127   let Word0{30-29} = pred_sel;
128   let Word0{31}    = last;
129 }
130
131 class R600ALU_Word1 {
132   field bits<32> Word1;
133
134   bits<11> dst;
135   bits<3>  bank_swizzle = 0;
136   bits<1>  dst_rel;
137   bits<1>  clamp;
138
139   bits<7>  dst_sel  = dst{6-0};
140   bits<2>  dst_chan = dst{10-9};
141
142   let Word1{20-18} = bank_swizzle;
143   let Word1{27-21} = dst_sel;
144   let Word1{28}    = dst_rel;
145   let Word1{30-29} = dst_chan;
146   let Word1{31}    = clamp;
147 }
148
149 class R600ALU_Word1_OP2 <bits<11> alu_inst> : R600ALU_Word1{
150
151   bits<1>  src0_abs;
152   bits<1>  src1_abs;
153   bits<1>  update_exec_mask;
154   bits<1>  update_pred;
155   bits<1>  write;
156   bits<2>  omod;
157
158   let Word1{0}     = src0_abs;
159   let Word1{1}     = src1_abs;
160   let Word1{2}     = update_exec_mask;
161   let Word1{3}     = update_pred;
162   let Word1{4}     = write;
163   let Word1{6-5}   = omod;
164   let Word1{17-7}  = alu_inst;
165 }
166
167 class R600ALU_Word1_OP3 <bits<5> alu_inst> : R600ALU_Word1{
168
169   bits<11> src2;
170   bits<1>  src2_rel;
171   bits<1>  src2_neg;
172
173   bits<9>  src2_sel = src2{8-0};
174   bits<2>  src2_chan = src2{10-9};
175
176   let Word1{8-0}   = src2_sel;
177   let Word1{9}     = src2_rel;
178   let Word1{11-10} = src2_chan;
179   let Word1{12}    = src2_neg;
180   let Word1{17-13} = alu_inst;
181 }
182
183 class VTX_WORD0 {
184   field bits<32> Word0;
185   bits<7> SRC_GPR;
186   bits<5> VC_INST;
187   bits<2> FETCH_TYPE;
188   bits<1> FETCH_WHOLE_QUAD;
189   bits<8> BUFFER_ID;
190   bits<1> SRC_REL;
191   bits<2> SRC_SEL_X;
192   bits<6> MEGA_FETCH_COUNT;
193
194   let Word0{4-0}   = VC_INST;
195   let Word0{6-5}   = FETCH_TYPE;
196   let Word0{7}     = FETCH_WHOLE_QUAD;
197   let Word0{15-8}  = BUFFER_ID;
198   let Word0{22-16} = SRC_GPR;
199   let Word0{23}    = SRC_REL;
200   let Word0{25-24} = SRC_SEL_X;
201   let Word0{31-26} = MEGA_FETCH_COUNT;
202 }
203
204 class VTX_WORD1_GPR {
205   field bits<32> Word1;
206   bits<7> DST_GPR;
207   bits<1> DST_REL;
208   bits<3> DST_SEL_X;
209   bits<3> DST_SEL_Y;
210   bits<3> DST_SEL_Z;
211   bits<3> DST_SEL_W;
212   bits<1> USE_CONST_FIELDS;
213   bits<6> DATA_FORMAT;
214   bits<2> NUM_FORMAT_ALL;
215   bits<1> FORMAT_COMP_ALL;
216   bits<1> SRF_MODE_ALL;
217
218   let Word1{6-0} = DST_GPR;
219   let Word1{7}    = DST_REL;
220   let Word1{8}    = 0; // Reserved
221   let Word1{11-9} = DST_SEL_X;
222   let Word1{14-12} = DST_SEL_Y;
223   let Word1{17-15} = DST_SEL_Z;
224   let Word1{20-18} = DST_SEL_W;
225   let Word1{21}    = USE_CONST_FIELDS;
226   let Word1{27-22} = DATA_FORMAT;
227   let Word1{29-28} = NUM_FORMAT_ALL;
228   let Word1{30}    = FORMAT_COMP_ALL;
229   let Word1{31}    = SRF_MODE_ALL;
230 }
231
232 /*
233 XXX: R600 subtarget uses a slightly different encoding than the other
234 subtargets.  We currently handle this in R600MCCodeEmitter, but we may
235 want to use these instruction classes in the future.
236
237 class R600ALU_Word1_OP2_r600 : R600ALU_Word1_OP2 {
238
239   bits<1>  fog_merge;
240   bits<10> alu_inst;
241
242   let Inst{37}    = fog_merge;
243   let Inst{39-38} = omod;
244   let Inst{49-40} = alu_inst;
245 }
246
247 class R600ALU_Word1_OP2_r700 : R600ALU_Word1_OP2 {
248
249   bits<11> alu_inst;
250
251   let Inst{38-37} = omod;
252   let Inst{49-39} = alu_inst;
253 }
254 */
255
256 def R600_Pred : PredicateOperand<i32, (ops R600_Predicate),
257                                      (ops PRED_SEL_OFF)>;
258
259
260 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
261
262 // Class for instructions with only one source register.
263 // If you add new ins to this instruction, make sure they are listed before
264 // $literal, because the backend currently assumes that the last operand is
265 // a literal.  Also be sure to update the enum R600Op1OperandIndex::ROI in
266 // R600Defines.h, R600InstrInfo::buildDefaultInstruction(),
267 // and R600InstrInfo::getOperandIdx().
268 class R600_1OP <bits<11> inst, string opName, list<dag> pattern,
269                 InstrItinClass itin = AnyALU> :
270     InstR600 <0,
271               (outs R600_Reg32:$dst),
272               (ins WRITE:$write, OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
273                    R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel,
274                    LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
275               !strconcat(opName,
276                    "$clamp $dst$write$dst_rel$omod, "
277                    "$src0_neg$src0_abs$src0$src0_sel$src0_abs$src0_rel, "
278                    "$literal $pred_sel$last"),
279               pattern,
280               itin>,
281     R600ALU_Word0,
282     R600ALU_Word1_OP2 <inst> {
283
284   let src1 = 0;
285   let src1_rel = 0;
286   let src1_neg = 0;
287   let src1_abs = 0;
288   let update_exec_mask = 0;
289   let update_pred = 0;
290   let HasNativeOperands = 1;
291   let Op1 = 1;
292   let DisableEncoding = "$literal";
293
294   let Inst{31-0}  = Word0;
295   let Inst{63-32} = Word1;
296 }
297
298 class R600_1OP_Helper <bits<11> inst, string opName, SDPatternOperator node,
299                     InstrItinClass itin = AnyALU> :
300     R600_1OP <inst, opName,
301               [(set R600_Reg32:$dst, (node R600_Reg32:$src0))]
302 >;
303
304 // If you add our change the operands for R600_2OP instructions, you must
305 // also update the R600Op2OperandIndex::ROI enum in R600Defines.h,
306 // R600InstrInfo::buildDefaultInstruction(), and R600InstrInfo::getOperandIdx().
307 class R600_2OP <bits<11> inst, string opName, list<dag> pattern,
308                 InstrItinClass itin = AnyALU> :
309   InstR600 <inst,
310           (outs R600_Reg32:$dst),
311           (ins UEM:$update_exec_mask, UP:$update_pred, WRITE:$write,
312                OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
313                R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel,
314                R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, ABS:$src1_abs, SEL:$src1_sel,
315                LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
316           !strconcat(opName,
317                 "$clamp $update_exec_mask$update_pred$dst$write$dst_rel$omod, "
318                 "$src0_neg$src0_abs$src0$src0_sel$src0_abs$src0_rel, "
319                 "$src1_neg$src1_abs$src1$src1_sel$src1_abs$src1_rel, "
320                 "$literal $pred_sel$last"),
321           pattern,
322           itin>,
323     R600ALU_Word0,
324     R600ALU_Word1_OP2 <inst> {
325
326   let HasNativeOperands = 1;
327   let Op2 = 1;
328   let DisableEncoding = "$literal";
329
330   let Inst{31-0}  = Word0;
331   let Inst{63-32} = Word1;
332 }
333
334 class R600_2OP_Helper <bits<11> inst, string opName, SDPatternOperator node,
335                        InstrItinClass itim = AnyALU> :
336     R600_2OP <inst, opName,
337               [(set R600_Reg32:$dst, (node R600_Reg32:$src0,
338                                            R600_Reg32:$src1))]
339 >;
340
341 // If you add our change the operands for R600_3OP instructions, you must
342 // also update the R600Op3OperandIndex::ROI enum in R600Defines.h,
343 // R600InstrInfo::buildDefaultInstruction(), and
344 // R600InstrInfo::getOperandIdx().
345 class R600_3OP <bits<5> inst, string opName, list<dag> pattern,
346                 InstrItinClass itin = AnyALU> :
347   InstR600 <0,
348           (outs R600_Reg32:$dst),
349           (ins REL:$dst_rel, CLAMP:$clamp,
350                R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, SEL:$src0_sel,
351                R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, SEL:$src1_sel,
352                R600_Reg32:$src2, NEG:$src2_neg, REL:$src2_rel, SEL:$src2_sel,
353                LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
354           !strconcat(opName, "$clamp $dst$dst_rel, "
355                              "$src0_neg$src0$src0_sel$src0_rel, "
356                              "$src1_neg$src1$src1_sel$src1_rel, "
357                              "$src2_neg$src2$src2_sel$src2_rel, "
358                              "$literal $pred_sel$last"),
359           pattern,
360           itin>,
361     R600ALU_Word0,
362     R600ALU_Word1_OP3<inst>{
363
364   let HasNativeOperands = 1;
365   let DisableEncoding = "$literal";
366   let Op3 = 1;
367
368   let Inst{31-0}  = Word0;
369   let Inst{63-32} = Word1;
370 }
371
372 class R600_REDUCTION <bits<11> inst, dag ins, string asm, list<dag> pattern,
373                       InstrItinClass itin = VecALU> :
374   InstR600 <inst,
375           (outs R600_Reg32:$dst),
376           ins,
377           asm,
378           pattern,
379           itin>;
380
381 class R600_TEX <bits<11> inst, string opName, list<dag> pattern,
382                 InstrItinClass itin = AnyALU> :
383   InstR600 <inst,
384           (outs R600_Reg128:$dst),
385           (ins R600_Reg128:$src0, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
386           !strconcat(opName, "$dst, $src0, $resourceId, $samplerId, $textureTarget"),
387           pattern,
388           itin>{
389     let Inst {10-0} = inst;
390   }
391
392 } // End mayLoad = 1, mayStore = 0, hasSideEffects = 0
393
394 def TEX_SHADOW : PatLeaf<
395   (imm),
396   [{uint32_t TType = (uint32_t)N->getZExtValue();
397     return (TType >= 6 && TType <= 8) || (TType >= 11 && TType <= 13);
398   }]
399 >;
400
401 def TEX_RECT : PatLeaf<
402   (imm),
403   [{uint32_t TType = (uint32_t)N->getZExtValue();
404     return TType == 5;
405   }]
406 >;
407
408 class EG_CF_RAT <bits <8> cf_inst, bits <6> rat_inst, bits<4> rat_id, dag outs,
409                  dag ins, string asm, list<dag> pattern> :
410     InstR600ISA <outs, ins, asm, pattern> {
411   bits<7>  RW_GPR;
412   bits<7>  INDEX_GPR;
413
414   bits<2>  RIM;
415   bits<2>  TYPE;
416   bits<1>  RW_REL;
417   bits<2>  ELEM_SIZE;
418
419   bits<12> ARRAY_SIZE;
420   bits<4>  COMP_MASK;
421   bits<4>  BURST_COUNT;
422   bits<1>  VPM;
423   bits<1>  eop;
424   bits<1>  MARK;
425   bits<1>  BARRIER;
426
427   // CF_ALLOC_EXPORT_WORD0_RAT
428   let Inst{3-0}   = rat_id;
429   let Inst{9-4}   = rat_inst;
430   let Inst{10}    = 0; // Reserved
431   let Inst{12-11} = RIM;
432   let Inst{14-13} = TYPE;
433   let Inst{21-15} = RW_GPR;
434   let Inst{22}    = RW_REL;
435   let Inst{29-23} = INDEX_GPR;
436   let Inst{31-30} = ELEM_SIZE;
437
438   // CF_ALLOC_EXPORT_WORD1_BUF
439   let Inst{43-32} = ARRAY_SIZE;
440   let Inst{47-44} = COMP_MASK;
441   let Inst{51-48} = BURST_COUNT;
442   let Inst{52}    = VPM;
443   let Inst{53}    = eop;
444   let Inst{61-54} = cf_inst;
445   let Inst{62}    = MARK;
446   let Inst{63}    = BARRIER;
447 }
448
449 class LoadParamFrag <PatFrag load_type> : PatFrag <
450   (ops node:$ptr), (load_type node:$ptr),
451   [{ return isParamLoad(dyn_cast<LoadSDNode>(N)); }]
452 >;
453
454 def load_param : LoadParamFrag<load>;
455 def load_param_zexti8 : LoadParamFrag<zextloadi8>;
456 def load_param_zexti16 : LoadParamFrag<zextloadi16>;
457
458 def isR600 : Predicate<"Subtarget.device()"
459                             "->getGeneration() == AMDGPUDeviceInfo::HD4XXX">;
460 def isR700 : Predicate<"Subtarget.device()"
461                             "->getGeneration() == AMDGPUDeviceInfo::HD4XXX &&"
462                             "Subtarget.device()->getDeviceFlag()"
463                             ">= OCL_DEVICE_RV710">;
464 def isEG : Predicate<
465   "Subtarget.device()->getGeneration() >= AMDGPUDeviceInfo::HD5XXX && "
466   "Subtarget.device()->getGeneration() < AMDGPUDeviceInfo::HD7XXX && "
467   "Subtarget.device()->getDeviceFlag() != OCL_DEVICE_CAYMAN">;
468
469 def isCayman : Predicate<"Subtarget.device()"
470                             "->getDeviceFlag() == OCL_DEVICE_CAYMAN">;
471 def isEGorCayman : Predicate<"Subtarget.device()"
472                             "->getGeneration() == AMDGPUDeviceInfo::HD5XXX"
473                             "|| Subtarget.device()->getGeneration() =="
474                             "AMDGPUDeviceInfo::HD6XXX">;
475
476 def isR600toCayman : Predicate<
477                      "Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX">;
478
479 //===----------------------------------------------------------------------===//
480 // R600 SDNodes
481 //===----------------------------------------------------------------------===//
482
483 def INTERP: SDNode<"AMDGPUISD::INTERP",
484   SDTypeProfile<1, 2, [SDTCisFP<0>, SDTCisInt<1>, SDTCisInt<2>]>
485   >;
486
487 def INTERP_P0: SDNode<"AMDGPUISD::INTERP_P0",
488   SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisInt<1>]>
489   >;
490
491 def CONST_ADDRESS: SDNode<"AMDGPUISD::CONST_ADDRESS",
492   SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>,
493   [SDNPMayLoad]
494 >;
495
496 //===----------------------------------------------------------------------===//
497 // Interpolation Instructions
498 //===----------------------------------------------------------------------===//
499
500 let usesCustomInserter = 1 in {
501 def input_perspective :  AMDGPUShaderInst <
502   (outs R600_Reg128:$dst),
503   (ins i32imm:$src0, i32imm:$src1),
504   "input_perspective $src0 $src1 : dst",
505   [(set R600_Reg128:$dst, (INTERP (i32 imm:$src0), (i32 imm:$src1)))]>;
506 }  // End usesCustomInserter = 1
507
508 def input_constant :  AMDGPUShaderInst <
509   (outs R600_Reg128:$dst),
510   (ins i32imm:$src),
511   "input_perspective $src : dst",
512   [(set R600_Reg128:$dst, (INTERP_P0 (i32 imm:$src)))]>;
513
514
515
516 def INTERP_XY : R600_2OP <0xD6, "INTERP_XY", []> {
517   let bank_swizzle = 5;
518 }
519
520 def INTERP_ZW : R600_2OP <0xD7, "INTERP_ZW", []> {
521   let bank_swizzle = 5;
522 }
523
524 def INTERP_LOAD_P0 : R600_1OP <0xE0, "INTERP_LOAD_P0", []>;
525
526 //===----------------------------------------------------------------------===//
527 // Export Instructions
528 //===----------------------------------------------------------------------===//
529
530 def ExportType : SDTypeProfile<0, 5, [SDTCisFP<0>, SDTCisInt<1>]>;
531
532 def EXPORT: SDNode<"AMDGPUISD::EXPORT", ExportType,
533   [SDNPHasChain, SDNPSideEffect]>;
534
535 class ExportWord0 {
536   field bits<32> Word0;
537
538   bits<13> arraybase;
539   bits<2> type;
540   bits<7> gpr;
541   bits<2> elem_size;
542
543   let Word0{12-0} = arraybase;
544   let Word0{14-13} = type;
545   let Word0{21-15} = gpr;
546   let Word0{22} = 0; // RW_REL
547   let Word0{29-23} = 0; // INDEX_GPR
548   let Word0{31-30} = elem_size;
549 }
550
551 class ExportSwzWord1 {
552   field bits<32> Word1;
553
554   bits<3> sw_x;
555   bits<3> sw_y;
556   bits<3> sw_z;
557   bits<3> sw_w;
558   bits<1> eop;
559   bits<8> inst;
560
561   let Word1{2-0} = sw_x;
562   let Word1{5-3} = sw_y;
563   let Word1{8-6} = sw_z;
564   let Word1{11-9} = sw_w;
565 }
566
567 class ExportBufWord1 {
568   field bits<32> Word1;
569
570   bits<12> arraySize;
571   bits<4> compMask;
572   bits<1> eop;
573   bits<8> inst;
574
575   let Word1{11-0} = arraySize;
576   let Word1{15-12} = compMask;
577 }
578
579 multiclass ExportPattern<Instruction ExportInst, bits<8> cf_inst> {
580   def : Pat<(int_R600_store_pixel_depth R600_Reg32:$reg),
581     (ExportInst
582         (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), R600_Reg32:$reg, sel_x),
583         0, 61, 0, 7, 7, 7, cf_inst, 0)
584   >;
585
586   def : Pat<(int_R600_store_pixel_stencil R600_Reg32:$reg),
587     (ExportInst
588         (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), R600_Reg32:$reg, sel_x),
589         0, 61, 7, 0, 7, 7, cf_inst, 0)
590   >;
591
592   def : Pat<(int_R600_store_pixel_dummy),
593     (ExportInst
594         (v4f32 (IMPLICIT_DEF)), 0, 0, 7, 7, 7, 7, cf_inst, 0)
595   >;
596
597   def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 0),
598     (i32 imm:$type), (i32 imm:$arraybase), (i32 imm)),
599         (ExportInst R600_Reg128:$src, imm:$type, imm:$arraybase,
600         0, 1, 2, 3, cf_inst, 0)
601   >;
602 }
603
604 multiclass SteamOutputExportPattern<Instruction ExportInst,
605     bits<8> buf0inst, bits<8> buf1inst, bits<8> buf2inst, bits<8> buf3inst> {
606 // Stream0
607   def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 1),
608       (i32 imm:$type), (i32 imm:$arraybase), (i32 imm:$mask)),
609       (ExportInst R600_Reg128:$src, imm:$type, imm:$arraybase,
610       4095, imm:$mask, buf0inst, 0)>;
611 // Stream1
612   def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 2),
613       (i32 imm:$type), (i32 imm:$arraybase), (i32 imm:$mask)),
614       (ExportInst R600_Reg128:$src, imm:$type, imm:$arraybase,
615       4095, imm:$mask, buf1inst, 0)>;
616 // Stream2
617   def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 3),
618       (i32 imm:$type), (i32 imm:$arraybase), (i32 imm:$mask)),
619       (ExportInst R600_Reg128:$src, imm:$type, imm:$arraybase,
620       4095, imm:$mask, buf2inst, 0)>;
621 // Stream3
622   def : Pat<(EXPORT (v4f32 R600_Reg128:$src), (i32 4),
623       (i32 imm:$type), (i32 imm:$arraybase), (i32 imm:$mask)),
624       (ExportInst R600_Reg128:$src, imm:$type, imm:$arraybase,
625       4095, imm:$mask, buf3inst, 0)>;
626 }
627
628 let isTerminator = 1, usesCustomInserter = 1 in {
629
630 class ExportSwzInst : InstR600ISA<(
631     outs),
632     (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase,
633     i32imm:$sw_x, i32imm:$sw_y, i32imm:$sw_z, i32imm:$sw_w, i32imm:$inst,
634     i32imm:$eop),
635     !strconcat("EXPORT", " $gpr"),
636     []>, ExportWord0, ExportSwzWord1 {
637   let elem_size = 3;
638   let Inst{31-0} = Word0;
639   let Inst{63-32} = Word1;
640 }
641
642 } // End isTerminator = 1, usesCustomInserter = 1
643
644 class ExportBufInst : InstR600ISA<(
645     outs),
646     (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase,
647     i32imm:$arraySize, i32imm:$compMask, i32imm:$inst, i32imm:$eop),
648     !strconcat("EXPORT", " $gpr"),
649     []>, ExportWord0, ExportBufWord1 {
650   let elem_size = 0;
651   let Inst{31-0} = Word0;
652   let Inst{63-32} = Word1;
653 }
654
655 let Predicates = [isR600toCayman] in { 
656
657 //===----------------------------------------------------------------------===//
658 // Common Instructions R600, R700, Evergreen, Cayman
659 //===----------------------------------------------------------------------===//
660
661 def ADD : R600_2OP_Helper <0x0, "ADD", fadd>;
662 // Non-IEEE MUL: 0 * anything = 0
663 def MUL : R600_2OP_Helper <0x1, "MUL NON-IEEE", int_AMDGPU_mul>;
664 def MUL_IEEE : R600_2OP_Helper <0x2, "MUL_IEEE", fmul>;
665 def MAX : R600_2OP_Helper <0x3, "MAX", AMDGPUfmax>;
666 def MIN : R600_2OP_Helper <0x4, "MIN", AMDGPUfmin>;
667
668 // For the SET* instructions there is a naming conflict in TargetSelectionDAG.td,
669 // so some of the instruction names don't match the asm string.
670 // XXX: Use the defs in TargetSelectionDAG.td instead of intrinsics.
671 def SETE : R600_2OP <
672   0x08, "SETE",
673   [(set R600_Reg32:$dst,
674    (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
675              COND_EQ))]
676 >;
677
678 def SGT : R600_2OP <
679   0x09, "SETGT",
680   [(set R600_Reg32:$dst,
681    (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
682               COND_GT))]
683 >;
684
685 def SGE : R600_2OP <
686   0xA, "SETGE",
687   [(set R600_Reg32:$dst,
688    (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
689               COND_GE))]
690 >;
691
692 def SNE : R600_2OP <
693   0xB, "SETNE",
694   [(set R600_Reg32:$dst,
695    (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO,
696     COND_NE))]
697 >;
698
699 def FRACT : R600_1OP_Helper <0x10, "FRACT", AMDGPUfract>;
700 def TRUNC : R600_1OP_Helper <0x11, "TRUNC", int_AMDGPU_trunc>;
701 def CEIL : R600_1OP_Helper <0x12, "CEIL", fceil>;
702 def RNDNE : R600_1OP_Helper <0x13, "RNDNE", frint>;
703 def FLOOR : R600_1OP_Helper <0x14, "FLOOR", ffloor>;
704
705 def MOV : R600_1OP <0x19, "MOV", []>;
706
707 let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in {
708
709 class MOV_IMM <ValueType vt, Operand immType> : AMDGPUInst <
710   (outs R600_Reg32:$dst),
711   (ins immType:$imm),
712   "",
713   []
714 >;
715
716 } // end let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1
717
718 def MOV_IMM_I32 : MOV_IMM<i32, i32imm>;
719 def : Pat <
720   (imm:$val),
721   (MOV_IMM_I32 imm:$val)
722 >;
723
724 def MOV_IMM_F32 : MOV_IMM<f32, f32imm>;
725 def : Pat <
726   (fpimm:$val),
727   (MOV_IMM_F32  fpimm:$val)
728 >;
729
730 def PRED_SETE : R600_2OP <0x20, "PRED_SETE", []>;
731 def PRED_SETGT : R600_2OP <0x21, "PRED_SETGT", []>;
732 def PRED_SETGE : R600_2OP <0x22, "PRED_SETGE", []>;
733 def PRED_SETNE : R600_2OP <0x23, "PRED_SETNE", []>;
734
735 let hasSideEffects = 1 in {
736
737 def KILLGT : R600_2OP <0x2D, "KILLGT", []>;
738
739 } // end hasSideEffects
740
741 def AND_INT : R600_2OP_Helper <0x30, "AND_INT", and>;
742 def OR_INT : R600_2OP_Helper <0x31, "OR_INT", or>;
743 def XOR_INT : R600_2OP_Helper <0x32, "XOR_INT", xor>;
744 def NOT_INT : R600_1OP_Helper <0x33, "NOT_INT", not>;
745 def ADD_INT : R600_2OP_Helper <0x34, "ADD_INT", add>;
746 def SUB_INT : R600_2OP_Helper <0x35, "SUB_INT", sub>;
747 def MAX_INT : R600_2OP_Helper <0x36, "MAX_INT", AMDGPUsmax>;
748 def MIN_INT : R600_2OP_Helper <0x37, "MIN_INT", AMDGPUsmin>;
749 def MAX_UINT : R600_2OP_Helper <0x38, "MAX_UINT", AMDGPUumax>;
750 def MIN_UINT : R600_2OP_Helper <0x39, "MIN_UINT", AMDGPUumin>;
751
752 def SETE_INT : R600_2OP <
753   0x3A, "SETE_INT",
754   [(set (i32 R600_Reg32:$dst),
755    (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETEQ))]
756 >;
757
758 def SETGT_INT : R600_2OP <
759   0x3B, "SGT_INT",
760   [(set (i32 R600_Reg32:$dst),
761    (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETGT))]
762 >;
763
764 def SETGE_INT : R600_2OP <
765   0x3C, "SETGE_INT",
766   [(set (i32 R600_Reg32:$dst),
767    (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETGE))]
768 >;
769
770 def SETNE_INT : R600_2OP <
771   0x3D, "SETNE_INT",
772   [(set (i32 R600_Reg32:$dst),
773    (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETNE))]
774 >;
775
776 def SETGT_UINT : R600_2OP <
777   0x3E, "SETGT_UINT",
778   [(set (i32 R600_Reg32:$dst),
779    (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGT))]
780 >;
781
782 def SETGE_UINT : R600_2OP <
783   0x3F, "SETGE_UINT",
784   [(set (i32 R600_Reg32:$dst),
785     (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGE))]
786 >;
787
788 def PRED_SETE_INT : R600_2OP <0x42, "PRED_SETE_INT", []>;
789 def PRED_SETGT_INT : R600_2OP <0x43, "PRED_SETGE_INT", []>;
790 def PRED_SETGE_INT : R600_2OP <0x44, "PRED_SETGE_INT", []>;
791 def PRED_SETNE_INT : R600_2OP <0x45, "PRED_SETNE_INT", []>;
792
793 def CNDE_INT : R600_3OP <
794   0x1C, "CNDE_INT",
795   [(set (i32 R600_Reg32:$dst),
796    (selectcc (i32 R600_Reg32:$src0), 0,
797        (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
798        COND_EQ))]
799 >;
800
801 def CNDGE_INT : R600_3OP <
802   0x1E, "CNDGE_INT",
803   [(set (i32 R600_Reg32:$dst),
804    (selectcc (i32 R600_Reg32:$src0), 0,
805        (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
806        COND_GE))]
807 >;
808
809 def CNDGT_INT : R600_3OP <
810   0x1D, "CNDGT_INT",
811   [(set (i32 R600_Reg32:$dst),
812    (selectcc (i32 R600_Reg32:$src0), 0,
813        (i32 R600_Reg32:$src1), (i32 R600_Reg32:$src2),
814        COND_GT))]
815 >;
816
817 //===----------------------------------------------------------------------===//
818 // Texture instructions
819 //===----------------------------------------------------------------------===//
820
821 def TEX_LD : R600_TEX <
822   0x03, "TEX_LD",
823   [(set R600_Reg128:$dst, (int_AMDGPU_txf R600_Reg128:$src0, imm:$src1, imm:$src2, imm:$src3, imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
824 > {
825 let AsmString = "TEX_LD $dst, $src0, $src1, $src2, $src3, $resourceId, $samplerId, $textureTarget";
826 let InOperandList = (ins R600_Reg128:$src0, i32imm:$src1, i32imm:$src2, i32imm:$src3, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget);
827 }
828
829 def TEX_GET_TEXTURE_RESINFO : R600_TEX <
830   0x04, "TEX_GET_TEXTURE_RESINFO",
831   [(set R600_Reg128:$dst, (int_AMDGPU_txq R600_Reg128:$src0, imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
832 >;
833
834 def TEX_GET_GRADIENTS_H : R600_TEX <
835   0x07, "TEX_GET_GRADIENTS_H",
836   [(set R600_Reg128:$dst, (int_AMDGPU_ddx R600_Reg128:$src0, imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
837 >;
838
839 def TEX_GET_GRADIENTS_V : R600_TEX <
840   0x08, "TEX_GET_GRADIENTS_V",
841   [(set R600_Reg128:$dst, (int_AMDGPU_ddy R600_Reg128:$src0, imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
842 >;
843
844 def TEX_SET_GRADIENTS_H : R600_TEX <
845   0x0B, "TEX_SET_GRADIENTS_H",
846   []
847 >;
848
849 def TEX_SET_GRADIENTS_V : R600_TEX <
850   0x0C, "TEX_SET_GRADIENTS_V",
851   []
852 >;
853
854 def TEX_SAMPLE : R600_TEX <
855   0x10, "TEX_SAMPLE",
856   [(set R600_Reg128:$dst, (int_AMDGPU_tex R600_Reg128:$src0, imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
857 >;
858
859 def TEX_SAMPLE_C : R600_TEX <
860   0x18, "TEX_SAMPLE_C",
861   [(set R600_Reg128:$dst, (int_AMDGPU_tex R600_Reg128:$src0, imm:$resourceId, imm:$samplerId, TEX_SHADOW:$textureTarget))]
862 >;
863
864 def TEX_SAMPLE_L : R600_TEX <
865   0x11, "TEX_SAMPLE_L",
866   [(set R600_Reg128:$dst, (int_AMDGPU_txl R600_Reg128:$src0, imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
867 >;
868
869 def TEX_SAMPLE_C_L : R600_TEX <
870   0x19, "TEX_SAMPLE_C_L",
871   [(set R600_Reg128:$dst, (int_AMDGPU_txl R600_Reg128:$src0, imm:$resourceId, imm:$samplerId, TEX_SHADOW:$textureTarget))]
872 >;
873
874 def TEX_SAMPLE_LB : R600_TEX <
875   0x12, "TEX_SAMPLE_LB",
876   [(set R600_Reg128:$dst, (int_AMDGPU_txb R600_Reg128:$src0,imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
877 >;
878
879 def TEX_SAMPLE_C_LB : R600_TEX <
880   0x1A, "TEX_SAMPLE_C_LB",
881   [(set R600_Reg128:$dst, (int_AMDGPU_txb R600_Reg128:$src0, imm:$resourceId, imm:$samplerId, TEX_SHADOW:$textureTarget))]
882 >;
883
884 def TEX_SAMPLE_G : R600_TEX <
885   0x14, "TEX_SAMPLE_G",
886   []
887 >;
888
889 def TEX_SAMPLE_C_G : R600_TEX <
890   0x1C, "TEX_SAMPLE_C_G",
891   []
892 >;
893
894 //===----------------------------------------------------------------------===//
895 // Helper classes for common instructions
896 //===----------------------------------------------------------------------===//
897
898 class MUL_LIT_Common <bits<5> inst> : R600_3OP <
899   inst, "MUL_LIT",
900   []
901 >;
902
903 class MULADD_Common <bits<5> inst> : R600_3OP <
904   inst, "MULADD",
905   [(set (f32 R600_Reg32:$dst),
906    (IL_mad R600_Reg32:$src0, R600_Reg32:$src1, R600_Reg32:$src2))]
907 >;
908
909 class CNDE_Common <bits<5> inst> : R600_3OP <
910   inst, "CNDE",
911   [(set R600_Reg32:$dst,
912    (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
913        (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
914        COND_EQ))]
915 >;
916
917 class CNDGT_Common <bits<5> inst> : R600_3OP <
918   inst, "CNDGT",
919   [(set R600_Reg32:$dst,
920    (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
921        (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
922        COND_GT))]
923 >;
924
925 class CNDGE_Common <bits<5> inst> : R600_3OP <
926   inst, "CNDGE",
927   [(set R600_Reg32:$dst,
928    (selectcc (f32 R600_Reg32:$src0), FP_ZERO,
929        (f32 R600_Reg32:$src1), (f32 R600_Reg32:$src2),
930        COND_GE))]
931 >;
932
933 multiclass DOT4_Common <bits<11> inst> {
934
935   def _pseudo : R600_REDUCTION <inst,
936     (ins R600_Reg128:$src0, R600_Reg128:$src1),
937     "DOT4 $dst $src0, $src1",
938     [(set R600_Reg32:$dst, (int_AMDGPU_dp4 R600_Reg128:$src0, R600_Reg128:$src1))]
939   >;
940
941   def _real : R600_2OP <inst, "DOT4", []>;
942 }
943
944 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
945 multiclass CUBE_Common <bits<11> inst> {
946
947   def _pseudo : InstR600 <
948     inst,
949     (outs R600_Reg128:$dst),
950     (ins R600_Reg128:$src),
951     "CUBE $dst $src",
952     [(set R600_Reg128:$dst, (int_AMDGPU_cube R600_Reg128:$src))],
953     VecALU
954   > {
955     let isPseudo = 1;
956   }
957
958   def _real : R600_2OP <inst, "CUBE", []>;
959 }
960 } // End mayLoad = 0, mayStore = 0, hasSideEffects = 0
961
962 class EXP_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
963   inst, "EXP_IEEE", fexp2
964 >;
965
966 class FLT_TO_INT_Common <bits<11> inst> : R600_1OP_Helper <
967   inst, "FLT_TO_INT", fp_to_sint
968 >;
969
970 class INT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
971   inst, "INT_TO_FLT", sint_to_fp
972 >;
973
974 class FLT_TO_UINT_Common <bits<11> inst> : R600_1OP_Helper <
975   inst, "FLT_TO_UINT", fp_to_uint
976 >;
977
978 class UINT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
979   inst, "UINT_TO_FLT", uint_to_fp
980 >;
981
982 class LOG_CLAMPED_Common <bits<11> inst> : R600_1OP <
983   inst, "LOG_CLAMPED", []
984 >;
985
986 class LOG_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
987   inst, "LOG_IEEE", flog2
988 >;
989
990 class LSHL_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHL", shl>;
991 class LSHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHR", srl>;
992 class ASHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "ASHR", sra>;
993 class MULHI_INT_Common <bits<11> inst> : R600_2OP_Helper <
994   inst, "MULHI_INT", mulhs
995 >;
996 class MULHI_UINT_Common <bits<11> inst> : R600_2OP_Helper <
997   inst, "MULHI", mulhu
998 >;
999 class MULLO_INT_Common <bits<11> inst> : R600_2OP_Helper <
1000   inst, "MULLO_INT", mul
1001 >;
1002 class MULLO_UINT_Common <bits<11> inst> : R600_2OP <inst, "MULLO_UINT", []>;
1003
1004 class RECIP_CLAMPED_Common <bits<11> inst> : R600_1OP <
1005   inst, "RECIP_CLAMPED", []
1006 >;
1007
1008 class RECIP_IEEE_Common <bits<11> inst> : R600_1OP <
1009   inst, "RECIP_IEEE", [(set R600_Reg32:$dst, (fdiv FP_ONE, R600_Reg32:$src0))]
1010 >;
1011
1012 class RECIP_UINT_Common <bits<11> inst> : R600_1OP_Helper <
1013   inst, "RECIP_UINT", AMDGPUurecip
1014 >;
1015
1016 class RECIPSQRT_CLAMPED_Common <bits<11> inst> : R600_1OP_Helper <
1017   inst, "RECIPSQRT_CLAMPED", int_AMDGPU_rsq
1018 >;
1019
1020 class RECIPSQRT_IEEE_Common <bits<11> inst> : R600_1OP <
1021   inst, "RECIPSQRT_IEEE", []
1022 >;
1023
1024 class SIN_Common <bits<11> inst> : R600_1OP <
1025   inst, "SIN", []>{
1026   let Trig = 1;
1027 }
1028
1029 class COS_Common <bits<11> inst> : R600_1OP <
1030   inst, "COS", []> {
1031   let Trig = 1;
1032 }
1033
1034 //===----------------------------------------------------------------------===//
1035 // Helper patterns for complex intrinsics
1036 //===----------------------------------------------------------------------===//
1037
1038 multiclass DIV_Common <InstR600 recip_ieee> {
1039 def : Pat<
1040   (int_AMDGPU_div R600_Reg32:$src0, R600_Reg32:$src1),
1041   (MUL R600_Reg32:$src0, (recip_ieee R600_Reg32:$src1))
1042 >;
1043
1044 def : Pat<
1045   (fdiv R600_Reg32:$src0, R600_Reg32:$src1),
1046   (MUL R600_Reg32:$src0, (recip_ieee R600_Reg32:$src1))
1047 >;
1048 }
1049
1050 class TGSI_LIT_Z_Common <InstR600 mul_lit, InstR600 log_clamped, InstR600 exp_ieee> : Pat <
1051   (int_TGSI_lit_z R600_Reg32:$src_x, R600_Reg32:$src_y, R600_Reg32:$src_w),
1052   (exp_ieee (mul_lit (log_clamped (MAX R600_Reg32:$src_y, (f32 ZERO))), R600_Reg32:$src_w, R600_Reg32:$src_x))
1053 >;
1054
1055 //===----------------------------------------------------------------------===//
1056 // R600 / R700 Instructions
1057 //===----------------------------------------------------------------------===//
1058
1059 let Predicates = [isR600] in {
1060
1061   def MUL_LIT_r600 : MUL_LIT_Common<0x0C>;
1062   def MULADD_r600 : MULADD_Common<0x10>;
1063   def CNDE_r600 : CNDE_Common<0x18>;
1064   def CNDGT_r600 : CNDGT_Common<0x19>;
1065   def CNDGE_r600 : CNDGE_Common<0x1A>;
1066   defm DOT4_r600 : DOT4_Common<0x50>;
1067   defm CUBE_r600 : CUBE_Common<0x52>;
1068   def EXP_IEEE_r600 : EXP_IEEE_Common<0x61>;
1069   def LOG_CLAMPED_r600 : LOG_CLAMPED_Common<0x62>;
1070   def LOG_IEEE_r600 : LOG_IEEE_Common<0x63>;
1071   def RECIP_CLAMPED_r600 : RECIP_CLAMPED_Common<0x64>;
1072   def RECIP_IEEE_r600 : RECIP_IEEE_Common<0x66>;
1073   def RECIPSQRT_CLAMPED_r600 : RECIPSQRT_CLAMPED_Common<0x67>;
1074   def RECIPSQRT_IEEE_r600 : RECIPSQRT_IEEE_Common<0x69>;
1075   def FLT_TO_INT_r600 : FLT_TO_INT_Common<0x6b>;
1076   def INT_TO_FLT_r600 : INT_TO_FLT_Common<0x6c>;
1077   def FLT_TO_UINT_r600 : FLT_TO_UINT_Common<0x79>;
1078   def UINT_TO_FLT_r600 : UINT_TO_FLT_Common<0x6d>;
1079   def SIN_r600 : SIN_Common<0x6E>;
1080   def COS_r600 : COS_Common<0x6F>;
1081   def ASHR_r600 : ASHR_Common<0x70>;
1082   def LSHR_r600 : LSHR_Common<0x71>;
1083   def LSHL_r600 : LSHL_Common<0x72>;
1084   def MULLO_INT_r600 : MULLO_INT_Common<0x73>;
1085   def MULHI_INT_r600 : MULHI_INT_Common<0x74>;
1086   def MULLO_UINT_r600 : MULLO_UINT_Common<0x75>;
1087   def MULHI_UINT_r600 : MULHI_UINT_Common<0x76>;
1088   def RECIP_UINT_r600 : RECIP_UINT_Common <0x78>;
1089
1090   defm DIV_r600 : DIV_Common<RECIP_IEEE_r600>;
1091   def TGSI_LIT_Z_r600 : TGSI_LIT_Z_Common<MUL_LIT_r600, LOG_CLAMPED_r600, EXP_IEEE_r600>;
1092
1093   def : Pat<(fsqrt R600_Reg32:$src),
1094     (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_r600 R600_Reg32:$src))>;
1095
1096   def R600_ExportSwz : ExportSwzInst {
1097     let Word1{20-17} = 1; // BURST_COUNT
1098     let Word1{21} = eop;
1099     let Word1{22} = 1; // VALID_PIXEL_MODE
1100     let Word1{30-23} = inst;
1101     let Word1{31} = 1; // BARRIER
1102   }
1103   defm : ExportPattern<R600_ExportSwz, 39>;
1104
1105   def R600_ExportBuf : ExportBufInst {
1106     let Word1{20-17} = 1; // BURST_COUNT
1107     let Word1{21} = eop;
1108     let Word1{22} = 1; // VALID_PIXEL_MODE
1109     let Word1{30-23} = inst;
1110     let Word1{31} = 1; // BARRIER
1111   }
1112   defm : SteamOutputExportPattern<R600_ExportBuf, 0x20, 0x21, 0x22, 0x23>;
1113 }
1114
1115 // Helper pattern for normalizing inputs to triginomic instructions for R700+
1116 // cards.
1117 class COS_PAT <InstR600 trig> : Pat<
1118   (fcos R600_Reg32:$src),
1119   (trig (MUL (MOV_IMM_I32 CONST.TWO_PI_INV), R600_Reg32:$src))
1120 >;
1121
1122 class SIN_PAT <InstR600 trig> : Pat<
1123   (fsin R600_Reg32:$src),
1124   (trig (MUL (MOV_IMM_I32 CONST.TWO_PI_INV), R600_Reg32:$src))
1125 >;
1126
1127 //===----------------------------------------------------------------------===//
1128 // R700 Only instructions
1129 //===----------------------------------------------------------------------===//
1130
1131 let Predicates = [isR700] in {
1132   def SIN_r700 : SIN_Common<0x6E>;
1133   def COS_r700 : COS_Common<0x6F>;
1134
1135   // R700 normalizes inputs to SIN/COS the same as EG
1136   def : SIN_PAT <SIN_r700>;
1137   def : COS_PAT <COS_r700>;
1138 }
1139
1140 //===----------------------------------------------------------------------===//
1141 // Evergreen Only instructions
1142 //===----------------------------------------------------------------------===//
1143
1144 let Predicates = [isEG] in {
1145   
1146 def RECIP_IEEE_eg : RECIP_IEEE_Common<0x86>;
1147 defm DIV_eg : DIV_Common<RECIP_IEEE_eg>;
1148
1149 def MULLO_INT_eg : MULLO_INT_Common<0x8F>;
1150 def MULHI_INT_eg : MULHI_INT_Common<0x90>;
1151 def MULLO_UINT_eg : MULLO_UINT_Common<0x91>;
1152 def MULHI_UINT_eg : MULHI_UINT_Common<0x92>;
1153 def RECIP_UINT_eg : RECIP_UINT_Common<0x94>;
1154 def RECIPSQRT_CLAMPED_eg : RECIPSQRT_CLAMPED_Common<0x87>;
1155 def EXP_IEEE_eg : EXP_IEEE_Common<0x81>;
1156 def LOG_IEEE_eg : LOG_IEEE_Common<0x83>;
1157 def RECIP_CLAMPED_eg : RECIP_CLAMPED_Common<0x84>;
1158 def RECIPSQRT_IEEE_eg : RECIPSQRT_IEEE_Common<0x89>;
1159 def SIN_eg : SIN_Common<0x8D>;
1160 def COS_eg : COS_Common<0x8E>;
1161
1162 def : SIN_PAT <SIN_eg>;
1163 def : COS_PAT <COS_eg>;
1164 def : Pat<(fsqrt R600_Reg32:$src),
1165   (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_eg R600_Reg32:$src))>;
1166 } // End Predicates = [isEG]
1167
1168 //===----------------------------------------------------------------------===//
1169 // Evergreen / Cayman Instructions
1170 //===----------------------------------------------------------------------===//
1171
1172 let Predicates = [isEGorCayman] in {
1173
1174   // BFE_UINT - bit_extract, an optimization for mask and shift
1175   // Src0 = Input
1176   // Src1 = Offset
1177   // Src2 = Width
1178   //
1179   // bit_extract = (Input << (32 - Offset - Width)) >> (32 - Width)
1180   //
1181   // Example Usage:
1182   // (Offset, Width)
1183   //
1184   // (0, 8)           = (Input << 24) >> 24  = (Input &  0xff)       >> 0
1185   // (8, 8)           = (Input << 16) >> 24  = (Input &  0xffff)     >> 8
1186   // (16,8)           = (Input <<  8) >> 24  = (Input &  0xffffff)   >> 16
1187   // (24,8)           = (Input <<  0) >> 24  = (Input &  0xffffffff) >> 24
1188   def BFE_UINT_eg : R600_3OP <0x4, "BFE_UINT",
1189     [(set R600_Reg32:$dst, (int_AMDIL_bit_extract_u32 R600_Reg32:$src0,
1190                                                       R600_Reg32:$src1,
1191                                                       R600_Reg32:$src2))],
1192     VecALU
1193   >;
1194
1195   def BIT_ALIGN_INT_eg : R600_3OP <0xC, "BIT_ALIGN_INT",
1196     [(set R600_Reg32:$dst, (AMDGPUbitalign R600_Reg32:$src0, R600_Reg32:$src1,
1197                                           R600_Reg32:$src2))],
1198     VecALU
1199   >;
1200
1201   def MULADD_eg : MULADD_Common<0x14>;
1202   def ASHR_eg : ASHR_Common<0x15>;
1203   def LSHR_eg : LSHR_Common<0x16>;
1204   def LSHL_eg : LSHL_Common<0x17>;
1205   def CNDE_eg : CNDE_Common<0x19>;
1206   def CNDGT_eg : CNDGT_Common<0x1A>;
1207   def CNDGE_eg : CNDGE_Common<0x1B>;
1208   def MUL_LIT_eg : MUL_LIT_Common<0x1F>;
1209   def LOG_CLAMPED_eg : LOG_CLAMPED_Common<0x82>;
1210   defm DOT4_eg : DOT4_Common<0xBE>;
1211   defm CUBE_eg : CUBE_Common<0xC0>;
1212
1213   def TGSI_LIT_Z_eg : TGSI_LIT_Z_Common<MUL_LIT_eg, LOG_CLAMPED_eg, EXP_IEEE_eg>;
1214
1215   def FLT_TO_INT_eg : FLT_TO_INT_Common<0x50> {
1216     let Pattern = [];
1217   }
1218
1219   def INT_TO_FLT_eg : INT_TO_FLT_Common<0x9B>;
1220
1221   def FLT_TO_UINT_eg : FLT_TO_UINT_Common<0x9A> {
1222     let Pattern = [];
1223   }
1224
1225   def UINT_TO_FLT_eg : UINT_TO_FLT_Common<0x9C>;
1226
1227   // TRUNC is used for the FLT_TO_INT instructions to work around a
1228   // perceived problem where the rounding modes are applied differently
1229   // depending on the instruction and the slot they are in.
1230   // See:
1231   // https://bugs.freedesktop.org/show_bug.cgi?id=50232
1232   // Mesa commit: a1a0974401c467cb86ef818f22df67c21774a38c
1233   //
1234   // XXX: Lowering SELECT_CC will sometimes generate fp_to_[su]int nodes,
1235   // which do not need to be truncated since the fp values are 0.0f or 1.0f.
1236   // We should look into handling these cases separately.
1237   def : Pat<(fp_to_sint R600_Reg32:$src0),
1238     (FLT_TO_INT_eg (TRUNC R600_Reg32:$src0))>;
1239
1240   def : Pat<(fp_to_uint R600_Reg32:$src0),
1241     (FLT_TO_UINT_eg (TRUNC R600_Reg32:$src0))>;
1242
1243   def EG_ExportSwz : ExportSwzInst {
1244     let Word1{19-16} = 1; // BURST_COUNT
1245     let Word1{20} = 1; // VALID_PIXEL_MODE
1246     let Word1{21} = eop;
1247     let Word1{29-22} = inst;
1248     let Word1{30} = 0; // MARK
1249     let Word1{31} = 1; // BARRIER
1250   }
1251   defm : ExportPattern<EG_ExportSwz, 83>;
1252
1253   def EG_ExportBuf : ExportBufInst {
1254     let Word1{19-16} = 1; // BURST_COUNT
1255     let Word1{20} = 1; // VALID_PIXEL_MODE
1256     let Word1{21} = eop;
1257     let Word1{29-22} = inst;
1258     let Word1{30} = 0; // MARK
1259     let Word1{31} = 1; // BARRIER
1260   }
1261   defm : SteamOutputExportPattern<EG_ExportBuf, 0x40, 0x41, 0x42, 0x43>;
1262
1263 //===----------------------------------------------------------------------===//
1264 // Memory read/write instructions
1265 //===----------------------------------------------------------------------===//
1266 let usesCustomInserter = 1 in {
1267
1268 class RAT_WRITE_CACHELESS_eg <dag ins, bits<4> comp_mask, string name,
1269                               list<dag> pattern>
1270     : EG_CF_RAT <0x57, 0x2, 0, (outs), ins,
1271                  !strconcat(name, " $rw_gpr, $index_gpr, $eop"), pattern> {
1272   let RIM         = 0;
1273   // XXX: Have a separate instruction for non-indexed writes.
1274   let TYPE        = 1;
1275   let RW_REL      = 0;
1276   let ELEM_SIZE   = 0;
1277
1278   let ARRAY_SIZE  = 0;
1279   let COMP_MASK   = comp_mask;
1280   let BURST_COUNT = 0;
1281   let VPM         = 0;
1282   let MARK        = 0;
1283   let BARRIER     = 1;
1284 }
1285
1286 } // End usesCustomInserter = 1
1287
1288 // 32-bit store
1289 def RAT_WRITE_CACHELESS_32_eg : RAT_WRITE_CACHELESS_eg <
1290   (ins R600_TReg32_X:$rw_gpr, R600_TReg32_X:$index_gpr, InstFlag:$eop),
1291   0x1, "RAT_WRITE_CACHELESS_32_eg",
1292   [(global_store (i32 R600_TReg32_X:$rw_gpr), R600_TReg32_X:$index_gpr)]
1293 >;
1294
1295 //128-bit store
1296 def RAT_WRITE_CACHELESS_128_eg : RAT_WRITE_CACHELESS_eg <
1297   (ins R600_Reg128:$rw_gpr, R600_TReg32_X:$index_gpr, InstFlag:$eop),
1298   0xf, "RAT_WRITE_CACHELESS_128",
1299   [(global_store (v4i32 R600_Reg128:$rw_gpr), R600_TReg32_X:$index_gpr)]
1300 >;
1301
1302 class VTX_READ_eg <string name, bits<8> buffer_id, dag outs, list<dag> pattern>
1303     : InstR600ISA <outs, (ins MEMxi:$ptr), name#" $dst, $ptr", pattern>,
1304       VTX_WORD1_GPR, VTX_WORD0 {
1305
1306   // Static fields
1307   let VC_INST = 0;
1308   let FETCH_TYPE = 2;
1309   let FETCH_WHOLE_QUAD = 0;
1310   let BUFFER_ID = buffer_id;
1311   let SRC_REL = 0;
1312   // XXX: We can infer this field based on the SRC_GPR.  This would allow us
1313   // to store vertex addresses in any channel, not just X.
1314   let SRC_SEL_X = 0;
1315   let DST_REL = 0;
1316   // The docs say that if this bit is set, then DATA_FORMAT, NUM_FORMAT_ALL,
1317   // FORMAT_COMP_ALL, SRF_MODE_ALL, and ENDIAN_SWAP fields will be ignored,
1318   // however, based on my testing if USE_CONST_FIELDS is set, then all
1319   // these fields need to be set to 0.
1320   let USE_CONST_FIELDS = 0;
1321   let NUM_FORMAT_ALL = 1;
1322   let FORMAT_COMP_ALL = 0;
1323   let SRF_MODE_ALL = 0;
1324
1325   let Inst{31-0} = Word0;
1326   let Inst{63-32} = Word1;
1327   // LLVM can only encode 64-bit instructions, so these fields are manually
1328   // encoded in R600CodeEmitter
1329   //
1330   // bits<16> OFFSET;
1331   // bits<2>  ENDIAN_SWAP = 0;
1332   // bits<1>  CONST_BUF_NO_STRIDE = 0;
1333   // bits<1>  MEGA_FETCH = 0;
1334   // bits<1>  ALT_CONST = 0;
1335   // bits<2>  BUFFER_INDEX_MODE = 0;
1336
1337
1338
1339   // VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
1340   // is done in R600CodeEmitter
1341   //
1342   // Inst{79-64} = OFFSET;
1343   // Inst{81-80} = ENDIAN_SWAP;
1344   // Inst{82}    = CONST_BUF_NO_STRIDE;
1345   // Inst{83}    = MEGA_FETCH;
1346   // Inst{84}    = ALT_CONST;
1347   // Inst{86-85} = BUFFER_INDEX_MODE;
1348   // Inst{95-86} = 0; Reserved
1349
1350   // VTX_WORD3 (Padding)
1351   //
1352   // Inst{127-96} = 0;
1353 }
1354
1355 class VTX_READ_8_eg <bits<8> buffer_id, list<dag> pattern>
1356     : VTX_READ_eg <"VTX_READ_8", buffer_id, (outs R600_TReg32_X:$dst),
1357                    pattern> {
1358
1359   let MEGA_FETCH_COUNT = 1;
1360   let DST_SEL_X = 0;
1361   let DST_SEL_Y = 7;   // Masked
1362   let DST_SEL_Z = 7;   // Masked
1363   let DST_SEL_W = 7;   // Masked
1364   let DATA_FORMAT = 1; // FMT_8
1365 }
1366
1367 class VTX_READ_16_eg <bits<8> buffer_id, list<dag> pattern>
1368     : VTX_READ_eg <"VTX_READ_16", buffer_id, (outs R600_TReg32_X:$dst),
1369                     pattern> {
1370   let MEGA_FETCH_COUNT = 2;
1371   let DST_SEL_X = 0;
1372   let DST_SEL_Y = 7;   // Masked
1373   let DST_SEL_Z = 7;   // Masked
1374   let DST_SEL_W = 7;   // Masked
1375   let DATA_FORMAT = 5; // FMT_16
1376
1377 }
1378
1379 class VTX_READ_32_eg <bits<8> buffer_id, list<dag> pattern>
1380     : VTX_READ_eg <"VTX_READ_32", buffer_id, (outs R600_TReg32_X:$dst),
1381                    pattern> {
1382
1383   let MEGA_FETCH_COUNT = 4;
1384   let DST_SEL_X        = 0;
1385   let DST_SEL_Y        = 7;   // Masked
1386   let DST_SEL_Z        = 7;   // Masked
1387   let DST_SEL_W        = 7;   // Masked
1388   let DATA_FORMAT      = 0xD; // COLOR_32
1389
1390   // This is not really necessary, but there were some GPU hangs that appeared
1391   // to be caused by ALU instructions in the next instruction group that wrote
1392   // to the $ptr registers of the VTX_READ.  
1393   // e.g.
1394   // %T3_X<def> = VTX_READ_PARAM_32_eg %T2_X<kill>, 24
1395   // %T2_X<def> = MOV %ZERO
1396   //Adding this constraint prevents this from happening.
1397   let Constraints = "$ptr.ptr = $dst";
1398 }
1399
1400 class VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern>
1401     : VTX_READ_eg <"VTX_READ_128", buffer_id, (outs R600_Reg128:$dst),
1402                    pattern> {
1403
1404   let MEGA_FETCH_COUNT = 16;
1405   let DST_SEL_X        =  0;
1406   let DST_SEL_Y        =  1;
1407   let DST_SEL_Z        =  2;
1408   let DST_SEL_W        =  3;
1409   let DATA_FORMAT      =  0x22; // COLOR_32_32_32_32
1410
1411   // XXX: Need to force VTX_READ_128 instructions to write to the same register
1412   // that holds its buffer address to avoid potential hangs.  We can't use
1413   // the same constraint as VTX_READ_32_eg, because the $ptr.ptr and $dst
1414   // registers are different sizes.
1415 }
1416
1417 //===----------------------------------------------------------------------===//
1418 // VTX Read from parameter memory space
1419 //===----------------------------------------------------------------------===//
1420
1421 def VTX_READ_PARAM_8_eg : VTX_READ_8_eg <0,
1422   [(set (i32 R600_TReg32_X:$dst), (load_param_zexti8 ADDRVTX_READ:$ptr))]
1423 >;
1424
1425 def VTX_READ_PARAM_16_eg : VTX_READ_16_eg <0,
1426   [(set (i32 R600_TReg32_X:$dst), (load_param_zexti16 ADDRVTX_READ:$ptr))]
1427 >;
1428
1429 def VTX_READ_PARAM_32_eg : VTX_READ_32_eg <0,
1430   [(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))]
1431 >;
1432
1433 //===----------------------------------------------------------------------===//
1434 // VTX Read from global memory space
1435 //===----------------------------------------------------------------------===//
1436
1437 // 8-bit reads
1438 def VTX_READ_GLOBAL_8_eg : VTX_READ_8_eg <1,
1439   [(set (i32 R600_TReg32_X:$dst), (zextloadi8_global ADDRVTX_READ:$ptr))]
1440 >;
1441
1442 // 32-bit reads
1443 def VTX_READ_GLOBAL_32_eg : VTX_READ_32_eg <1,
1444   [(set (i32 R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))]
1445 >;
1446
1447 // 128-bit reads
1448 def VTX_READ_GLOBAL_128_eg : VTX_READ_128_eg <1,
1449   [(set (v4i32 R600_Reg128:$dst), (global_load ADDRVTX_READ:$ptr))]
1450 >;
1451
1452 //===----------------------------------------------------------------------===//
1453 // Constant Loads
1454 // XXX: We are currently storing all constants in the global address space.
1455 //===----------------------------------------------------------------------===//
1456
1457 def CONSTANT_LOAD_eg : VTX_READ_32_eg <1,
1458   [(set (i32 R600_TReg32_X:$dst), (constant_load ADDRVTX_READ:$ptr))]
1459 >;
1460
1461 }
1462
1463 let Predicates = [isCayman] in {
1464
1465 let isVector = 1 in { 
1466
1467 def RECIP_IEEE_cm : RECIP_IEEE_Common<0x86>;
1468
1469 def MULLO_INT_cm : MULLO_INT_Common<0x8F>;
1470 def MULHI_INT_cm : MULHI_INT_Common<0x90>;
1471 def MULLO_UINT_cm : MULLO_UINT_Common<0x91>;
1472 def MULHI_UINT_cm : MULHI_UINT_Common<0x92>;
1473 def RECIPSQRT_CLAMPED_cm : RECIPSQRT_CLAMPED_Common<0x87>;
1474 def EXP_IEEE_cm : EXP_IEEE_Common<0x81>;
1475 def LOG_IEEE_ : LOG_IEEE_Common<0x83>;
1476 def RECIP_CLAMPED_cm : RECIP_CLAMPED_Common<0x84>;
1477 def RECIPSQRT_IEEE_cm : RECIPSQRT_IEEE_Common<0x89>;
1478 def SIN_cm : SIN_Common<0x8D>;
1479 def COS_cm : COS_Common<0x8E>;
1480 } // End isVector = 1
1481
1482 def : SIN_PAT <SIN_cm>;
1483 def : COS_PAT <COS_cm>;
1484
1485 defm DIV_cm : DIV_Common<RECIP_IEEE_cm>;
1486
1487 // RECIP_UINT emulation for Cayman
1488 def : Pat <
1489   (AMDGPUurecip R600_Reg32:$src0),
1490   (FLT_TO_UINT_eg (MUL_IEEE (RECIP_IEEE_cm (UINT_TO_FLT_eg R600_Reg32:$src0)),
1491                             (MOV_IMM_I32 0x4f800000)))
1492 >;
1493
1494
1495 def : Pat<(fsqrt R600_Reg32:$src),
1496   (MUL R600_Reg32:$src, (RECIPSQRT_CLAMPED_cm R600_Reg32:$src))>;
1497
1498 } // End isCayman
1499
1500 //===----------------------------------------------------------------------===//
1501 // Branch Instructions
1502 //===----------------------------------------------------------------------===//
1503
1504
1505 def IF_PREDICATE_SET  : ILFormat<(outs), (ins GPRI32:$src),
1506   "IF_PREDICATE_SET $src", []>;
1507
1508 def PREDICATED_BREAK : ILFormat<(outs), (ins GPRI32:$src),
1509   "PREDICATED_BREAK $src", []>;
1510
1511 //===----------------------------------------------------------------------===//
1512 // Pseudo instructions
1513 //===----------------------------------------------------------------------===//
1514
1515 let isPseudo = 1 in {
1516
1517 def PRED_X : InstR600 <
1518   0, (outs R600_Predicate_Bit:$dst),
1519   (ins R600_Reg32:$src0, i32imm:$src1, i32imm:$flags),
1520   "", [], NullALU> {
1521   let FlagOperandIdx = 3;
1522 }
1523
1524 let isTerminator = 1, isBranch = 1, isBarrier = 1 in {
1525
1526 def JUMP : InstR600 <0x10,
1527           (outs),
1528           (ins brtarget:$target, R600_Pred:$p),
1529           "JUMP $target ($p)",
1530           [], AnyALU
1531   >;
1532
1533 }  // End isTerminator = 1, isBranch = 1, isBarrier = 1
1534
1535 let usesCustomInserter = 1 in {
1536
1537 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in {
1538
1539 def MASK_WRITE : AMDGPUShaderInst <
1540     (outs),
1541     (ins R600_Reg32:$src),
1542     "MASK_WRITE $src",
1543     []
1544 >;
1545
1546 } // End mayLoad = 0, mayStore = 0, hasSideEffects = 1
1547
1548
1549 def RESERVE_REG : AMDGPUShaderInst <
1550   (outs),
1551   (ins i32imm:$src),
1552   "RESERVE_REG $src",
1553   [(int_AMDGPU_reserve_reg imm:$src)]
1554 >;
1555 def TXD: AMDGPUShaderInst <
1556   (outs R600_Reg128:$dst),
1557   (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
1558   "TXD $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget",
1559   [(set R600_Reg128:$dst, (int_AMDGPU_txd R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, imm:$resourceId, imm:$samplerId, imm:$textureTarget))]
1560 >;
1561
1562 def TXD_SHADOW: AMDGPUShaderInst <
1563   (outs R600_Reg128:$dst),
1564   (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
1565   "TXD_SHADOW $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget",
1566   [(set R600_Reg128:$dst, (int_AMDGPU_txd R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, imm:$resourceId, imm:$samplerId, TEX_SHADOW:$textureTarget))]
1567 >;
1568
1569 } // End isPseudo = 1
1570 } // End usesCustomInserter = 1
1571
1572 def CLAMP_R600 :  CLAMP <R600_Reg32>;
1573 def FABS_R600 : FABS<R600_Reg32>;
1574 def FNEG_R600 : FNEG<R600_Reg32>;
1575
1576 //===---------------------------------------------------------------------===//
1577 // Return instruction
1578 //===---------------------------------------------------------------------===//
1579 let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
1580   def RETURN          : ILFormat<(outs), (ins variable_ops),
1581       "RETURN", [(IL_retflag)]>;
1582 }
1583
1584
1585 //===----------------------------------------------------------------------===//
1586 // Constant Buffer Addressing Support
1587 //===----------------------------------------------------------------------===//
1588
1589 let isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU"  in {
1590 def CONST_COPY : Instruction {
1591   let OutOperandList = (outs R600_Reg32:$dst);
1592   let InOperandList = (ins i32imm:$src);
1593   let Pattern = [(set R600_Reg32:$dst, (CONST_ADDRESS ADDRGA_CONST_OFFSET:$src))];
1594   let AsmString = "CONST_COPY";
1595   let neverHasSideEffects = 1;
1596   let isAsCheapAsAMove = 1;
1597   let Itinerary = NullALU;
1598 }
1599 } // end isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU"
1600
1601 def TEX_VTX_CONSTBUF :
1602   InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr), "VTX_READ_eg $dst, $ptr",
1603       [(set R600_Reg128:$dst, (CONST_ADDRESS ADDRGA_VAR_OFFSET:$ptr))]>,
1604   VTX_WORD1_GPR, VTX_WORD0 {
1605
1606   let VC_INST = 0;
1607   let FETCH_TYPE = 2;
1608   let FETCH_WHOLE_QUAD = 0;
1609   let BUFFER_ID = 0;
1610   let SRC_REL = 0;
1611   let SRC_SEL_X = 0;
1612   let DST_REL = 0;
1613   let USE_CONST_FIELDS = 0;
1614   let NUM_FORMAT_ALL = 2;
1615   let FORMAT_COMP_ALL = 1;
1616   let SRF_MODE_ALL = 1;
1617   let MEGA_FETCH_COUNT = 16;
1618   let DST_SEL_X        = 0;
1619   let DST_SEL_Y        = 1;
1620   let DST_SEL_Z        = 2;
1621   let DST_SEL_W        = 3;
1622   let DATA_FORMAT      = 35;
1623
1624   let Inst{31-0} = Word0;
1625   let Inst{63-32} = Word1;
1626
1627 // LLVM can only encode 64-bit instructions, so these fields are manually
1628 // encoded in R600CodeEmitter
1629 //
1630 // bits<16> OFFSET;
1631 // bits<2>  ENDIAN_SWAP = 0;
1632 // bits<1>  CONST_BUF_NO_STRIDE = 0;
1633 // bits<1>  MEGA_FETCH = 0;
1634 // bits<1>  ALT_CONST = 0;
1635 // bits<2>  BUFFER_INDEX_MODE = 0;
1636
1637
1638
1639 // VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
1640 // is done in R600CodeEmitter
1641 //
1642 // Inst{79-64} = OFFSET;
1643 // Inst{81-80} = ENDIAN_SWAP;
1644 // Inst{82}    = CONST_BUF_NO_STRIDE;
1645 // Inst{83}    = MEGA_FETCH;
1646 // Inst{84}    = ALT_CONST;
1647 // Inst{86-85} = BUFFER_INDEX_MODE;
1648 // Inst{95-86} = 0; Reserved
1649
1650 // VTX_WORD3 (Padding)
1651 //
1652 // Inst{127-96} = 0;
1653 }
1654
1655
1656 //===--------------------------------------------------------------------===//
1657 // Instructions support
1658 //===--------------------------------------------------------------------===//
1659 //===---------------------------------------------------------------------===//
1660 // Custom Inserter for Branches and returns, this eventually will be a
1661 // seperate pass
1662 //===---------------------------------------------------------------------===//
1663 let isTerminator = 1, usesCustomInserter = 1, isBranch = 1, isBarrier = 1 in {
1664   def BRANCH : ILFormat<(outs), (ins brtarget:$target),
1665       "; Pseudo unconditional branch instruction",
1666       [(br bb:$target)]>;
1667   defm BRANCH_COND : BranchConditional<IL_brcond>;
1668 }
1669
1670 //===---------------------------------------------------------------------===//
1671 // Flow and Program control Instructions
1672 //===---------------------------------------------------------------------===//
1673 let isTerminator=1 in {
1674   def SWITCH      : ILFormat< (outs), (ins GPRI32:$src),
1675   !strconcat("SWITCH", " $src"), []>;
1676   def CASE        : ILFormat< (outs), (ins GPRI32:$src),
1677       !strconcat("CASE", " $src"), []>;
1678   def BREAK       : ILFormat< (outs), (ins),
1679       "BREAK", []>;
1680   def CONTINUE    : ILFormat< (outs), (ins),
1681       "CONTINUE", []>;
1682   def DEFAULT     : ILFormat< (outs), (ins),
1683       "DEFAULT", []>;
1684   def ELSE        : ILFormat< (outs), (ins),
1685       "ELSE", []>;
1686   def ENDSWITCH   : ILFormat< (outs), (ins),
1687       "ENDSWITCH", []>;
1688   def ENDMAIN     : ILFormat< (outs), (ins),
1689       "ENDMAIN", []>;
1690   def END         : ILFormat< (outs), (ins),
1691       "END", []>;
1692   def ENDFUNC     : ILFormat< (outs), (ins),
1693       "ENDFUNC", []>;
1694   def ENDIF       : ILFormat< (outs), (ins),
1695       "ENDIF", []>;
1696   def WHILELOOP   : ILFormat< (outs), (ins),
1697       "WHILE", []>;
1698   def ENDLOOP     : ILFormat< (outs), (ins),
1699       "ENDLOOP", []>;
1700   def FUNC        : ILFormat< (outs), (ins),
1701       "FUNC", []>;
1702   def RETDYN      : ILFormat< (outs), (ins),
1703       "RET_DYN", []>;
1704   // This opcode has custom swizzle pattern encoded in Swizzle Encoder
1705   defm IF_LOGICALNZ  : BranchInstr<"IF_LOGICALNZ">;
1706   // This opcode has custom swizzle pattern encoded in Swizzle Encoder
1707   defm IF_LOGICALZ   : BranchInstr<"IF_LOGICALZ">;
1708   // This opcode has custom swizzle pattern encoded in Swizzle Encoder
1709   defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">;
1710   // This opcode has custom swizzle pattern encoded in Swizzle Encoder
1711   defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">;
1712   // This opcode has custom swizzle pattern encoded in Swizzle Encoder
1713   defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">;
1714   // This opcode has custom swizzle pattern encoded in Swizzle Encoder
1715   defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">;
1716   defm IFC         : BranchInstr2<"IFC">;
1717   defm BREAKC      : BranchInstr2<"BREAKC">;
1718   defm CONTINUEC   : BranchInstr2<"CONTINUEC">;
1719 }
1720
1721 //===----------------------------------------------------------------------===//
1722 // ISel Patterns
1723 //===----------------------------------------------------------------------===//
1724
1725 //CNDGE_INT extra pattern
1726 def : Pat <
1727   (selectcc (i32 R600_Reg32:$src0), -1, (i32 R600_Reg32:$src1),
1728                                         (i32 R600_Reg32:$src2), COND_GT),
1729   (CNDGE_INT R600_Reg32:$src0, R600_Reg32:$src1, R600_Reg32:$src2)
1730 >;
1731
1732 // KIL Patterns
1733 def KILP : Pat <
1734   (int_AMDGPU_kilp),
1735   (MASK_WRITE (KILLGT (f32 ONE), (f32 ZERO)))
1736 >;
1737
1738 def KIL : Pat <
1739   (int_AMDGPU_kill R600_Reg32:$src0),
1740   (MASK_WRITE (KILLGT (f32 ZERO), (f32 R600_Reg32:$src0)))
1741 >;
1742
1743 // SGT Reverse args
1744 def : Pat <
1745   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, COND_LT),
1746   (SGT R600_Reg32:$src1, R600_Reg32:$src0)
1747 >;
1748
1749 // SGE Reverse args
1750 def : Pat <
1751   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, COND_LE),
1752   (SGE R600_Reg32:$src1, R600_Reg32:$src0) 
1753 >;
1754
1755 // SETGT_INT reverse args
1756 def : Pat <
1757   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETLT),
1758   (SETGT_INT R600_Reg32:$src1, R600_Reg32:$src0)
1759 >;
1760
1761 // SETGE_INT reverse args
1762 def : Pat <
1763   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETLE),
1764   (SETGE_INT R600_Reg32:$src1, R600_Reg32:$src0)
1765 >;
1766
1767 // SETGT_UINT reverse args
1768 def : Pat <
1769   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETULT),
1770   (SETGT_UINT R600_Reg32:$src1, R600_Reg32:$src0)
1771 >;
1772
1773 // SETGE_UINT reverse args
1774 def : Pat <
1775   (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETULE),
1776   (SETGE_UINT R600_Reg32:$src1, R600_Reg32:$src0)
1777 >;
1778
1779 // The next two patterns are special cases for handling 'true if ordered' and
1780 // 'true if unordered' conditionals.  The assumption here is that the behavior of
1781 // SETE and SNE conforms to the Direct3D 10 rules for floating point values
1782 // described here:
1783 // http://msdn.microsoft.com/en-us/library/windows/desktop/cc308050.aspx#alpha_32_bit
1784 // We assume that  SETE returns false when one of the operands is NAN and
1785 // SNE returns true when on of the operands is NAN
1786
1787 //SETE - 'true if ordered'
1788 def : Pat <
1789   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, SETO),
1790   (SETE R600_Reg32:$src0, R600_Reg32:$src1)
1791 >;
1792
1793 //SNE - 'true if unordered'
1794 def : Pat <
1795   (selectcc (f32 R600_Reg32:$src0), R600_Reg32:$src1, FP_ONE, FP_ZERO, SETUO),
1796   (SNE R600_Reg32:$src0, R600_Reg32:$src1)
1797 >;
1798
1799 def : Extract_Element <f32, v4f32, R600_Reg128, 0, sel_x>;
1800 def : Extract_Element <f32, v4f32, R600_Reg128, 1, sel_y>;
1801 def : Extract_Element <f32, v4f32, R600_Reg128, 2, sel_z>;
1802 def : Extract_Element <f32, v4f32, R600_Reg128, 3, sel_w>;
1803
1804 def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 0, sel_x>;
1805 def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 1, sel_y>;
1806 def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 2, sel_z>;
1807 def : Insert_Element <f32, v4f32, R600_Reg32, R600_Reg128, 3, sel_w>;
1808
1809 def : Extract_Element <i32, v4i32, R600_Reg128, 0, sel_x>;
1810 def : Extract_Element <i32, v4i32, R600_Reg128, 1, sel_y>;
1811 def : Extract_Element <i32, v4i32, R600_Reg128, 2, sel_z>;
1812 def : Extract_Element <i32, v4i32, R600_Reg128, 3, sel_w>;
1813
1814 def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 0, sel_x>;
1815 def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 1, sel_y>;
1816 def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 2, sel_z>;
1817 def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 3, sel_w>;
1818
1819 def : Vector_Build <v4f32, R600_Reg128, f32, R600_Reg32>;
1820 def : Vector_Build <v4i32, R600_Reg128, i32, R600_Reg32>;
1821
1822 // bitconvert patterns
1823
1824 def : BitConvert <i32, f32, R600_Reg32>;
1825 def : BitConvert <f32, i32, R600_Reg32>;
1826 def : BitConvert <v4f32, v4i32, R600_Reg128>;
1827 def : BitConvert <v4i32, v4f32, R600_Reg128>;
1828
1829 // DWORDADDR pattern
1830 def : DwordAddrPat  <i32, R600_Reg32>;
1831
1832 } // End isR600toCayman Predicate