brw_eu.h revision 9b4053cabd8bda180b352d2d2047209f6ca5f6e8
1/*
2 Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **********************************************************************/
27 /*
28  * Authors:
29  *   Keith Whitwell <keith@tungstengraphics.com>
30  */
31
32
33#ifndef BRW_EU_H
34#define BRW_EU_H
35
36#include <stdbool.h>
37#include "brw_structs.h"
38#include "brw_defines.h"
39#include "program/prog_instruction.h"
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
46#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
47
48#define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
49#define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
50#define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
51#define BRW_SWIZZLE_YYYY      BRW_SWIZZLE4(1,1,1,1)
52#define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
53#define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
54#define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
55
56static inline bool brw_is_single_value_swizzle(int swiz)
57{
58   return (swiz == BRW_SWIZZLE_XXXX ||
59	   swiz == BRW_SWIZZLE_YYYY ||
60	   swiz == BRW_SWIZZLE_ZZZZ ||
61	   swiz == BRW_SWIZZLE_WWWW);
62}
63
64#define REG_SIZE (8*4)
65
66
67/* These aren't hardware structs, just something useful for us to pass around:
68 *
69 * Align1 operation has a lot of control over input ranges.  Used in
70 * WM programs to implement shaders decomposed into "channel serial"
71 * or "structure of array" form:
72 */
73struct brw_reg
74{
75   GLuint type:4;
76   GLuint file:2;
77   GLuint nr:8;
78   GLuint subnr:5;		/* :1 in align16 */
79   GLuint negate:1;		/* source only */
80   GLuint abs:1;		/* source only */
81   GLuint vstride:4;		/* source only */
82   GLuint width:3;		/* src only, align1 only */
83   GLuint hstride:2;   		/* align1 only */
84   GLuint address_mode:1;	/* relative addressing, hopefully! */
85   GLuint pad0:1;
86
87   union {
88      struct {
89	 GLuint swizzle:8;		/* src only, align16 only */
90	 GLuint writemask:4;		/* dest only, align16 only */
91	 GLint  indirect_offset:10;	/* relative addressing offset */
92	 GLuint pad1:10;		/* two dwords total */
93      } bits;
94
95      GLfloat f;
96      GLint   d;
97      GLuint ud;
98   } dw1;
99};
100
101
102struct brw_indirect {
103   GLuint addr_subnr:4;
104   GLint addr_offset:10;
105   GLuint pad:18;
106};
107
108
109#define BRW_EU_MAX_INSN_STACK 5
110
111struct brw_compile {
112   struct brw_instruction *store;
113   int store_size;
114   GLuint nr_insn;
115
116   void *mem_ctx;
117
118   /* Allow clients to push/pop instruction state:
119    */
120   struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
121   bool compressed_stack[BRW_EU_MAX_INSN_STACK];
122   struct brw_instruction *current;
123
124   GLuint flag_value;
125   bool single_program_flow;
126   bool compressed;
127   struct brw_context *brw;
128
129   /* Control flow stacks:
130    * - if_stack contains IF and ELSE instructions which must be patched
131    *   (and popped) once the matching ENDIF instruction is encountered.
132    *
133    *   Just store the instruction pointer(an index).
134    */
135   int *if_stack;
136   int if_stack_depth;
137   int if_stack_array_size;
138
139   /**
140    * loop_stack contains the instruction pointers of the starts of loops which
141    * must be patched (and popped) once the matching WHILE instruction is
142    * encountered.
143    */
144   int *loop_stack;
145   /**
146    * pre-gen6, the BREAK and CONT instructions had to tell how many IF/ENDIF
147    * blocks they were popping out of, to fix up the mask stack.  This tracks
148    * the IF/ENDIF nesting in each current nested loop level.
149    */
150   int *if_depth_in_loop;
151   int loop_stack_depth;
152   int loop_stack_array_size;
153};
154
155static INLINE int type_sz( GLuint type )
156{
157   switch( type ) {
158   case BRW_REGISTER_TYPE_UD:
159   case BRW_REGISTER_TYPE_D:
160   case BRW_REGISTER_TYPE_F:
161      return 4;
162   case BRW_REGISTER_TYPE_HF:
163   case BRW_REGISTER_TYPE_UW:
164   case BRW_REGISTER_TYPE_W:
165      return 2;
166   case BRW_REGISTER_TYPE_UB:
167   case BRW_REGISTER_TYPE_B:
168      return 1;
169   default:
170      return 0;
171   }
172}
173
174/**
175 * Construct a brw_reg.
176 * \param file  one of the BRW_x_REGISTER_FILE values
177 * \param nr  register number/index
178 * \param subnr  register sub number
179 * \param type  one of BRW_REGISTER_TYPE_x
180 * \param vstride  one of BRW_VERTICAL_STRIDE_x
181 * \param width  one of BRW_WIDTH_x
182 * \param hstride  one of BRW_HORIZONTAL_STRIDE_x
183 * \param swizzle  one of BRW_SWIZZLE_x
184 * \param writemask  WRITEMASK_X/Y/Z/W bitfield
185 */
186static INLINE struct brw_reg brw_reg( GLuint file,
187                                      GLuint nr,
188                                      GLuint subnr,
189                                      GLuint type,
190                                      GLuint vstride,
191                                      GLuint width,
192                                      GLuint hstride,
193                                      GLuint swizzle,
194                                      GLuint writemask )
195{
196   struct brw_reg reg;
197   if (file == BRW_GENERAL_REGISTER_FILE)
198      assert(nr < BRW_MAX_GRF);
199   else if (file == BRW_MESSAGE_REGISTER_FILE)
200      assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
201   else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
202      assert(nr <= BRW_ARF_IP);
203
204   reg.type = type;
205   reg.file = file;
206   reg.nr = nr;
207   reg.subnr = subnr * type_sz(type);
208   reg.negate = 0;
209   reg.abs = 0;
210   reg.vstride = vstride;
211   reg.width = width;
212   reg.hstride = hstride;
213   reg.address_mode = BRW_ADDRESS_DIRECT;
214   reg.pad0 = 0;
215
216   /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
217    * set swizzle and writemask to W, as the lower bits of subnr will
218    * be lost when converted to align16.  This is probably too much to
219    * keep track of as you'd want it adjusted by suboffset(), etc.
220    * Perhaps fix up when converting to align16?
221    */
222   reg.dw1.bits.swizzle = swizzle;
223   reg.dw1.bits.writemask = writemask;
224   reg.dw1.bits.indirect_offset = 0;
225   reg.dw1.bits.pad1 = 0;
226   return reg;
227}
228
229/** Construct float[16] register */
230static INLINE struct brw_reg brw_vec16_reg( GLuint file,
231					      GLuint nr,
232					      GLuint subnr )
233{
234   return brw_reg(file,
235		  nr,
236		  subnr,
237		  BRW_REGISTER_TYPE_F,
238		  BRW_VERTICAL_STRIDE_16,
239		  BRW_WIDTH_16,
240		  BRW_HORIZONTAL_STRIDE_1,
241		  BRW_SWIZZLE_XYZW,
242		  WRITEMASK_XYZW);
243}
244
245/** Construct float[8] register */
246static INLINE struct brw_reg brw_vec8_reg( GLuint file,
247					     GLuint nr,
248					     GLuint subnr )
249{
250   return brw_reg(file,
251		  nr,
252		  subnr,
253		  BRW_REGISTER_TYPE_F,
254		  BRW_VERTICAL_STRIDE_8,
255		  BRW_WIDTH_8,
256		  BRW_HORIZONTAL_STRIDE_1,
257		  BRW_SWIZZLE_XYZW,
258		  WRITEMASK_XYZW);
259}
260
261/** Construct float[4] register */
262static INLINE struct brw_reg brw_vec4_reg( GLuint file,
263					      GLuint nr,
264					      GLuint subnr )
265{
266   return brw_reg(file,
267		  nr,
268		  subnr,
269		  BRW_REGISTER_TYPE_F,
270		  BRW_VERTICAL_STRIDE_4,
271		  BRW_WIDTH_4,
272		  BRW_HORIZONTAL_STRIDE_1,
273		  BRW_SWIZZLE_XYZW,
274		  WRITEMASK_XYZW);
275}
276
277/** Construct float[2] register */
278static INLINE struct brw_reg brw_vec2_reg( GLuint file,
279					      GLuint nr,
280					      GLuint subnr )
281{
282   return brw_reg(file,
283		  nr,
284		  subnr,
285		  BRW_REGISTER_TYPE_F,
286		  BRW_VERTICAL_STRIDE_2,
287		  BRW_WIDTH_2,
288		  BRW_HORIZONTAL_STRIDE_1,
289		  BRW_SWIZZLE_XYXY,
290		  WRITEMASK_XY);
291}
292
293/** Construct float[1] register */
294static INLINE struct brw_reg brw_vec1_reg( GLuint file,
295					     GLuint nr,
296					     GLuint subnr )
297{
298   return brw_reg(file,
299		  nr,
300		  subnr,
301		  BRW_REGISTER_TYPE_F,
302		  BRW_VERTICAL_STRIDE_0,
303		  BRW_WIDTH_1,
304		  BRW_HORIZONTAL_STRIDE_0,
305		  BRW_SWIZZLE_XXXX,
306		  WRITEMASK_X);
307}
308
309
310static INLINE struct brw_reg retype( struct brw_reg reg,
311				       GLuint type )
312{
313   reg.type = type;
314   return reg;
315}
316
317static inline struct brw_reg
318sechalf(struct brw_reg reg)
319{
320   if (reg.vstride)
321      reg.nr++;
322   return reg;
323}
324
325static INLINE struct brw_reg suboffset( struct brw_reg reg,
326					  GLuint delta )
327{
328   reg.subnr += delta * type_sz(reg.type);
329   return reg;
330}
331
332
333static INLINE struct brw_reg offset( struct brw_reg reg,
334				       GLuint delta )
335{
336   reg.nr += delta;
337   return reg;
338}
339
340
341static INLINE struct brw_reg byte_offset( struct brw_reg reg,
342					    GLuint bytes )
343{
344   GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
345   reg.nr = newoffset / REG_SIZE;
346   reg.subnr = newoffset % REG_SIZE;
347   return reg;
348}
349
350
351/** Construct unsigned word[16] register */
352static INLINE struct brw_reg brw_uw16_reg( GLuint file,
353					     GLuint nr,
354					     GLuint subnr )
355{
356   return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
357}
358
359/** Construct unsigned word[8] register */
360static INLINE struct brw_reg brw_uw8_reg( GLuint file,
361					    GLuint nr,
362					    GLuint subnr )
363{
364   return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
365}
366
367/** Construct unsigned word[1] register */
368static INLINE struct brw_reg brw_uw1_reg( GLuint file,
369					    GLuint nr,
370					    GLuint subnr )
371{
372   return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
373}
374
375static INLINE struct brw_reg brw_imm_reg( GLuint type )
376{
377   return brw_reg( BRW_IMMEDIATE_VALUE,
378		   0,
379		   0,
380		   type,
381		   BRW_VERTICAL_STRIDE_0,
382		   BRW_WIDTH_1,
383		   BRW_HORIZONTAL_STRIDE_0,
384		   0,
385		   0);
386}
387
388/** Construct float immediate register */
389static INLINE struct brw_reg brw_imm_f( GLfloat f )
390{
391   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
392   imm.dw1.f = f;
393   return imm;
394}
395
396/** Construct integer immediate register */
397static INLINE struct brw_reg brw_imm_d( GLint d )
398{
399   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
400   imm.dw1.d = d;
401   return imm;
402}
403
404/** Construct uint immediate register */
405static INLINE struct brw_reg brw_imm_ud( GLuint ud )
406{
407   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
408   imm.dw1.ud = ud;
409   return imm;
410}
411
412/** Construct ushort immediate register */
413static INLINE struct brw_reg brw_imm_uw( GLushort uw )
414{
415   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
416   imm.dw1.ud = uw | (uw << 16);
417   return imm;
418}
419
420/** Construct short immediate register */
421static INLINE struct brw_reg brw_imm_w( GLshort w )
422{
423   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
424   imm.dw1.d = w | (w << 16);
425   return imm;
426}
427
428/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
429 * numbers alias with _V and _VF below:
430 */
431
432/** Construct vector of eight signed half-byte values */
433static INLINE struct brw_reg brw_imm_v( GLuint v )
434{
435   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
436   imm.vstride = BRW_VERTICAL_STRIDE_0;
437   imm.width = BRW_WIDTH_8;
438   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
439   imm.dw1.ud = v;
440   return imm;
441}
442
443/** Construct vector of four 8-bit float values */
444static INLINE struct brw_reg brw_imm_vf( GLuint v )
445{
446   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
447   imm.vstride = BRW_VERTICAL_STRIDE_0;
448   imm.width = BRW_WIDTH_4;
449   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
450   imm.dw1.ud = v;
451   return imm;
452}
453
454#define VF_ZERO 0x0
455#define VF_ONE  0x30
456#define VF_NEG  (1<<7)
457
458static INLINE struct brw_reg brw_imm_vf4( GLuint v0,
459					    GLuint v1,
460					    GLuint v2,
461					    GLuint v3)
462{
463   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
464   imm.vstride = BRW_VERTICAL_STRIDE_0;
465   imm.width = BRW_WIDTH_4;
466   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
467   imm.dw1.ud = ((v0 << 0) |
468		 (v1 << 8) |
469		 (v2 << 16) |
470		 (v3 << 24));
471   return imm;
472}
473
474
475static INLINE struct brw_reg brw_address( struct brw_reg reg )
476{
477   return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
478}
479
480/** Construct float[1] general-purpose register */
481static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
482{
483   return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
484}
485
486/** Construct float[2] general-purpose register */
487static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
488{
489   return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
490}
491
492/** Construct float[4] general-purpose register */
493static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
494{
495   return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
496}
497
498/** Construct float[8] general-purpose register */
499static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
500{
501   return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
502}
503
504
505static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
506{
507   return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
508}
509
510static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
511{
512   return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
513}
514
515
516/** Construct null register (usually used for setting condition codes) */
517static INLINE struct brw_reg brw_null_reg( void )
518{
519   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
520		       BRW_ARF_NULL,
521		       0);
522}
523
524static INLINE struct brw_reg brw_address_reg( GLuint subnr )
525{
526   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
527		      BRW_ARF_ADDRESS,
528		      subnr);
529}
530
531/* If/else instructions break in align16 mode if writemask & swizzle
532 * aren't xyzw.  This goes against the convention for other scalar
533 * regs:
534 */
535static INLINE struct brw_reg brw_ip_reg( void )
536{
537   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
538		  BRW_ARF_IP,
539		  0,
540		  BRW_REGISTER_TYPE_UD,
541		  BRW_VERTICAL_STRIDE_4, /* ? */
542		  BRW_WIDTH_1,
543		  BRW_HORIZONTAL_STRIDE_0,
544		  BRW_SWIZZLE_XYZW, /* NOTE! */
545		  WRITEMASK_XYZW); /* NOTE! */
546}
547
548static INLINE struct brw_reg brw_acc_reg( void )
549{
550   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
551		       BRW_ARF_ACCUMULATOR,
552		       0);
553}
554
555static INLINE struct brw_reg brw_notification_1_reg(void)
556{
557
558   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
559		  BRW_ARF_NOTIFICATION_COUNT,
560		  1,
561		  BRW_REGISTER_TYPE_UD,
562		  BRW_VERTICAL_STRIDE_0,
563		  BRW_WIDTH_1,
564		  BRW_HORIZONTAL_STRIDE_0,
565		  BRW_SWIZZLE_XXXX,
566		  WRITEMASK_X);
567}
568
569
570static INLINE struct brw_reg brw_flag_reg( void )
571{
572   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
573		      BRW_ARF_FLAG,
574		      0);
575}
576
577
578static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
579{
580   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
581		      BRW_ARF_MASK,
582		      subnr);
583}
584
585static INLINE struct brw_reg brw_message_reg( GLuint nr )
586{
587   assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
588   return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
589		       nr,
590		       0);
591}
592
593
594
595
596/* This is almost always called with a numeric constant argument, so
597 * make things easy to evaluate at compile time:
598 */
599static INLINE GLuint cvt( GLuint val )
600{
601   switch (val) {
602   case 0: return 0;
603   case 1: return 1;
604   case 2: return 2;
605   case 4: return 3;
606   case 8: return 4;
607   case 16: return 5;
608   case 32: return 6;
609   }
610   return 0;
611}
612
613static INLINE struct brw_reg stride( struct brw_reg reg,
614				       GLuint vstride,
615				       GLuint width,
616				       GLuint hstride )
617{
618   reg.vstride = cvt(vstride);
619   reg.width = cvt(width) - 1;
620   reg.hstride = cvt(hstride);
621   return reg;
622}
623
624
625static INLINE struct brw_reg vec16( struct brw_reg reg )
626{
627   return stride(reg, 16,16,1);
628}
629
630static INLINE struct brw_reg vec8( struct brw_reg reg )
631{
632   return stride(reg, 8,8,1);
633}
634
635static INLINE struct brw_reg vec4( struct brw_reg reg )
636{
637   return stride(reg, 4,4,1);
638}
639
640static INLINE struct brw_reg vec2( struct brw_reg reg )
641{
642   return stride(reg, 2,2,1);
643}
644
645static INLINE struct brw_reg vec1( struct brw_reg reg )
646{
647   return stride(reg, 0,1,0);
648}
649
650
651static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
652{
653   return vec1(suboffset(reg, elt));
654}
655
656static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
657{
658   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
659}
660
661static INLINE struct brw_reg get_element_d( struct brw_reg reg, GLuint elt )
662{
663   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
664}
665
666
667static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
668					    GLuint x,
669					    GLuint y,
670					    GLuint z,
671					    GLuint w)
672{
673   assert(reg.file != BRW_IMMEDIATE_VALUE);
674
675   reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
676				       BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
677				       BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
678				       BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
679   return reg;
680}
681
682
683static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
684					     GLuint x )
685{
686   return brw_swizzle(reg, x, x, x, x);
687}
688
689static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
690					      GLuint mask )
691{
692   assert(reg.file != BRW_IMMEDIATE_VALUE);
693   reg.dw1.bits.writemask &= mask;
694   return reg;
695}
696
697static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
698						  GLuint mask )
699{
700   assert(reg.file != BRW_IMMEDIATE_VALUE);
701   reg.dw1.bits.writemask = mask;
702   return reg;
703}
704
705static INLINE struct brw_reg negate( struct brw_reg reg )
706{
707   reg.negate ^= 1;
708   return reg;
709}
710
711static INLINE struct brw_reg brw_abs( struct brw_reg reg )
712{
713   reg.abs = 1;
714   reg.negate = 0;
715   return reg;
716}
717
718/***********************************************************************
719 */
720static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
721						  GLint offset )
722{
723   struct brw_reg reg =  brw_vec4_grf(0, 0);
724   reg.subnr = subnr;
725   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
726   reg.dw1.bits.indirect_offset = offset;
727   return reg;
728}
729
730static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
731						  GLint offset )
732{
733   struct brw_reg reg =  brw_vec1_grf(0, 0);
734   reg.subnr = subnr;
735   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
736   reg.dw1.bits.indirect_offset = offset;
737   return reg;
738}
739
740static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
741{
742   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
743}
744
745static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
746{
747   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
748}
749
750static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
751{
752   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
753}
754
755static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
756{
757   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
758}
759
760static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
761{
762   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
763}
764
765static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
766{
767   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
768}
769
770static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
771{
772   return brw_address_reg(ptr.addr_subnr);
773}
774
775static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
776{
777   ptr.addr_offset += offset;
778   return ptr;
779}
780
781static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
782{
783   struct brw_indirect ptr;
784   ptr.addr_subnr = addr_subnr;
785   ptr.addr_offset = offset;
786   ptr.pad = 0;
787   return ptr;
788}
789
790/** Do two brw_regs refer to the same register? */
791static INLINE bool
792brw_same_reg(struct brw_reg r1, struct brw_reg r2)
793{
794   return r1.file == r2.file && r1.nr == r2.nr;
795}
796
797static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
798{
799   return &p->store[p->nr_insn];
800}
801
802void brw_pop_insn_state( struct brw_compile *p );
803void brw_push_insn_state( struct brw_compile *p );
804void brw_set_mask_control( struct brw_compile *p, GLuint value );
805void brw_set_saturate( struct brw_compile *p, bool enable );
806void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
807void brw_set_compression_control(struct brw_compile *p, enum brw_compression c);
808void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
809void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
810void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse);
811void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
812void brw_set_acc_write_control(struct brw_compile *p, GLuint value);
813
814void brw_init_compile(struct brw_context *, struct brw_compile *p,
815		      void *mem_ctx);
816const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
817
818struct brw_instruction *brw_next_insn(struct brw_compile *p, GLuint opcode);
819void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn,
820		  struct brw_reg dest);
821void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn,
822		  struct brw_reg reg);
823
824void gen6_resolve_implied_move(struct brw_compile *p,
825			       struct brw_reg *src,
826			       GLuint msg_reg_nr);
827
828/* Helpers for regular instructions:
829 */
830#define ALU1(OP)					\
831struct brw_instruction *brw_##OP(struct brw_compile *p,	\
832	      struct brw_reg dest,			\
833	      struct brw_reg src0);
834
835#define ALU2(OP)					\
836struct brw_instruction *brw_##OP(struct brw_compile *p,	\
837	      struct brw_reg dest,			\
838	      struct brw_reg src0,			\
839	      struct brw_reg src1);
840
841#define ALU3(OP)					\
842struct brw_instruction *brw_##OP(struct brw_compile *p,	\
843	      struct brw_reg dest,			\
844	      struct brw_reg src0,			\
845	      struct brw_reg src1,			\
846	      struct brw_reg src2);
847
848#define ROUND(OP) \
849void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0);
850
851ALU1(MOV)
852ALU2(SEL)
853ALU1(NOT)
854ALU2(AND)
855ALU2(OR)
856ALU2(XOR)
857ALU2(SHR)
858ALU2(SHL)
859ALU2(RSR)
860ALU2(RSL)
861ALU2(ASR)
862ALU2(JMPI)
863ALU2(ADD)
864ALU2(AVG)
865ALU2(MUL)
866ALU1(FRC)
867ALU1(RNDD)
868ALU2(MAC)
869ALU2(MACH)
870ALU1(LZD)
871ALU2(DP4)
872ALU2(DPH)
873ALU2(DP3)
874ALU2(DP2)
875ALU2(LINE)
876ALU2(PLN)
877ALU3(MAD)
878
879ROUND(RNDZ)
880ROUND(RNDE)
881
882#undef ALU1
883#undef ALU2
884#undef ALU3
885#undef ROUND
886
887
888/* Helpers for SEND instruction:
889 */
890void brw_set_sampler_message(struct brw_compile *p,
891                             struct brw_instruction *insn,
892                             GLuint binding_table_index,
893                             GLuint sampler,
894                             GLuint msg_type,
895                             GLuint response_length,
896                             GLuint msg_length,
897                             GLuint header_present,
898                             GLuint simd_mode,
899                             GLuint return_format);
900
901void brw_set_dp_read_message(struct brw_compile *p,
902			     struct brw_instruction *insn,
903			     GLuint binding_table_index,
904			     GLuint msg_control,
905			     GLuint msg_type,
906			     GLuint target_cache,
907			     GLuint msg_length,
908			     GLuint response_length);
909
910void brw_set_dp_write_message(struct brw_compile *p,
911			      struct brw_instruction *insn,
912			      GLuint binding_table_index,
913			      GLuint msg_control,
914			      GLuint msg_type,
915			      GLuint msg_length,
916			      bool header_present,
917			      GLuint last_render_target,
918			      GLuint response_length,
919			      GLuint end_of_thread,
920			      GLuint send_commit_msg);
921
922void brw_urb_WRITE(struct brw_compile *p,
923		   struct brw_reg dest,
924		   GLuint msg_reg_nr,
925		   struct brw_reg src0,
926		   bool allocate,
927		   bool used,
928		   GLuint msg_length,
929		   GLuint response_length,
930		   bool eot,
931		   bool writes_complete,
932		   GLuint offset,
933		   GLuint swizzle);
934
935void brw_ff_sync(struct brw_compile *p,
936		   struct brw_reg dest,
937		   GLuint msg_reg_nr,
938		   struct brw_reg src0,
939		   bool allocate,
940		   GLuint response_length,
941		   bool eot);
942
943void brw_svb_write(struct brw_compile *p,
944                   struct brw_reg dest,
945                   GLuint msg_reg_nr,
946                   struct brw_reg src0,
947                   GLuint binding_table_index,
948                   bool   send_commit_msg);
949
950void brw_fb_WRITE(struct brw_compile *p,
951		  int dispatch_width,
952		   GLuint msg_reg_nr,
953		   struct brw_reg src0,
954		   GLuint msg_control,
955		   GLuint binding_table_index,
956		   GLuint msg_length,
957		   GLuint response_length,
958		   bool eot,
959		   bool header_present);
960
961void brw_SAMPLE(struct brw_compile *p,
962		struct brw_reg dest,
963		GLuint msg_reg_nr,
964		struct brw_reg src0,
965		GLuint binding_table_index,
966		GLuint sampler,
967		GLuint writemask,
968		GLuint msg_type,
969		GLuint response_length,
970		GLuint msg_length,
971		GLuint header_present,
972		GLuint simd_mode,
973		GLuint return_format);
974
975void brw_math_16( struct brw_compile *p,
976		  struct brw_reg dest,
977		  GLuint function,
978		  GLuint msg_reg_nr,
979		  struct brw_reg src,
980		  GLuint precision );
981
982void brw_math( struct brw_compile *p,
983	       struct brw_reg dest,
984	       GLuint function,
985	       GLuint msg_reg_nr,
986	       struct brw_reg src,
987	       GLuint data_type,
988	       GLuint precision );
989
990void brw_math2(struct brw_compile *p,
991	       struct brw_reg dest,
992	       GLuint function,
993	       struct brw_reg src0,
994	       struct brw_reg src1);
995
996void brw_oword_block_read(struct brw_compile *p,
997			  struct brw_reg dest,
998			  struct brw_reg mrf,
999			  uint32_t offset,
1000			  uint32_t bind_table_index);
1001
1002void brw_oword_block_read_scratch(struct brw_compile *p,
1003				  struct brw_reg dest,
1004				  struct brw_reg mrf,
1005				  int num_regs,
1006				  GLuint offset);
1007
1008void brw_oword_block_write_scratch(struct brw_compile *p,
1009				   struct brw_reg mrf,
1010				   int num_regs,
1011				   GLuint offset);
1012
1013void brw_dword_scattered_read(struct brw_compile *p,
1014			      struct brw_reg dest,
1015			      struct brw_reg mrf,
1016			      uint32_t bind_table_index);
1017
1018void brw_dp_READ_4_vs( struct brw_compile *p,
1019                       struct brw_reg dest,
1020                       GLuint location,
1021                       GLuint bind_table_index );
1022
1023void brw_dp_READ_4_vs_relative(struct brw_compile *p,
1024			       struct brw_reg dest,
1025			       struct brw_reg addrReg,
1026			       GLuint offset,
1027			       GLuint bind_table_index);
1028
1029/* If/else/endif.  Works by manipulating the execution flags on each
1030 * channel.
1031 */
1032struct brw_instruction *brw_IF(struct brw_compile *p,
1033			       GLuint execute_size);
1034struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional,
1035				struct brw_reg src0, struct brw_reg src1);
1036
1037void brw_ELSE(struct brw_compile *p);
1038void brw_ENDIF(struct brw_compile *p);
1039
1040/* DO/WHILE loops:
1041 */
1042struct brw_instruction *brw_DO(struct brw_compile *p,
1043			       GLuint execute_size);
1044
1045struct brw_instruction *brw_WHILE(struct brw_compile *p);
1046
1047struct brw_instruction *brw_BREAK(struct brw_compile *p);
1048struct brw_instruction *brw_CONT(struct brw_compile *p);
1049struct brw_instruction *gen6_CONT(struct brw_compile *p);
1050/* Forward jumps:
1051 */
1052void brw_land_fwd_jump(struct brw_compile *p, int jmp_insn_idx);
1053
1054
1055
1056void brw_NOP(struct brw_compile *p);
1057
1058void brw_WAIT(struct brw_compile *p);
1059
1060/* Special case: there is never a destination, execution size will be
1061 * taken from src0:
1062 */
1063void brw_CMP(struct brw_compile *p,
1064	     struct brw_reg dest,
1065	     GLuint conditional,
1066	     struct brw_reg src0,
1067	     struct brw_reg src1);
1068
1069void brw_print_reg( struct brw_reg reg );
1070
1071
1072/***********************************************************************
1073 * brw_eu_util.c:
1074 */
1075
1076void brw_copy_indirect_to_indirect(struct brw_compile *p,
1077				   struct brw_indirect dst_ptr,
1078				   struct brw_indirect src_ptr,
1079				   GLuint count);
1080
1081void brw_copy_from_indirect(struct brw_compile *p,
1082			    struct brw_reg dst,
1083			    struct brw_indirect ptr,
1084			    GLuint count);
1085
1086void brw_copy4(struct brw_compile *p,
1087	       struct brw_reg dst,
1088	       struct brw_reg src,
1089	       GLuint count);
1090
1091void brw_copy8(struct brw_compile *p,
1092	       struct brw_reg dst,
1093	       struct brw_reg src,
1094	       GLuint count);
1095
1096void brw_math_invert( struct brw_compile *p,
1097		      struct brw_reg dst,
1098		      struct brw_reg src);
1099
1100void brw_set_src1(struct brw_compile *p,
1101		  struct brw_instruction *insn,
1102		  struct brw_reg reg);
1103
1104void brw_set_uip_jip(struct brw_compile *p);
1105
1106uint32_t brw_swap_cmod(uint32_t cmod);
1107
1108/* brw_optimize.c */
1109void brw_optimize(struct brw_compile *p);
1110void brw_remove_duplicate_mrf_moves(struct brw_compile *p);
1111void brw_remove_grf_to_mrf_moves(struct brw_compile *p);
1112
1113#ifdef __cplusplus
1114}
1115#endif
1116
1117#endif
1118