Merge commit 'origin/gallium-0.1'
[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 "brw_structs.h"
37 #include "brw_defines.h"
38 #include "shader/prog_instruction.h"
39
40 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
41 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
42
43 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
44 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
45 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
46 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
47
48
49 #define REG_SIZE (8*4)
50
51
52 /* These aren't hardware structs, just something useful for us to pass around:
53 *
54 * Align1 operation has a lot of control over input ranges. Used in
55 * WM programs to implement shaders decomposed into "channel serial"
56 * or "structure of array" form:
57 */
58 struct brw_reg
59 {
60 GLuint type:4;
61 GLuint file:2;
62 GLuint nr:8;
63 GLuint subnr:5; /* :1 in align16 */
64 GLuint negate:1; /* source only */
65 GLuint abs:1; /* source only */
66 GLuint vstride:4; /* source only */
67 GLuint width:3; /* src only, align1 only */
68 GLuint hstride:2; /* align1 only */
69 GLuint address_mode:1; /* relative addressing, hopefully! */
70 GLuint pad0:1;
71
72 union {
73 struct {
74 GLuint swizzle:8; /* src only, align16 only */
75 GLuint writemask:4; /* dest only, align16 only */
76 GLint indirect_offset:10; /* relative addressing offset */
77 GLuint pad1:10; /* two dwords total */
78 } bits;
79
80 GLfloat f;
81 GLint d;
82 GLuint ud;
83 } dw1;
84 };
85
86
87 struct brw_indirect {
88 GLuint addr_subnr:4;
89 GLint addr_offset:10;
90 GLuint pad:18;
91 };
92
93
94 struct brw_glsl_label;
95 struct brw_glsl_call;
96
97
98
99 #define BRW_EU_MAX_INSN_STACK 5
100 #define BRW_EU_MAX_INSN 1200
101
102 struct brw_compile {
103 struct brw_instruction store[BRW_EU_MAX_INSN];
104 GLuint nr_insn;
105
106 /* Allow clients to push/pop instruction state:
107 */
108 struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
109 struct brw_instruction *current;
110
111 GLuint flag_value;
112 GLboolean single_program_flow;
113 struct brw_context *brw;
114
115 struct brw_glsl_label *first_label; /**< linked list of labels */
116 struct brw_glsl_call *first_call; /**< linked list of CALs */
117 };
118
119
120 void
121 brw_save_label(struct brw_compile *c, const char *name, GLuint position);
122
123 void
124 brw_save_call(struct brw_compile *c, const char *name, GLuint call_pos);
125
126 void
127 brw_resolve_cals(struct brw_compile *c);
128
129
130
131 static INLINE int type_sz( GLuint type )
132 {
133 switch( type ) {
134 case BRW_REGISTER_TYPE_UD:
135 case BRW_REGISTER_TYPE_D:
136 case BRW_REGISTER_TYPE_F:
137 return 4;
138 case BRW_REGISTER_TYPE_HF:
139 case BRW_REGISTER_TYPE_UW:
140 case BRW_REGISTER_TYPE_W:
141 return 2;
142 case BRW_REGISTER_TYPE_UB:
143 case BRW_REGISTER_TYPE_B:
144 return 1;
145 default:
146 return 0;
147 }
148 }
149
150 /**
151 * Construct a brw_reg.
152 * \param file one of the BRW_x_REGISTER_FILE values
153 * \param nr register number/index
154 * \param subnr register sub number
155 * \param type one of BRW_REGISTER_TYPE_x
156 * \param vstride one of BRW_VERTICAL_STRIDE_x
157 * \param width one of BRW_WIDTH_x
158 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
159 * \param swizzle one of BRW_SWIZZLE_x
160 * \param writemask WRITEMASK_X/Y/Z/W bitfield
161 */
162 static INLINE struct brw_reg brw_reg( GLuint file,
163 GLuint nr,
164 GLuint subnr,
165 GLuint type,
166 GLuint vstride,
167 GLuint width,
168 GLuint hstride,
169 GLuint swizzle,
170 GLuint writemask )
171 {
172 struct brw_reg reg;
173 reg.type = type;
174 reg.file = file;
175 reg.nr = nr;
176 reg.subnr = subnr * type_sz(type);
177 reg.negate = 0;
178 reg.abs = 0;
179 reg.vstride = vstride;
180 reg.width = width;
181 reg.hstride = hstride;
182 reg.address_mode = BRW_ADDRESS_DIRECT;
183 reg.pad0 = 0;
184
185 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
186 * set swizzle and writemask to W, as the lower bits of subnr will
187 * be lost when converted to align16. This is probably too much to
188 * keep track of as you'd want it adjusted by suboffset(), etc.
189 * Perhaps fix up when converting to align16?
190 */
191 reg.dw1.bits.swizzle = swizzle;
192 reg.dw1.bits.writemask = writemask;
193 reg.dw1.bits.indirect_offset = 0;
194 reg.dw1.bits.pad1 = 0;
195 return reg;
196 }
197
198 /** Construct float[16] register */
199 static INLINE struct brw_reg brw_vec16_reg( GLuint file,
200 GLuint nr,
201 GLuint subnr )
202 {
203 return brw_reg(file,
204 nr,
205 subnr,
206 BRW_REGISTER_TYPE_F,
207 BRW_VERTICAL_STRIDE_16,
208 BRW_WIDTH_16,
209 BRW_HORIZONTAL_STRIDE_1,
210 BRW_SWIZZLE_XYZW,
211 WRITEMASK_XYZW);
212 }
213
214 /** Construct float[8] register */
215 static INLINE struct brw_reg brw_vec8_reg( GLuint file,
216 GLuint nr,
217 GLuint subnr )
218 {
219 return brw_reg(file,
220 nr,
221 subnr,
222 BRW_REGISTER_TYPE_F,
223 BRW_VERTICAL_STRIDE_8,
224 BRW_WIDTH_8,
225 BRW_HORIZONTAL_STRIDE_1,
226 BRW_SWIZZLE_XYZW,
227 WRITEMASK_XYZW);
228 }
229
230 /** Construct float[4] register */
231 static INLINE struct brw_reg brw_vec4_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_4,
240 BRW_WIDTH_4,
241 BRW_HORIZONTAL_STRIDE_1,
242 BRW_SWIZZLE_XYZW,
243 WRITEMASK_XYZW);
244 }
245
246 /** Construct float[2] register */
247 static INLINE struct brw_reg brw_vec2_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_2,
256 BRW_WIDTH_2,
257 BRW_HORIZONTAL_STRIDE_1,
258 BRW_SWIZZLE_XYXY,
259 WRITEMASK_XY);
260 }
261
262 /** Construct float[1] register */
263 static INLINE struct brw_reg brw_vec1_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_0,
272 BRW_WIDTH_1,
273 BRW_HORIZONTAL_STRIDE_0,
274 BRW_SWIZZLE_XXXX,
275 WRITEMASK_X);
276 }
277
278
279 static INLINE struct brw_reg retype( struct brw_reg reg,
280 GLuint type )
281 {
282 reg.type = type;
283 return reg;
284 }
285
286 static INLINE struct brw_reg suboffset( struct brw_reg reg,
287 GLuint delta )
288 {
289 reg.subnr += delta * type_sz(reg.type);
290 return reg;
291 }
292
293
294 static INLINE struct brw_reg offset( struct brw_reg reg,
295 GLuint delta )
296 {
297 reg.nr += delta;
298 return reg;
299 }
300
301
302 static INLINE struct brw_reg byte_offset( struct brw_reg reg,
303 GLuint bytes )
304 {
305 GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
306 reg.nr = newoffset / REG_SIZE;
307 reg.subnr = newoffset % REG_SIZE;
308 return reg;
309 }
310
311
312 /** Construct unsigned word[16] register */
313 static INLINE struct brw_reg brw_uw16_reg( GLuint file,
314 GLuint nr,
315 GLuint subnr )
316 {
317 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
318 }
319
320 /** Construct unsigned word[8] register */
321 static INLINE struct brw_reg brw_uw8_reg( GLuint file,
322 GLuint nr,
323 GLuint subnr )
324 {
325 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
326 }
327
328 /** Construct unsigned word[1] register */
329 static INLINE struct brw_reg brw_uw1_reg( GLuint file,
330 GLuint nr,
331 GLuint subnr )
332 {
333 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
334 }
335
336 static INLINE struct brw_reg brw_imm_reg( GLuint type )
337 {
338 return brw_reg( BRW_IMMEDIATE_VALUE,
339 0,
340 0,
341 type,
342 BRW_VERTICAL_STRIDE_0,
343 BRW_WIDTH_1,
344 BRW_HORIZONTAL_STRIDE_0,
345 0,
346 0);
347 }
348
349 /** Construct float immediate register */
350 static INLINE struct brw_reg brw_imm_f( GLfloat f )
351 {
352 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
353 imm.dw1.f = f;
354 return imm;
355 }
356
357 /** Construct integer immediate register */
358 static INLINE struct brw_reg brw_imm_d( GLint d )
359 {
360 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
361 imm.dw1.d = d;
362 return imm;
363 }
364
365 /** Construct uint immediate register */
366 static INLINE struct brw_reg brw_imm_ud( GLuint ud )
367 {
368 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
369 imm.dw1.ud = ud;
370 return imm;
371 }
372
373 /** Construct ushort immediate register */
374 static INLINE struct brw_reg brw_imm_uw( GLushort uw )
375 {
376 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
377 imm.dw1.ud = uw | (uw << 16);
378 return imm;
379 }
380
381 /** Construct short immediate register */
382 static INLINE struct brw_reg brw_imm_w( GLshort w )
383 {
384 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
385 imm.dw1.d = w | (w << 16);
386 return imm;
387 }
388
389 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
390 * numbers alias with _V and _VF below:
391 */
392
393 /** Construct vector of eight signed half-byte values */
394 static INLINE struct brw_reg brw_imm_v( GLuint v )
395 {
396 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
397 imm.vstride = BRW_VERTICAL_STRIDE_0;
398 imm.width = BRW_WIDTH_8;
399 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
400 imm.dw1.ud = v;
401 return imm;
402 }
403
404 /** Construct vector of four 8-bit float values */
405 static INLINE struct brw_reg brw_imm_vf( GLuint v )
406 {
407 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
408 imm.vstride = BRW_VERTICAL_STRIDE_0;
409 imm.width = BRW_WIDTH_4;
410 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
411 imm.dw1.ud = v;
412 return imm;
413 }
414
415 #define VF_ZERO 0x0
416 #define VF_ONE 0x30
417 #define VF_NEG (1<<7)
418
419 static INLINE struct brw_reg brw_imm_vf4( GLuint v0,
420 GLuint v1,
421 GLuint v2,
422 GLuint v3)
423 {
424 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
425 imm.vstride = BRW_VERTICAL_STRIDE_0;
426 imm.width = BRW_WIDTH_4;
427 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
428 imm.dw1.ud = ((v0 << 0) |
429 (v1 << 8) |
430 (v2 << 16) |
431 (v3 << 24));
432 return imm;
433 }
434
435
436 static INLINE struct brw_reg brw_address( struct brw_reg reg )
437 {
438 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
439 }
440
441 /** Construct float[1] general-purpose register */
442 static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
443 {
444 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
445 }
446
447 /** Construct float[2] general-purpose register */
448 static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
449 {
450 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
451 }
452
453 /** Construct float[4] general-purpose register */
454 static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
455 {
456 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
457 }
458
459 /** Construct float[8] general-purpose register */
460 static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
461 {
462 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
463 }
464
465
466 static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
467 {
468 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
469 }
470
471 static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
472 {
473 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
474 }
475
476
477 /** Construct null register (usually used for setting condition codes) */
478 static INLINE struct brw_reg brw_null_reg( void )
479 {
480 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
481 BRW_ARF_NULL,
482 0);
483 }
484
485 static INLINE struct brw_reg brw_address_reg( GLuint subnr )
486 {
487 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
488 BRW_ARF_ADDRESS,
489 subnr);
490 }
491
492 /* If/else instructions break in align16 mode if writemask & swizzle
493 * aren't xyzw. This goes against the convention for other scalar
494 * regs:
495 */
496 static INLINE struct brw_reg brw_ip_reg( void )
497 {
498 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
499 BRW_ARF_IP,
500 0,
501 BRW_REGISTER_TYPE_UD,
502 BRW_VERTICAL_STRIDE_4, /* ? */
503 BRW_WIDTH_1,
504 BRW_HORIZONTAL_STRIDE_0,
505 BRW_SWIZZLE_XYZW, /* NOTE! */
506 WRITEMASK_XYZW); /* NOTE! */
507 }
508
509 static INLINE struct brw_reg brw_acc_reg( void )
510 {
511 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
512 BRW_ARF_ACCUMULATOR,
513 0);
514 }
515
516
517 static INLINE struct brw_reg brw_flag_reg( void )
518 {
519 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
520 BRW_ARF_FLAG,
521 0);
522 }
523
524
525 static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
526 {
527 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
528 BRW_ARF_MASK,
529 subnr);
530 }
531
532 static INLINE struct brw_reg brw_message_reg( GLuint nr )
533 {
534 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
535 nr,
536 0);
537 }
538
539
540
541
542 /* This is almost always called with a numeric constant argument, so
543 * make things easy to evaluate at compile time:
544 */
545 static INLINE GLuint cvt( GLuint val )
546 {
547 switch (val) {
548 case 0: return 0;
549 case 1: return 1;
550 case 2: return 2;
551 case 4: return 3;
552 case 8: return 4;
553 case 16: return 5;
554 case 32: return 6;
555 }
556 return 0;
557 }
558
559 static INLINE struct brw_reg stride( struct brw_reg reg,
560 GLuint vstride,
561 GLuint width,
562 GLuint hstride )
563 {
564 reg.vstride = cvt(vstride);
565 reg.width = cvt(width) - 1;
566 reg.hstride = cvt(hstride);
567 return reg;
568 }
569
570
571 static INLINE struct brw_reg vec16( struct brw_reg reg )
572 {
573 return stride(reg, 16,16,1);
574 }
575
576 static INLINE struct brw_reg vec8( struct brw_reg reg )
577 {
578 return stride(reg, 8,8,1);
579 }
580
581 static INLINE struct brw_reg vec4( struct brw_reg reg )
582 {
583 return stride(reg, 4,4,1);
584 }
585
586 static INLINE struct brw_reg vec2( struct brw_reg reg )
587 {
588 return stride(reg, 2,2,1);
589 }
590
591 static INLINE struct brw_reg vec1( struct brw_reg reg )
592 {
593 return stride(reg, 0,1,0);
594 }
595
596
597 static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
598 {
599 return vec1(suboffset(reg, elt));
600 }
601
602 static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
603 {
604 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
605 }
606
607
608 static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
609 GLuint x,
610 GLuint y,
611 GLuint z,
612 GLuint w)
613 {
614 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
615 BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
616 BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
617 BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
618 return reg;
619 }
620
621
622 static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
623 GLuint x )
624 {
625 return brw_swizzle(reg, x, x, x, x);
626 }
627
628 static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
629 GLuint mask )
630 {
631 reg.dw1.bits.writemask &= mask;
632 return reg;
633 }
634
635 static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
636 GLuint mask )
637 {
638 reg.dw1.bits.writemask = mask;
639 return reg;
640 }
641
642 static INLINE struct brw_reg negate( struct brw_reg reg )
643 {
644 reg.negate ^= 1;
645 return reg;
646 }
647
648 static INLINE struct brw_reg brw_abs( struct brw_reg reg )
649 {
650 reg.abs = 1;
651 return reg;
652 }
653
654 /***********************************************************************
655 */
656 static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
657 GLint offset )
658 {
659 struct brw_reg reg = brw_vec4_grf(0, 0);
660 reg.subnr = subnr;
661 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
662 reg.dw1.bits.indirect_offset = offset;
663 return reg;
664 }
665
666 static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
667 GLint offset )
668 {
669 struct brw_reg reg = brw_vec1_grf(0, 0);
670 reg.subnr = subnr;
671 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
672 reg.dw1.bits.indirect_offset = offset;
673 return reg;
674 }
675
676 static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
677 {
678 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
679 }
680
681 static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
682 {
683 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
684 }
685
686 static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
687 {
688 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
689 }
690
691 static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
692 {
693 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
694 }
695
696 static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
697 {
698 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
699 }
700
701 static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
702 {
703 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
704 }
705
706 static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
707 {
708 return brw_address_reg(ptr.addr_subnr);
709 }
710
711 static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
712 {
713 ptr.addr_offset += offset;
714 return ptr;
715 }
716
717 static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
718 {
719 struct brw_indirect ptr;
720 ptr.addr_subnr = addr_subnr;
721 ptr.addr_offset = offset;
722 ptr.pad = 0;
723 return ptr;
724 }
725
726 static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
727 {
728 return &p->store[p->nr_insn];
729 }
730
731 void brw_pop_insn_state( struct brw_compile *p );
732 void brw_push_insn_state( struct brw_compile *p );
733 void brw_set_mask_control( struct brw_compile *p, GLuint value );
734 void brw_set_saturate( struct brw_compile *p, GLuint value );
735 void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
736 void brw_set_compression_control( struct brw_compile *p, GLboolean control );
737 void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
738 void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
739 void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
740
741 void brw_init_compile( struct brw_context *, struct brw_compile *p );
742 const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
743
744
745 /* Helpers for regular instructions:
746 */
747 #define ALU1(OP) \
748 struct brw_instruction *brw_##OP(struct brw_compile *p, \
749 struct brw_reg dest, \
750 struct brw_reg src0);
751
752 #define ALU2(OP) \
753 struct brw_instruction *brw_##OP(struct brw_compile *p, \
754 struct brw_reg dest, \
755 struct brw_reg src0, \
756 struct brw_reg src1);
757
758 ALU1(MOV)
759 ALU2(SEL)
760 ALU1(NOT)
761 ALU2(AND)
762 ALU2(OR)
763 ALU2(XOR)
764 ALU2(SHR)
765 ALU2(SHL)
766 ALU2(RSR)
767 ALU2(RSL)
768 ALU2(ASR)
769 ALU2(JMPI)
770 ALU2(ADD)
771 ALU2(MUL)
772 ALU1(FRC)
773 ALU1(RNDD)
774 ALU1(RNDZ)
775 ALU2(MAC)
776 ALU2(MACH)
777 ALU1(LZD)
778 ALU2(DP4)
779 ALU2(DPH)
780 ALU2(DP3)
781 ALU2(DP2)
782 ALU2(LINE)
783
784 #undef ALU1
785 #undef ALU2
786
787
788
789 /* Helpers for SEND instruction:
790 */
791 void brw_urb_WRITE(struct brw_compile *p,
792 struct brw_reg dest,
793 GLuint msg_reg_nr,
794 struct brw_reg src0,
795 GLboolean allocate,
796 GLboolean used,
797 GLuint msg_length,
798 GLuint response_length,
799 GLboolean eot,
800 GLboolean writes_complete,
801 GLuint offset,
802 GLuint swizzle);
803
804 void brw_fb_WRITE(struct brw_compile *p,
805 struct brw_reg dest,
806 GLuint msg_reg_nr,
807 struct brw_reg src0,
808 GLuint binding_table_index,
809 GLuint msg_length,
810 GLuint response_length,
811 GLboolean eot);
812
813 void brw_SAMPLE(struct brw_compile *p,
814 struct brw_reg dest,
815 GLuint msg_reg_nr,
816 struct brw_reg src0,
817 GLuint binding_table_index,
818 GLuint sampler,
819 GLuint writemask,
820 GLuint msg_type,
821 GLuint response_length,
822 GLuint msg_length,
823 GLboolean eot);
824
825 void brw_math_16( struct brw_compile *p,
826 struct brw_reg dest,
827 GLuint function,
828 GLuint saturate,
829 GLuint msg_reg_nr,
830 struct brw_reg src,
831 GLuint precision );
832
833 void brw_math( struct brw_compile *p,
834 struct brw_reg dest,
835 GLuint function,
836 GLuint saturate,
837 GLuint msg_reg_nr,
838 struct brw_reg src,
839 GLuint data_type,
840 GLuint precision );
841
842 void brw_dp_READ_16( struct brw_compile *p,
843 struct brw_reg dest,
844 GLuint msg_reg_nr,
845 GLuint scratch_offset );
846
847 void brw_dp_WRITE_16( struct brw_compile *p,
848 struct brw_reg src,
849 GLuint msg_reg_nr,
850 GLuint scratch_offset );
851
852 /* If/else/endif. Works by manipulating the execution flags on each
853 * channel.
854 */
855 struct brw_instruction *brw_IF(struct brw_compile *p,
856 GLuint execute_size);
857
858 struct brw_instruction *brw_ELSE(struct brw_compile *p,
859 struct brw_instruction *if_insn);
860
861 void brw_ENDIF(struct brw_compile *p,
862 struct brw_instruction *if_or_else_insn);
863
864
865 /* DO/WHILE loops:
866 */
867 struct brw_instruction *brw_DO(struct brw_compile *p,
868 GLuint execute_size);
869
870 struct brw_instruction *brw_WHILE(struct brw_compile *p,
871 struct brw_instruction *patch_insn);
872
873 struct brw_instruction *brw_BREAK(struct brw_compile *p);
874 struct brw_instruction *brw_CONT(struct brw_compile *p);
875 /* Forward jumps:
876 */
877 void brw_land_fwd_jump(struct brw_compile *p,
878 struct brw_instruction *jmp_insn);
879
880
881
882 void brw_NOP(struct brw_compile *p);
883
884 /* Special case: there is never a destination, execution size will be
885 * taken from src0:
886 */
887 void brw_CMP(struct brw_compile *p,
888 struct brw_reg dest,
889 GLuint conditional,
890 struct brw_reg src0,
891 struct brw_reg src1);
892
893 void brw_print_reg( struct brw_reg reg );
894
895
896 /***********************************************************************
897 * brw_eu_util.c:
898 */
899
900 void brw_copy_indirect_to_indirect(struct brw_compile *p,
901 struct brw_indirect dst_ptr,
902 struct brw_indirect src_ptr,
903 GLuint count);
904
905 void brw_copy_from_indirect(struct brw_compile *p,
906 struct brw_reg dst,
907 struct brw_indirect ptr,
908 GLuint count);
909
910 void brw_copy4(struct brw_compile *p,
911 struct brw_reg dst,
912 struct brw_reg src,
913 GLuint count);
914
915 void brw_copy8(struct brw_compile *p,
916 struct brw_reg dst,
917 struct brw_reg src,
918 GLuint count);
919
920 void brw_math_invert( struct brw_compile *p,
921 struct brw_reg dst,
922 struct brw_reg src);
923
924 void brw_set_src1( struct brw_instruction *insn,
925 struct brw_reg reg );
926 #endif