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