brw_eu.h revision 3f5e938a9ded42ae8dc9ae2486e8d5c8b64cfe07
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   return reg;
702}
703
704/***********************************************************************
705 */
706static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
707						  GLint offset )
708{
709   struct brw_reg reg =  brw_vec4_grf(0, 0);
710   reg.subnr = subnr;
711   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
712   reg.dw1.bits.indirect_offset = offset;
713   return reg;
714}
715
716static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
717						  GLint offset )
718{
719   struct brw_reg reg =  brw_vec1_grf(0, 0);
720   reg.subnr = subnr;
721   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
722   reg.dw1.bits.indirect_offset = offset;
723   return reg;
724}
725
726static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
727{
728   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
729}
730
731static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
732{
733   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
734}
735
736static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
737{
738   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
739}
740
741static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
742{
743   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
744}
745
746static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
747{
748   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
749}
750
751static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
752{
753   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
754}
755
756static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
757{
758   return brw_address_reg(ptr.addr_subnr);
759}
760
761static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
762{
763   ptr.addr_offset += offset;
764   return ptr;
765}
766
767static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
768{
769   struct brw_indirect ptr;
770   ptr.addr_subnr = addr_subnr;
771   ptr.addr_offset = offset;
772   ptr.pad = 0;
773   return ptr;
774}
775
776/** Do two brw_regs refer to the same register? */
777static INLINE GLboolean
778brw_same_reg(struct brw_reg r1, struct brw_reg r2)
779{
780   return r1.file == r2.file && r1.nr == r2.nr;
781}
782
783static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
784{
785   return &p->store[p->nr_insn];
786}
787
788void brw_pop_insn_state( struct brw_compile *p );
789void brw_push_insn_state( struct brw_compile *p );
790void brw_set_mask_control( struct brw_compile *p, GLuint value );
791void brw_set_saturate( struct brw_compile *p, GLuint value );
792void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
793void brw_set_compression_control(struct brw_compile *p, enum brw_compression c);
794void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
795void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
796void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse);
797void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
798void brw_set_acc_write_control(struct brw_compile *p, GLuint value);
799
800void brw_init_compile(struct brw_context *, struct brw_compile *p,
801		      void *mem_ctx);
802const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
803
804struct brw_instruction *brw_next_insn(struct brw_compile *p, GLuint opcode);
805void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn,
806		  struct brw_reg dest);
807void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn,
808		  struct brw_reg reg);
809
810void gen6_resolve_implied_move(struct brw_compile *p,
811			       struct brw_reg *src,
812			       GLuint msg_reg_nr);
813
814/* Helpers for regular instructions:
815 */
816#define ALU1(OP)					\
817struct brw_instruction *brw_##OP(struct brw_compile *p,	\
818	      struct brw_reg dest,			\
819	      struct brw_reg src0);
820
821#define ALU2(OP)					\
822struct brw_instruction *brw_##OP(struct brw_compile *p,	\
823	      struct brw_reg dest,			\
824	      struct brw_reg src0,			\
825	      struct brw_reg src1);
826
827#define ROUND(OP) \
828void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0);
829
830
831ALU1(MOV)
832ALU2(SEL)
833ALU1(NOT)
834ALU2(AND)
835ALU2(OR)
836ALU2(XOR)
837ALU2(SHR)
838ALU2(SHL)
839ALU2(RSR)
840ALU2(RSL)
841ALU2(ASR)
842ALU2(JMPI)
843ALU2(ADD)
844ALU2(MUL)
845ALU1(FRC)
846ALU1(RNDD)
847ALU2(MAC)
848ALU2(MACH)
849ALU1(LZD)
850ALU2(DP4)
851ALU2(DPH)
852ALU2(DP3)
853ALU2(DP2)
854ALU2(LINE)
855ALU2(PLN)
856
857ROUND(RNDZ)
858ROUND(RNDE)
859
860#undef ALU1
861#undef ALU2
862#undef ROUND
863
864
865/* Helpers for SEND instruction:
866 */
867void brw_set_dp_read_message(struct brw_compile *p,
868			     struct brw_instruction *insn,
869			     GLuint binding_table_index,
870			     GLuint msg_control,
871			     GLuint msg_type,
872			     GLuint target_cache,
873			     GLuint msg_length,
874			     GLuint response_length);
875
876void brw_set_dp_write_message(struct brw_compile *p,
877			      struct brw_instruction *insn,
878			      GLuint binding_table_index,
879			      GLuint msg_control,
880			      GLuint msg_type,
881			      GLuint msg_length,
882			      GLboolean header_present,
883			      GLuint pixel_scoreboard_clear,
884			      GLuint response_length,
885			      GLuint end_of_thread,
886			      GLuint send_commit_msg);
887
888void brw_urb_WRITE(struct brw_compile *p,
889		   struct brw_reg dest,
890		   GLuint msg_reg_nr,
891		   struct brw_reg src0,
892		   GLboolean allocate,
893		   GLboolean used,
894		   GLuint msg_length,
895		   GLuint response_length,
896		   GLboolean eot,
897		   GLboolean writes_complete,
898		   GLuint offset,
899		   GLuint swizzle);
900
901void brw_ff_sync(struct brw_compile *p,
902		   struct brw_reg dest,
903		   GLuint msg_reg_nr,
904		   struct brw_reg src0,
905		   GLboolean allocate,
906		   GLuint response_length,
907		   GLboolean eot);
908
909void brw_fb_WRITE(struct brw_compile *p,
910		  int dispatch_width,
911		   GLuint msg_reg_nr,
912		   struct brw_reg src0,
913		   GLuint binding_table_index,
914		   GLuint msg_length,
915		   GLuint response_length,
916		   GLboolean eot,
917		   GLboolean header_present);
918
919void brw_SAMPLE(struct brw_compile *p,
920		struct brw_reg dest,
921		GLuint msg_reg_nr,
922		struct brw_reg src0,
923		GLuint binding_table_index,
924		GLuint sampler,
925		GLuint writemask,
926		GLuint msg_type,
927		GLuint response_length,
928		GLuint msg_length,
929		GLboolean eot,
930		GLuint header_present,
931		GLuint simd_mode);
932
933void brw_math_16( struct brw_compile *p,
934		  struct brw_reg dest,
935		  GLuint function,
936		  GLuint saturate,
937		  GLuint msg_reg_nr,
938		  struct brw_reg src,
939		  GLuint precision );
940
941void brw_math( struct brw_compile *p,
942	       struct brw_reg dest,
943	       GLuint function,
944	       GLuint saturate,
945	       GLuint msg_reg_nr,
946	       struct brw_reg src,
947	       GLuint data_type,
948	       GLuint precision );
949
950void brw_math2(struct brw_compile *p,
951	       struct brw_reg dest,
952	       GLuint function,
953	       struct brw_reg src0,
954	       struct brw_reg src1);
955
956void brw_oword_block_read(struct brw_compile *p,
957			  struct brw_reg dest,
958			  struct brw_reg mrf,
959			  uint32_t offset,
960			  uint32_t bind_table_index);
961
962void brw_oword_block_read_scratch(struct brw_compile *p,
963				  struct brw_reg dest,
964				  struct brw_reg mrf,
965				  int num_regs,
966				  GLuint offset);
967
968void brw_oword_block_write_scratch(struct brw_compile *p,
969				   struct brw_reg mrf,
970				   int num_regs,
971				   GLuint offset);
972
973void brw_dword_scattered_read(struct brw_compile *p,
974			      struct brw_reg dest,
975			      struct brw_reg mrf,
976			      uint32_t bind_table_index);
977
978void brw_dp_READ_4_vs( struct brw_compile *p,
979                       struct brw_reg dest,
980                       GLuint location,
981                       GLuint bind_table_index );
982
983void brw_dp_READ_4_vs_relative(struct brw_compile *p,
984			       struct brw_reg dest,
985			       struct brw_reg addrReg,
986			       GLuint offset,
987			       GLuint bind_table_index);
988
989/* If/else/endif.  Works by manipulating the execution flags on each
990 * channel.
991 */
992struct brw_instruction *brw_IF(struct brw_compile *p,
993			       GLuint execute_size);
994struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional,
995				struct brw_reg src0, struct brw_reg src1);
996
997void brw_ELSE(struct brw_compile *p);
998void brw_ENDIF(struct brw_compile *p);
999
1000/* DO/WHILE loops:
1001 */
1002struct brw_instruction *brw_DO(struct brw_compile *p,
1003			       GLuint execute_size);
1004
1005struct brw_instruction *brw_WHILE(struct brw_compile *p,
1006	       struct brw_instruction *patch_insn);
1007
1008struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count);
1009struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count);
1010struct brw_instruction *gen6_CONT(struct brw_compile *p,
1011				  struct brw_instruction *do_insn);
1012/* Forward jumps:
1013 */
1014void brw_land_fwd_jump(struct brw_compile *p,
1015		       struct brw_instruction *jmp_insn);
1016
1017
1018
1019void brw_NOP(struct brw_compile *p);
1020
1021void brw_WAIT(struct brw_compile *p);
1022
1023/* Special case: there is never a destination, execution size will be
1024 * taken from src0:
1025 */
1026void brw_CMP(struct brw_compile *p,
1027	     struct brw_reg dest,
1028	     GLuint conditional,
1029	     struct brw_reg src0,
1030	     struct brw_reg src1);
1031
1032void brw_print_reg( struct brw_reg reg );
1033
1034
1035/***********************************************************************
1036 * brw_eu_util.c:
1037 */
1038
1039void brw_copy_indirect_to_indirect(struct brw_compile *p,
1040				   struct brw_indirect dst_ptr,
1041				   struct brw_indirect src_ptr,
1042				   GLuint count);
1043
1044void brw_copy_from_indirect(struct brw_compile *p,
1045			    struct brw_reg dst,
1046			    struct brw_indirect ptr,
1047			    GLuint count);
1048
1049void brw_copy4(struct brw_compile *p,
1050	       struct brw_reg dst,
1051	       struct brw_reg src,
1052	       GLuint count);
1053
1054void brw_copy8(struct brw_compile *p,
1055	       struct brw_reg dst,
1056	       struct brw_reg src,
1057	       GLuint count);
1058
1059void brw_math_invert( struct brw_compile *p,
1060		      struct brw_reg dst,
1061		      struct brw_reg src);
1062
1063void brw_set_src1(struct brw_compile *p,
1064		  struct brw_instruction *insn,
1065		  struct brw_reg reg);
1066
1067void brw_set_uip_jip(struct brw_compile *p);
1068
1069uint32_t brw_swap_cmod(uint32_t cmod);
1070
1071/* brw_optimize.c */
1072void brw_optimize(struct brw_compile *p);
1073void brw_remove_duplicate_mrf_moves(struct brw_compile *p);
1074void brw_remove_grf_to_mrf_moves(struct brw_compile *p);
1075
1076#endif
1077