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