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