i965: Add support for AVG instruction.
[mesa.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 #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
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
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 */
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 */
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 */
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 */
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 */
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 */
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
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
318 sechalf(struct brw_reg reg)
319 {
320 if (reg.vstride)
321 reg.nr++;
322 return reg;
323 }
324
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
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
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 */
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 */
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 */
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
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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
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
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 */
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 */
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 */
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 */
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
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
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) */
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
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 */
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
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
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
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
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
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 */
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
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
625 static INLINE struct brw_reg vec16( struct brw_reg reg )
626 {
627 return stride(reg, 16,16,1);
628 }
629
630 static INLINE struct brw_reg vec8( struct brw_reg reg )
631 {
632 return stride(reg, 8,8,1);
633 }
634
635 static INLINE struct brw_reg vec4( struct brw_reg reg )
636 {
637 return stride(reg, 4,4,1);
638 }
639
640 static INLINE struct brw_reg vec2( struct brw_reg reg )
641 {
642 return stride(reg, 2,2,1);
643 }
644
645 static INLINE struct brw_reg vec1( struct brw_reg reg )
646 {
647 return stride(reg, 0,1,0);
648 }
649
650
651 static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
652 {
653 return vec1(suboffset(reg, elt));
654 }
655
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
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
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
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
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
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
705 static INLINE struct brw_reg negate( struct brw_reg reg )
706 {
707 reg.negate ^= 1;
708 return reg;
709 }
710
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 */
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
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
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
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
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
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
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
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
770 static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
771 {
772 return brw_address_reg(ptr.addr_subnr);
773 }
774
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
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
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
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, GLuint value );
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 saturate,
979 GLuint msg_reg_nr,
980 struct brw_reg src,
981 GLuint precision );
982
983 void brw_math( struct brw_compile *p,
984 struct brw_reg dest,
985 GLuint function,
986 GLuint saturate,
987 GLuint msg_reg_nr,
988 struct brw_reg src,
989 GLuint data_type,
990 GLuint precision );
991
992 void brw_math2(struct brw_compile *p,
993 struct brw_reg dest,
994 GLuint function,
995 struct brw_reg src0,
996 struct brw_reg src1);
997
998 void brw_oword_block_read(struct brw_compile *p,
999 struct brw_reg dest,
1000 struct brw_reg mrf,
1001 uint32_t offset,
1002 uint32_t bind_table_index);
1003
1004 void brw_oword_block_read_scratch(struct brw_compile *p,
1005 struct brw_reg dest,
1006 struct brw_reg mrf,
1007 int num_regs,
1008 GLuint offset);
1009
1010 void brw_oword_block_write_scratch(struct brw_compile *p,
1011 struct brw_reg mrf,
1012 int num_regs,
1013 GLuint offset);
1014
1015 void brw_dword_scattered_read(struct brw_compile *p,
1016 struct brw_reg dest,
1017 struct brw_reg mrf,
1018 uint32_t bind_table_index);
1019
1020 void brw_dp_READ_4_vs( struct brw_compile *p,
1021 struct brw_reg dest,
1022 GLuint location,
1023 GLuint bind_table_index );
1024
1025 void brw_dp_READ_4_vs_relative(struct brw_compile *p,
1026 struct brw_reg dest,
1027 struct brw_reg addrReg,
1028 GLuint offset,
1029 GLuint bind_table_index);
1030
1031 /* If/else/endif. Works by manipulating the execution flags on each
1032 * channel.
1033 */
1034 struct brw_instruction *brw_IF(struct brw_compile *p,
1035 GLuint execute_size);
1036 struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional,
1037 struct brw_reg src0, struct brw_reg src1);
1038
1039 void brw_ELSE(struct brw_compile *p);
1040 void brw_ENDIF(struct brw_compile *p);
1041
1042 /* DO/WHILE loops:
1043 */
1044 struct brw_instruction *brw_DO(struct brw_compile *p,
1045 GLuint execute_size);
1046
1047 struct brw_instruction *brw_WHILE(struct brw_compile *p);
1048
1049 struct brw_instruction *brw_BREAK(struct brw_compile *p);
1050 struct brw_instruction *brw_CONT(struct brw_compile *p);
1051 struct brw_instruction *gen6_CONT(struct brw_compile *p);
1052 /* Forward jumps:
1053 */
1054 void brw_land_fwd_jump(struct brw_compile *p, int jmp_insn_idx);
1055
1056
1057
1058 void brw_NOP(struct brw_compile *p);
1059
1060 void brw_WAIT(struct brw_compile *p);
1061
1062 /* Special case: there is never a destination, execution size will be
1063 * taken from src0:
1064 */
1065 void brw_CMP(struct brw_compile *p,
1066 struct brw_reg dest,
1067 GLuint conditional,
1068 struct brw_reg src0,
1069 struct brw_reg src1);
1070
1071 void brw_print_reg( struct brw_reg reg );
1072
1073
1074 /***********************************************************************
1075 * brw_eu_util.c:
1076 */
1077
1078 void brw_copy_indirect_to_indirect(struct brw_compile *p,
1079 struct brw_indirect dst_ptr,
1080 struct brw_indirect src_ptr,
1081 GLuint count);
1082
1083 void brw_copy_from_indirect(struct brw_compile *p,
1084 struct brw_reg dst,
1085 struct brw_indirect ptr,
1086 GLuint count);
1087
1088 void brw_copy4(struct brw_compile *p,
1089 struct brw_reg dst,
1090 struct brw_reg src,
1091 GLuint count);
1092
1093 void brw_copy8(struct brw_compile *p,
1094 struct brw_reg dst,
1095 struct brw_reg src,
1096 GLuint count);
1097
1098 void brw_math_invert( struct brw_compile *p,
1099 struct brw_reg dst,
1100 struct brw_reg src);
1101
1102 void brw_set_src1(struct brw_compile *p,
1103 struct brw_instruction *insn,
1104 struct brw_reg reg);
1105
1106 void brw_set_uip_jip(struct brw_compile *p);
1107
1108 uint32_t brw_swap_cmod(uint32_t cmod);
1109
1110 /* brw_optimize.c */
1111 void brw_optimize(struct brw_compile *p);
1112 void brw_remove_duplicate_mrf_moves(struct brw_compile *p);
1113 void brw_remove_grf_to_mrf_moves(struct brw_compile *p);
1114
1115 #ifdef __cplusplus
1116 }
1117 #endif
1118
1119 #endif