Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / 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 <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_XYXY      BRW_SWIZZLE4(0,1,0,1)
48
49
50 #define REG_SIZE (8*4)
51
52
53 /* These aren't hardware structs, just something useful for us to pass around:
54  *
55  * Align1 operation has a lot of control over input ranges.  Used in
56  * WM programs to implement shaders decomposed into "channel serial"
57  * or "structure of array" form:
58  */
59 struct brw_reg
60 {
61    GLuint type:4;
62    GLuint file:2;
63    GLuint nr:8;
64    GLuint subnr:5;              /* :1 in align16 */
65    GLuint negate:1;             /* source only */
66    GLuint abs:1;                /* source only */
67    GLuint vstride:4;            /* source only */
68    GLuint width:3;              /* src only, align1 only */
69    GLuint hstride:2;            /* align1 only */
70    GLuint address_mode:1;       /* relative addressing, hopefully! */
71    GLuint pad0:1;
72
73    union {      
74       struct {
75          GLuint swizzle:8;              /* src only, align16 only */
76          GLuint writemask:4;            /* dest only, align16 only */
77          GLint  indirect_offset:10;     /* relative addressing offset */
78          GLuint pad1:10;                /* two dwords total */
79       } bits;
80
81       GLfloat f;
82       GLint   d;
83       GLuint ud;
84    } dw1;      
85 };
86
87
88 struct brw_indirect {
89    GLuint addr_subnr:4;
90    GLint addr_offset:10;
91    GLuint pad:18;
92 };
93
94
95 struct brw_glsl_label;
96 struct brw_glsl_call;
97
98
99
100 #define BRW_EU_MAX_INSN_STACK 5
101 #define BRW_EU_MAX_INSN 10000
102
103 struct brw_compile {
104    struct brw_instruction store[BRW_EU_MAX_INSN];
105    GLuint nr_insn;
106
107    void *mem_ctx;
108
109    /* Allow clients to push/pop instruction state:
110     */
111    struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
112    bool compressed_stack[BRW_EU_MAX_INSN_STACK];
113    struct brw_instruction *current;
114
115    GLuint flag_value;
116    GLboolean single_program_flow;
117    bool compressed;
118    struct brw_context *brw;
119
120    /* Control flow stacks:
121     * - if_stack contains IF and ELSE instructions which must be patched
122     *   (and popped) once the matching ENDIF instruction is encountered.
123     */
124    struct brw_instruction **if_stack;
125    int if_stack_depth;
126    int if_stack_array_size;
127
128    struct brw_glsl_label *first_label;  /**< linked list of labels */
129    struct brw_glsl_call *first_call;    /**< linked list of CALs */
130 };
131
132
133 void
134 brw_save_label(struct brw_compile *c, const char *name, GLuint position);
135
136 void
137 brw_save_call(struct brw_compile *c, const char *name, GLuint call_pos);
138
139 void
140 brw_resolve_cals(struct brw_compile *c);
141
142
143
144 static INLINE int type_sz( GLuint type )
145 {
146    switch( type ) {
147    case BRW_REGISTER_TYPE_UD:
148    case BRW_REGISTER_TYPE_D:
149    case BRW_REGISTER_TYPE_F:
150       return 4;
151    case BRW_REGISTER_TYPE_HF:
152    case BRW_REGISTER_TYPE_UW:
153    case BRW_REGISTER_TYPE_W:
154       return 2;
155    case BRW_REGISTER_TYPE_UB:
156    case BRW_REGISTER_TYPE_B:
157       return 1;
158    default:
159       return 0;
160    }
161 }
162
163 /**
164  * Construct a brw_reg.
165  * \param file  one of the BRW_x_REGISTER_FILE values
166  * \param nr  register number/index
167  * \param subnr  register sub number
168  * \param type  one of BRW_REGISTER_TYPE_x
169  * \param vstride  one of BRW_VERTICAL_STRIDE_x
170  * \param width  one of BRW_WIDTH_x
171  * \param hstride  one of BRW_HORIZONTAL_STRIDE_x
172  * \param swizzle  one of BRW_SWIZZLE_x
173  * \param writemask  WRITEMASK_X/Y/Z/W bitfield
174  */
175 static INLINE struct brw_reg brw_reg( GLuint file,
176                                       GLuint nr,
177                                       GLuint subnr,
178                                       GLuint type,
179                                       GLuint vstride,
180                                       GLuint width,
181                                       GLuint hstride,
182                                       GLuint swizzle,
183                                       GLuint writemask )
184 {
185    struct brw_reg reg;
186    if (file == BRW_GENERAL_REGISTER_FILE)
187       assert(nr < BRW_MAX_GRF);
188    else if (file == BRW_MESSAGE_REGISTER_FILE)
189       assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
190    else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
191       assert(nr <= BRW_ARF_IP);
192
193    reg.type = type;
194    reg.file = file;
195    reg.nr = nr;
196    reg.subnr = subnr * type_sz(type);
197    reg.negate = 0;
198    reg.abs = 0;
199    reg.vstride = vstride;
200    reg.width = width;
201    reg.hstride = hstride;
202    reg.address_mode = BRW_ADDRESS_DIRECT;
203    reg.pad0 = 0;
204
205    /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
206     * set swizzle and writemask to W, as the lower bits of subnr will
207     * be lost when converted to align16.  This is probably too much to
208     * keep track of as you'd want it adjusted by suboffset(), etc.
209     * Perhaps fix up when converting to align16?
210     */
211    reg.dw1.bits.swizzle = swizzle;
212    reg.dw1.bits.writemask = writemask;
213    reg.dw1.bits.indirect_offset = 0;
214    reg.dw1.bits.pad1 = 0;
215    return reg;
216 }
217
218 /** Construct float[16] register */
219 static INLINE struct brw_reg brw_vec16_reg( GLuint file,
220                                               GLuint nr,
221                                               GLuint subnr )
222 {
223    return brw_reg(file,
224                   nr,
225                   subnr,
226                   BRW_REGISTER_TYPE_F,
227                   BRW_VERTICAL_STRIDE_16,
228                   BRW_WIDTH_16,
229                   BRW_HORIZONTAL_STRIDE_1,
230                   BRW_SWIZZLE_XYZW,
231                   WRITEMASK_XYZW);
232 }
233
234 /** Construct float[8] register */
235 static INLINE struct brw_reg brw_vec8_reg( GLuint file,
236                                              GLuint nr,
237                                              GLuint subnr )
238 {
239    return brw_reg(file,
240                   nr,
241                   subnr,
242                   BRW_REGISTER_TYPE_F,
243                   BRW_VERTICAL_STRIDE_8,
244                   BRW_WIDTH_8,
245                   BRW_HORIZONTAL_STRIDE_1,
246                   BRW_SWIZZLE_XYZW,
247                   WRITEMASK_XYZW);
248 }
249
250 /** Construct float[4] register */
251 static INLINE struct brw_reg brw_vec4_reg( GLuint file,
252                                               GLuint nr,
253                                               GLuint subnr )
254 {
255    return brw_reg(file,
256                   nr,
257                   subnr,
258                   BRW_REGISTER_TYPE_F,
259                   BRW_VERTICAL_STRIDE_4,
260                   BRW_WIDTH_4,
261                   BRW_HORIZONTAL_STRIDE_1,
262                   BRW_SWIZZLE_XYZW,
263                   WRITEMASK_XYZW);
264 }
265
266 /** Construct float[2] register */
267 static INLINE struct brw_reg brw_vec2_reg( GLuint file,
268                                               GLuint nr,
269                                               GLuint subnr )
270 {
271    return brw_reg(file,
272                   nr,
273                   subnr,
274                   BRW_REGISTER_TYPE_F,
275                   BRW_VERTICAL_STRIDE_2,
276                   BRW_WIDTH_2,
277                   BRW_HORIZONTAL_STRIDE_1,
278                   BRW_SWIZZLE_XYXY,
279                   WRITEMASK_XY);
280 }
281
282 /** Construct float[1] register */
283 static INLINE struct brw_reg brw_vec1_reg( GLuint file,
284                                              GLuint nr,
285                                              GLuint subnr )
286 {
287    return brw_reg(file,
288                   nr,
289                   subnr,
290                   BRW_REGISTER_TYPE_F,
291                   BRW_VERTICAL_STRIDE_0,
292                   BRW_WIDTH_1,
293                   BRW_HORIZONTAL_STRIDE_0,
294                   BRW_SWIZZLE_XXXX,
295                   WRITEMASK_X);
296 }
297
298
299 static INLINE struct brw_reg retype( struct brw_reg reg,
300                                        GLuint type )
301 {
302    reg.type = type;
303    return reg;
304 }
305
306 static inline struct brw_reg
307 sechalf(struct brw_reg reg)
308 {
309    if (reg.vstride)
310       reg.nr++;
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                   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 static INLINE struct brw_reg brw_notification_1_reg(void)
545 {
546
547    return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
548                   BRW_ARF_NOTIFICATION_COUNT,
549                   1,
550                   BRW_REGISTER_TYPE_UD,
551                   BRW_VERTICAL_STRIDE_0,
552                   BRW_WIDTH_1,
553                   BRW_HORIZONTAL_STRIDE_0,
554                   BRW_SWIZZLE_XXXX,
555                   WRITEMASK_X);
556 }
557
558
559 static INLINE struct brw_reg brw_flag_reg( void )
560 {
561    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
562                       BRW_ARF_FLAG,
563                       0);
564 }
565
566
567 static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
568 {
569    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
570                       BRW_ARF_MASK,
571                       subnr);
572 }
573
574 static INLINE struct brw_reg brw_message_reg( GLuint nr )
575 {
576    assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
577    return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
578                        nr,
579                        0);
580 }
581
582
583
584
585 /* This is almost always called with a numeric constant argument, so
586  * make things easy to evaluate at compile time:
587  */
588 static INLINE GLuint cvt( GLuint val )
589 {
590    switch (val) {
591    case 0: return 0;
592    case 1: return 1;
593    case 2: return 2;
594    case 4: return 3;
595    case 8: return 4;
596    case 16: return 5;
597    case 32: return 6;
598    }
599    return 0;
600 }
601
602 static INLINE struct brw_reg stride( struct brw_reg reg,
603                                        GLuint vstride,
604                                        GLuint width,
605                                        GLuint hstride )
606 {
607    reg.vstride = cvt(vstride);
608    reg.width = cvt(width) - 1;
609    reg.hstride = cvt(hstride);
610    return reg;
611 }
612
613
614 static INLINE struct brw_reg vec16( struct brw_reg reg )
615 {
616    return stride(reg, 16,16,1);
617 }
618
619 static INLINE struct brw_reg vec8( struct brw_reg reg )
620 {
621    return stride(reg, 8,8,1);
622 }
623
624 static INLINE struct brw_reg vec4( struct brw_reg reg )
625 {
626    return stride(reg, 4,4,1);
627 }
628
629 static INLINE struct brw_reg vec2( struct brw_reg reg )
630 {
631    return stride(reg, 2,2,1);
632 }
633
634 static INLINE struct brw_reg vec1( struct brw_reg reg )
635 {
636    return stride(reg, 0,1,0);
637 }
638
639
640 static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
641 {
642    return vec1(suboffset(reg, elt));
643 }
644
645 static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
646 {
647    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
648 }
649
650
651 static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
652                                             GLuint x,
653                                             GLuint y, 
654                                             GLuint z,
655                                             GLuint w)
656 {
657    assert(reg.file != BRW_IMMEDIATE_VALUE);
658
659    reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
660                                        BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
661                                        BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
662                                        BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
663    return reg;
664 }
665
666
667 static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
668                                              GLuint x )
669 {
670    return brw_swizzle(reg, x, x, x, x);
671 }
672
673 static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
674                                               GLuint mask )
675 {
676    assert(reg.file != BRW_IMMEDIATE_VALUE);
677    reg.dw1.bits.writemask &= mask;
678    return reg;
679 }
680
681 static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
682                                                   GLuint mask )
683 {
684    assert(reg.file != BRW_IMMEDIATE_VALUE);
685    reg.dw1.bits.writemask = mask;
686    return reg;
687 }
688
689 static INLINE struct brw_reg negate( struct brw_reg reg )
690 {
691    reg.negate ^= 1;
692    return reg;
693 }
694
695 static INLINE struct brw_reg brw_abs( struct brw_reg reg )
696 {
697    reg.abs = 1;
698    return reg;
699 }
700
701 /***********************************************************************
702  */
703 static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
704                                                   GLint offset )
705 {
706    struct brw_reg reg =  brw_vec4_grf(0, 0);
707    reg.subnr = subnr;
708    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
709    reg.dw1.bits.indirect_offset = offset;
710    return reg;
711 }
712
713 static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
714                                                   GLint offset )
715 {
716    struct brw_reg reg =  brw_vec1_grf(0, 0);
717    reg.subnr = subnr;
718    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
719    reg.dw1.bits.indirect_offset = offset;
720    return reg;
721 }
722
723 static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
724 {
725    return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
726 }
727
728 static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
729 {
730    return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
731 }
732
733 static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
734 {
735    return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
736 }
737
738 static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
739 {
740    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
741 }
742
743 static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
744 {
745    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
746 }
747
748 static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
749 {
750    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
751 }
752
753 static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
754 {
755    return brw_address_reg(ptr.addr_subnr);
756 }
757
758 static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
759 {
760    ptr.addr_offset += offset;
761    return ptr;
762 }
763
764 static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
765 {
766    struct brw_indirect ptr;
767    ptr.addr_subnr = addr_subnr;
768    ptr.addr_offset = offset;
769    ptr.pad = 0;
770    return ptr;
771 }
772
773 /** Do two brw_regs refer to the same register? */
774 static INLINE GLboolean
775 brw_same_reg(struct brw_reg r1, struct brw_reg r2)
776 {
777    return r1.file == r2.file && r1.nr == r2.nr;
778 }
779
780 static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
781 {
782    return &p->store[p->nr_insn];
783 }
784
785 void brw_pop_insn_state( struct brw_compile *p );
786 void brw_push_insn_state( struct brw_compile *p );
787 void brw_set_mask_control( struct brw_compile *p, GLuint value );
788 void brw_set_saturate( struct brw_compile *p, GLuint value );
789 void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
790 void brw_set_compression_control( struct brw_compile *p, GLboolean control );
791 void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
792 void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
793 void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse);
794 void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
795 void brw_set_acc_write_control(struct brw_compile *p, GLuint value);
796
797 void brw_init_compile(struct brw_context *, struct brw_compile *p,
798                       void *mem_ctx);
799 const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
800
801
802 /* Helpers for regular instructions:
803  */
804 #define ALU1(OP)                                        \
805 struct brw_instruction *brw_##OP(struct brw_compile *p, \
806               struct brw_reg dest,                      \
807               struct brw_reg src0);
808
809 #define ALU2(OP)                                        \
810 struct brw_instruction *brw_##OP(struct brw_compile *p, \
811               struct brw_reg dest,                      \
812               struct brw_reg src0,                      \
813               struct brw_reg src1);
814
815 #define ROUND(OP) \
816 void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0);
817
818
819 ALU1(MOV)
820 ALU2(SEL)
821 ALU1(NOT)
822 ALU2(AND)
823 ALU2(OR)
824 ALU2(XOR)
825 ALU2(SHR)
826 ALU2(SHL)
827 ALU2(RSR)
828 ALU2(RSL)
829 ALU2(ASR)
830 ALU2(JMPI)
831 ALU2(ADD)
832 ALU2(MUL)
833 ALU1(FRC)
834 ALU1(RNDD)
835 ALU2(MAC)
836 ALU2(MACH)
837 ALU1(LZD)
838 ALU2(DP4)
839 ALU2(DPH)
840 ALU2(DP3)
841 ALU2(DP2)
842 ALU2(LINE)
843 ALU2(PLN)
844
845 ROUND(RNDZ)
846 ROUND(RNDE)
847
848 #undef ALU1
849 #undef ALU2
850 #undef ROUND
851
852
853 /* Helpers for SEND instruction:
854  */
855 void brw_urb_WRITE(struct brw_compile *p,
856                    struct brw_reg dest,
857                    GLuint msg_reg_nr,
858                    struct brw_reg src0,
859                    GLboolean allocate,
860                    GLboolean used,
861                    GLuint msg_length,
862                    GLuint response_length,
863                    GLboolean eot,
864                    GLboolean writes_complete,
865                    GLuint offset,
866                    GLuint swizzle);
867
868 void brw_ff_sync(struct brw_compile *p,
869                    struct brw_reg dest,
870                    GLuint msg_reg_nr,
871                    struct brw_reg src0,
872                    GLboolean allocate,
873                    GLuint response_length,
874                    GLboolean eot);
875
876 void brw_fb_WRITE(struct brw_compile *p,
877                   int dispatch_width,
878                    GLuint msg_reg_nr,
879                    struct brw_reg src0,
880                    GLuint binding_table_index,
881                    GLuint msg_length,
882                    GLuint response_length,
883                    GLboolean eot,
884                    GLboolean header_present);
885
886 void brw_SAMPLE(struct brw_compile *p,
887                 struct brw_reg dest,
888                 GLuint msg_reg_nr,
889                 struct brw_reg src0,
890                 GLuint binding_table_index,
891                 GLuint sampler,
892                 GLuint writemask,
893                 GLuint msg_type,
894                 GLuint response_length,
895                 GLuint msg_length,
896                 GLboolean eot,
897                 GLuint header_present,
898                 GLuint simd_mode);
899
900 void brw_math_16( struct brw_compile *p,
901                   struct brw_reg dest,
902                   GLuint function,
903                   GLuint saturate,
904                   GLuint msg_reg_nr,
905                   struct brw_reg src,
906                   GLuint precision );
907
908 void brw_math( struct brw_compile *p,
909                struct brw_reg dest,
910                GLuint function,
911                GLuint saturate,
912                GLuint msg_reg_nr,
913                struct brw_reg src,
914                GLuint data_type,
915                GLuint precision );
916
917 void brw_math2(struct brw_compile *p,
918                struct brw_reg dest,
919                GLuint function,
920                struct brw_reg src0,
921                struct brw_reg src1);
922
923 void brw_oword_block_read(struct brw_compile *p,
924                           struct brw_reg dest,
925                           struct brw_reg mrf,
926                           uint32_t offset,
927                           uint32_t bind_table_index);
928
929 void brw_oword_block_read_scratch(struct brw_compile *p,
930                                   struct brw_reg dest,
931                                   struct brw_reg mrf,
932                                   int num_regs,
933                                   GLuint offset);
934
935 void brw_oword_block_write_scratch(struct brw_compile *p,
936                                    struct brw_reg mrf,
937                                    int num_regs,
938                                    GLuint offset);
939
940 void brw_dword_scattered_read(struct brw_compile *p,
941                               struct brw_reg dest,
942                               struct brw_reg mrf,
943                               uint32_t bind_table_index);
944
945 void brw_dp_READ_4_vs( struct brw_compile *p,
946                        struct brw_reg dest,
947                        GLuint location,
948                        GLuint bind_table_index );
949
950 void brw_dp_READ_4_vs_relative(struct brw_compile *p,
951                                struct brw_reg dest,
952                                struct brw_reg addrReg,
953                                GLuint offset,
954                                GLuint bind_table_index);
955
956 /* If/else/endif.  Works by manipulating the execution flags on each
957  * channel.
958  */
959 struct brw_instruction *brw_IF(struct brw_compile *p, 
960                                GLuint execute_size);
961 struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional,
962                                 struct brw_reg src0, struct brw_reg src1);
963
964 void brw_ELSE(struct brw_compile *p);
965 void brw_ENDIF(struct brw_compile *p);
966
967 /* DO/WHILE loops:
968  */
969 struct brw_instruction *brw_DO(struct brw_compile *p,
970                                GLuint execute_size);
971
972 struct brw_instruction *brw_WHILE(struct brw_compile *p, 
973                struct brw_instruction *patch_insn);
974
975 struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count);
976 struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count);
977 struct brw_instruction *gen6_CONT(struct brw_compile *p,
978                                   struct brw_instruction *do_insn);
979 /* Forward jumps:
980  */
981 void brw_land_fwd_jump(struct brw_compile *p, 
982                        struct brw_instruction *jmp_insn);
983
984
985
986 void brw_NOP(struct brw_compile *p);
987
988 void brw_WAIT(struct brw_compile *p);
989
990 /* Special case: there is never a destination, execution size will be
991  * taken from src0:
992  */
993 void brw_CMP(struct brw_compile *p,
994              struct brw_reg dest,
995              GLuint conditional,
996              struct brw_reg src0,
997              struct brw_reg src1);
998
999 void brw_print_reg( struct brw_reg reg );
1000
1001
1002 /*********************************************************************** 
1003  * brw_eu_util.c:
1004  */
1005
1006 void brw_copy_indirect_to_indirect(struct brw_compile *p,
1007                                    struct brw_indirect dst_ptr,
1008                                    struct brw_indirect src_ptr,
1009                                    GLuint count);
1010
1011 void brw_copy_from_indirect(struct brw_compile *p,
1012                             struct brw_reg dst,
1013                             struct brw_indirect ptr,
1014                             GLuint count);
1015
1016 void brw_copy4(struct brw_compile *p,
1017                struct brw_reg dst,
1018                struct brw_reg src,
1019                GLuint count);
1020
1021 void brw_copy8(struct brw_compile *p,
1022                struct brw_reg dst,
1023                struct brw_reg src,
1024                GLuint count);
1025
1026 void brw_math_invert( struct brw_compile *p, 
1027                       struct brw_reg dst,
1028                       struct brw_reg src);
1029
1030 void brw_set_src1(struct brw_compile *p,
1031                   struct brw_instruction *insn,
1032                   struct brw_reg reg);
1033
1034 void brw_set_uip_jip(struct brw_compile *p);
1035
1036 uint32_t brw_swap_cmod(uint32_t cmod);
1037
1038 /* brw_optimize.c */
1039 void brw_optimize(struct brw_compile *p);
1040 void brw_remove_duplicate_mrf_moves(struct brw_compile *p);
1041 void brw_remove_grf_to_mrf_moves(struct brw_compile *p);
1042
1043 #endif