brw_eu.h revision 21eaa62ba461854003e5f74e6fc32e559e9c8455
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 "program/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 (file == BRW_GENERAL_REGISTER_FILE)
174      assert(nr < BRW_MAX_GRF);
175   else if (file == BRW_MESSAGE_REGISTER_FILE)
176      assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
177   else if (file == 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
523static INLINE struct brw_reg brw_notification_1_reg(void)
524{
525
526   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
527		  BRW_ARF_NOTIFICATION_COUNT,
528		  1,
529		  BRW_REGISTER_TYPE_UD,
530		  BRW_VERTICAL_STRIDE_0,
531		  BRW_WIDTH_1,
532		  BRW_HORIZONTAL_STRIDE_0,
533		  BRW_SWIZZLE_XXXX,
534		  WRITEMASK_X);
535}
536
537
538static INLINE struct brw_reg brw_flag_reg( void )
539{
540   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
541		      BRW_ARF_FLAG,
542		      0);
543}
544
545
546static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
547{
548   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
549		      BRW_ARF_MASK,
550		      subnr);
551}
552
553static INLINE struct brw_reg brw_message_reg( GLuint nr )
554{
555   assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
556   return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
557		       nr,
558		       0);
559}
560
561
562
563
564/* This is almost always called with a numeric constant argument, so
565 * make things easy to evaluate at compile time:
566 */
567static INLINE GLuint cvt( GLuint val )
568{
569   switch (val) {
570   case 0: return 0;
571   case 1: return 1;
572   case 2: return 2;
573   case 4: return 3;
574   case 8: return 4;
575   case 16: return 5;
576   case 32: return 6;
577   }
578   return 0;
579}
580
581static INLINE struct brw_reg stride( struct brw_reg reg,
582				       GLuint vstride,
583				       GLuint width,
584				       GLuint hstride )
585{
586   reg.vstride = cvt(vstride);
587   reg.width = cvt(width) - 1;
588   reg.hstride = cvt(hstride);
589   return reg;
590}
591
592
593static INLINE struct brw_reg vec16( struct brw_reg reg )
594{
595   return stride(reg, 16,16,1);
596}
597
598static INLINE struct brw_reg vec8( struct brw_reg reg )
599{
600   return stride(reg, 8,8,1);
601}
602
603static INLINE struct brw_reg vec4( struct brw_reg reg )
604{
605   return stride(reg, 4,4,1);
606}
607
608static INLINE struct brw_reg vec2( struct brw_reg reg )
609{
610   return stride(reg, 2,2,1);
611}
612
613static INLINE struct brw_reg vec1( struct brw_reg reg )
614{
615   return stride(reg, 0,1,0);
616}
617
618
619static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
620{
621   return vec1(suboffset(reg, elt));
622}
623
624static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
625{
626   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
627}
628
629
630static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
631					    GLuint x,
632					    GLuint y,
633					    GLuint z,
634					    GLuint w)
635{
636   reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
637				       BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
638				       BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
639				       BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
640   return reg;
641}
642
643
644static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
645					     GLuint x )
646{
647   return brw_swizzle(reg, x, x, x, x);
648}
649
650static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
651					      GLuint mask )
652{
653   reg.dw1.bits.writemask &= mask;
654   return reg;
655}
656
657static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
658						  GLuint mask )
659{
660   reg.dw1.bits.writemask = mask;
661   return reg;
662}
663
664static INLINE struct brw_reg negate( struct brw_reg reg )
665{
666   reg.negate ^= 1;
667   return reg;
668}
669
670static INLINE struct brw_reg brw_abs( struct brw_reg reg )
671{
672   reg.abs = 1;
673   return reg;
674}
675
676/***********************************************************************
677 */
678static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
679						  GLint offset )
680{
681   struct brw_reg reg =  brw_vec4_grf(0, 0);
682   reg.subnr = subnr;
683   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
684   reg.dw1.bits.indirect_offset = offset;
685   return reg;
686}
687
688static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
689						  GLint offset )
690{
691   struct brw_reg reg =  brw_vec1_grf(0, 0);
692   reg.subnr = subnr;
693   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
694   reg.dw1.bits.indirect_offset = offset;
695   return reg;
696}
697
698static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
699{
700   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
701}
702
703static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
704{
705   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
706}
707
708static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
709{
710   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
711}
712
713static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
714{
715   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
716}
717
718static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
719{
720   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
721}
722
723static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
724{
725   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
726}
727
728static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
729{
730   return brw_address_reg(ptr.addr_subnr);
731}
732
733static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
734{
735   ptr.addr_offset += offset;
736   return ptr;
737}
738
739static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
740{
741   struct brw_indirect ptr;
742   ptr.addr_subnr = addr_subnr;
743   ptr.addr_offset = offset;
744   ptr.pad = 0;
745   return ptr;
746}
747
748/** Do two brw_regs refer to the same register? */
749static INLINE GLboolean
750brw_same_reg(struct brw_reg r1, struct brw_reg r2)
751{
752   return r1.file == r2.file && r1.nr == r2.nr;
753}
754
755static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
756{
757   return &p->store[p->nr_insn];
758}
759
760void brw_pop_insn_state( struct brw_compile *p );
761void brw_push_insn_state( struct brw_compile *p );
762void brw_set_mask_control( struct brw_compile *p, GLuint value );
763void brw_set_saturate( struct brw_compile *p, GLuint value );
764void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
765void brw_set_compression_control( struct brw_compile *p, GLboolean control );
766void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
767void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
768void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
769
770void brw_init_compile( struct brw_context *, struct brw_compile *p );
771const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
772
773
774/* Helpers for regular instructions:
775 */
776#define ALU1(OP)					\
777struct brw_instruction *brw_##OP(struct brw_compile *p,	\
778	      struct brw_reg dest,			\
779	      struct brw_reg src0);
780
781#define ALU2(OP)					\
782struct brw_instruction *brw_##OP(struct brw_compile *p,	\
783	      struct brw_reg dest,			\
784	      struct brw_reg src0,			\
785	      struct brw_reg src1);
786
787ALU1(MOV)
788ALU2(SEL)
789ALU1(NOT)
790ALU2(AND)
791ALU2(OR)
792ALU2(XOR)
793ALU2(SHR)
794ALU2(SHL)
795ALU2(RSR)
796ALU2(RSL)
797ALU2(ASR)
798ALU2(JMPI)
799ALU2(ADD)
800ALU2(MUL)
801ALU1(FRC)
802ALU1(RNDD)
803ALU1(RNDZ)
804ALU2(MAC)
805ALU2(MACH)
806ALU1(LZD)
807ALU2(DP4)
808ALU2(DPH)
809ALU2(DP3)
810ALU2(DP2)
811ALU2(LINE)
812ALU2(PLN)
813
814#undef ALU1
815#undef ALU2
816
817
818
819/* Helpers for SEND instruction:
820 */
821void brw_urb_WRITE(struct brw_compile *p,
822		   struct brw_reg dest,
823		   GLuint msg_reg_nr,
824		   struct brw_reg src0,
825		   GLboolean allocate,
826		   GLboolean used,
827		   GLuint msg_length,
828		   GLuint response_length,
829		   GLboolean eot,
830		   GLboolean writes_complete,
831		   GLuint offset,
832		   GLuint swizzle);
833
834void brw_ff_sync(struct brw_compile *p,
835		   struct brw_reg dest,
836		   GLuint msg_reg_nr,
837		   struct brw_reg src0,
838		   GLboolean allocate,
839		   GLuint response_length,
840		   GLboolean eot);
841
842void brw_fb_WRITE(struct brw_compile *p,
843		   struct brw_reg dest,
844		   GLuint msg_reg_nr,
845		   struct brw_reg src0,
846		   GLuint binding_table_index,
847		   GLuint msg_length,
848		   GLuint response_length,
849		   GLboolean eot);
850
851void brw_SAMPLE(struct brw_compile *p,
852		struct brw_reg dest,
853		GLuint msg_reg_nr,
854		struct brw_reg src0,
855		GLuint binding_table_index,
856		GLuint sampler,
857		GLuint writemask,
858		GLuint msg_type,
859		GLuint response_length,
860		GLuint msg_length,
861		GLboolean eot,
862		GLuint header_present,
863		GLuint simd_mode);
864
865void brw_math_16( struct brw_compile *p,
866		  struct brw_reg dest,
867		  GLuint function,
868		  GLuint saturate,
869		  GLuint msg_reg_nr,
870		  struct brw_reg src,
871		  GLuint precision );
872
873void brw_math( struct brw_compile *p,
874	       struct brw_reg dest,
875	       GLuint function,
876	       GLuint saturate,
877	       GLuint msg_reg_nr,
878	       struct brw_reg src,
879	       GLuint data_type,
880	       GLuint precision );
881
882void brw_dp_READ_16( struct brw_compile *p,
883		     struct brw_reg dest,
884		     GLuint scratch_offset );
885
886void brw_dp_READ_4( struct brw_compile *p,
887                    struct brw_reg dest,
888                    GLboolean relAddr,
889                    GLuint location,
890                    GLuint bind_table_index );
891
892void brw_dp_READ_4_vs( struct brw_compile *p,
893                       struct brw_reg dest,
894                       GLuint location,
895                       GLuint bind_table_index );
896
897void brw_dp_READ_4_vs_relative(struct brw_compile *p,
898			       struct brw_reg dest,
899			       struct brw_reg addrReg,
900			       GLuint offset,
901			       GLuint bind_table_index);
902
903void brw_dp_WRITE_16( struct brw_compile *p,
904		      struct brw_reg src,
905		      GLuint scratch_offset );
906
907/* If/else/endif.  Works by manipulating the execution flags on each
908 * channel.
909 */
910struct brw_instruction *brw_IF(struct brw_compile *p,
911			       GLuint execute_size);
912
913struct brw_instruction *brw_ELSE(struct brw_compile *p,
914				 struct brw_instruction *if_insn);
915
916void brw_ENDIF(struct brw_compile *p,
917	       struct brw_instruction *if_or_else_insn);
918
919
920/* DO/WHILE loops:
921 */
922struct brw_instruction *brw_DO(struct brw_compile *p,
923			       GLuint execute_size);
924
925struct brw_instruction *brw_WHILE(struct brw_compile *p,
926	       struct brw_instruction *patch_insn);
927
928struct brw_instruction *brw_BREAK(struct brw_compile *p);
929struct brw_instruction *brw_CONT(struct brw_compile *p);
930/* Forward jumps:
931 */
932void brw_land_fwd_jump(struct brw_compile *p,
933		       struct brw_instruction *jmp_insn);
934
935
936
937void brw_NOP(struct brw_compile *p);
938
939void brw_WAIT(struct brw_compile *p);
940
941/* Special case: there is never a destination, execution size will be
942 * taken from src0:
943 */
944void brw_CMP(struct brw_compile *p,
945	     struct brw_reg dest,
946	     GLuint conditional,
947	     struct brw_reg src0,
948	     struct brw_reg src1);
949
950void brw_print_reg( struct brw_reg reg );
951
952
953/***********************************************************************
954 * brw_eu_util.c:
955 */
956
957void brw_copy_indirect_to_indirect(struct brw_compile *p,
958				   struct brw_indirect dst_ptr,
959				   struct brw_indirect src_ptr,
960				   GLuint count);
961
962void brw_copy_from_indirect(struct brw_compile *p,
963			    struct brw_reg dst,
964			    struct brw_indirect ptr,
965			    GLuint count);
966
967void brw_copy4(struct brw_compile *p,
968	       struct brw_reg dst,
969	       struct brw_reg src,
970	       GLuint count);
971
972void brw_copy8(struct brw_compile *p,
973	       struct brw_reg dst,
974	       struct brw_reg src,
975	       GLuint count);
976
977void brw_math_invert( struct brw_compile *p,
978		      struct brw_reg dst,
979		      struct brw_reg src);
980
981void brw_set_src1( struct brw_instruction *insn,
982                          struct brw_reg reg );
983
984
985/* brw_optimize.c */
986void brw_optimize(struct brw_compile *p);
987
988#endif
989