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