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