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