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