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