Merge branch 'glsl2-head' into glsl2
[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 10000
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 if (file == BRW_GENERAL_REGISTER_FILE)
174 assert(nr < BRW_MAX_GRF);
175 else if (file == BRW_MESSAGE_REGISTER_FILE)
176 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
177 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
178 assert(nr <= BRW_ARF_IP);
179
180 reg.type = type;
181 reg.file = file;
182 reg.nr = nr;
183 reg.subnr = subnr * type_sz(type);
184 reg.negate = 0;
185 reg.abs = 0;
186 reg.vstride = vstride;
187 reg.width = width;
188 reg.hstride = hstride;
189 reg.address_mode = BRW_ADDRESS_DIRECT;
190 reg.pad0 = 0;
191
192 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
193 * set swizzle and writemask to W, as the lower bits of subnr will
194 * be lost when converted to align16. This is probably too much to
195 * keep track of as you'd want it adjusted by suboffset(), etc.
196 * Perhaps fix up when converting to align16?
197 */
198 reg.dw1.bits.swizzle = swizzle;
199 reg.dw1.bits.writemask = writemask;
200 reg.dw1.bits.indirect_offset = 0;
201 reg.dw1.bits.pad1 = 0;
202 return reg;
203 }
204
205 /** Construct float[16] register */
206 static INLINE struct brw_reg brw_vec16_reg( GLuint file,
207 GLuint nr,
208 GLuint subnr )
209 {
210 return brw_reg(file,
211 nr,
212 subnr,
213 BRW_REGISTER_TYPE_F,
214 BRW_VERTICAL_STRIDE_16,
215 BRW_WIDTH_16,
216 BRW_HORIZONTAL_STRIDE_1,
217 BRW_SWIZZLE_XYZW,
218 WRITEMASK_XYZW);
219 }
220
221 /** Construct float[8] register */
222 static INLINE struct brw_reg brw_vec8_reg( GLuint file,
223 GLuint nr,
224 GLuint subnr )
225 {
226 return brw_reg(file,
227 nr,
228 subnr,
229 BRW_REGISTER_TYPE_F,
230 BRW_VERTICAL_STRIDE_8,
231 BRW_WIDTH_8,
232 BRW_HORIZONTAL_STRIDE_1,
233 BRW_SWIZZLE_XYZW,
234 WRITEMASK_XYZW);
235 }
236
237 /** Construct float[4] register */
238 static INLINE struct brw_reg brw_vec4_reg( GLuint file,
239 GLuint nr,
240 GLuint subnr )
241 {
242 return brw_reg(file,
243 nr,
244 subnr,
245 BRW_REGISTER_TYPE_F,
246 BRW_VERTICAL_STRIDE_4,
247 BRW_WIDTH_4,
248 BRW_HORIZONTAL_STRIDE_1,
249 BRW_SWIZZLE_XYZW,
250 WRITEMASK_XYZW);
251 }
252
253 /** Construct float[2] register */
254 static INLINE struct brw_reg brw_vec2_reg( GLuint file,
255 GLuint nr,
256 GLuint subnr )
257 {
258 return brw_reg(file,
259 nr,
260 subnr,
261 BRW_REGISTER_TYPE_F,
262 BRW_VERTICAL_STRIDE_2,
263 BRW_WIDTH_2,
264 BRW_HORIZONTAL_STRIDE_1,
265 BRW_SWIZZLE_XYXY,
266 WRITEMASK_XY);
267 }
268
269 /** Construct float[1] register */
270 static INLINE struct brw_reg brw_vec1_reg( GLuint file,
271 GLuint nr,
272 GLuint subnr )
273 {
274 return brw_reg(file,
275 nr,
276 subnr,
277 BRW_REGISTER_TYPE_F,
278 BRW_VERTICAL_STRIDE_0,
279 BRW_WIDTH_1,
280 BRW_HORIZONTAL_STRIDE_0,
281 BRW_SWIZZLE_XXXX,
282 WRITEMASK_X);
283 }
284
285
286 static INLINE struct brw_reg retype( struct brw_reg reg,
287 GLuint type )
288 {
289 reg.type = type;
290 return reg;
291 }
292
293 static INLINE struct brw_reg suboffset( struct brw_reg reg,
294 GLuint delta )
295 {
296 reg.subnr += delta * type_sz(reg.type);
297 return reg;
298 }
299
300
301 static INLINE struct brw_reg offset( struct brw_reg reg,
302 GLuint delta )
303 {
304 reg.nr += delta;
305 return reg;
306 }
307
308
309 static INLINE struct brw_reg byte_offset( struct brw_reg reg,
310 GLuint bytes )
311 {
312 GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
313 reg.nr = newoffset / REG_SIZE;
314 reg.subnr = newoffset % REG_SIZE;
315 return reg;
316 }
317
318
319 /** Construct unsigned word[16] register */
320 static INLINE struct brw_reg brw_uw16_reg( GLuint file,
321 GLuint nr,
322 GLuint subnr )
323 {
324 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
325 }
326
327 /** Construct unsigned word[8] register */
328 static INLINE struct brw_reg brw_uw8_reg( GLuint file,
329 GLuint nr,
330 GLuint subnr )
331 {
332 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
333 }
334
335 /** Construct unsigned word[1] register */
336 static INLINE struct brw_reg brw_uw1_reg( GLuint file,
337 GLuint nr,
338 GLuint subnr )
339 {
340 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
341 }
342
343 static INLINE struct brw_reg brw_imm_reg( GLuint type )
344 {
345 return brw_reg( BRW_IMMEDIATE_VALUE,
346 0,
347 0,
348 type,
349 BRW_VERTICAL_STRIDE_0,
350 BRW_WIDTH_1,
351 BRW_HORIZONTAL_STRIDE_0,
352 0,
353 0);
354 }
355
356 /** Construct float immediate register */
357 static INLINE struct brw_reg brw_imm_f( GLfloat f )
358 {
359 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
360 imm.dw1.f = f;
361 return imm;
362 }
363
364 /** Construct integer immediate register */
365 static INLINE struct brw_reg brw_imm_d( GLint d )
366 {
367 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
368 imm.dw1.d = d;
369 return imm;
370 }
371
372 /** Construct uint immediate register */
373 static INLINE struct brw_reg brw_imm_ud( GLuint ud )
374 {
375 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
376 imm.dw1.ud = ud;
377 return imm;
378 }
379
380 /** Construct ushort immediate register */
381 static INLINE struct brw_reg brw_imm_uw( GLushort uw )
382 {
383 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
384 imm.dw1.ud = uw | (uw << 16);
385 return imm;
386 }
387
388 /** Construct short immediate register */
389 static INLINE struct brw_reg brw_imm_w( GLshort w )
390 {
391 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
392 imm.dw1.d = w | (w << 16);
393 return imm;
394 }
395
396 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
397 * numbers alias with _V and _VF below:
398 */
399
400 /** Construct vector of eight signed half-byte values */
401 static INLINE struct brw_reg brw_imm_v( GLuint v )
402 {
403 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
404 imm.vstride = BRW_VERTICAL_STRIDE_0;
405 imm.width = BRW_WIDTH_8;
406 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
407 imm.dw1.ud = v;
408 return imm;
409 }
410
411 /** Construct vector of four 8-bit float values */
412 static INLINE struct brw_reg brw_imm_vf( GLuint v )
413 {
414 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
415 imm.vstride = BRW_VERTICAL_STRIDE_0;
416 imm.width = BRW_WIDTH_4;
417 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
418 imm.dw1.ud = v;
419 return imm;
420 }
421
422 #define VF_ZERO 0x0
423 #define VF_ONE 0x30
424 #define VF_NEG (1<<7)
425
426 static INLINE struct brw_reg brw_imm_vf4( GLuint v0,
427 GLuint v1,
428 GLuint v2,
429 GLuint v3)
430 {
431 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
432 imm.vstride = BRW_VERTICAL_STRIDE_0;
433 imm.width = BRW_WIDTH_4;
434 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
435 imm.dw1.ud = ((v0 << 0) |
436 (v1 << 8) |
437 (v2 << 16) |
438 (v3 << 24));
439 return imm;
440 }
441
442
443 static INLINE struct brw_reg brw_address( struct brw_reg reg )
444 {
445 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
446 }
447
448 /** Construct float[1] general-purpose register */
449 static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
450 {
451 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
452 }
453
454 /** Construct float[2] general-purpose register */
455 static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
456 {
457 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
458 }
459
460 /** Construct float[4] general-purpose register */
461 static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
462 {
463 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
464 }
465
466 /** Construct float[8] general-purpose register */
467 static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
468 {
469 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
470 }
471
472
473 static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
474 {
475 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
476 }
477
478 static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
479 {
480 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
481 }
482
483
484 /** Construct null register (usually used for setting condition codes) */
485 static INLINE struct brw_reg brw_null_reg( void )
486 {
487 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
488 BRW_ARF_NULL,
489 0);
490 }
491
492 static INLINE struct brw_reg brw_address_reg( GLuint subnr )
493 {
494 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
495 BRW_ARF_ADDRESS,
496 subnr);
497 }
498
499 /* If/else instructions break in align16 mode if writemask & swizzle
500 * aren't xyzw. This goes against the convention for other scalar
501 * regs:
502 */
503 static INLINE struct brw_reg brw_ip_reg( void )
504 {
505 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
506 BRW_ARF_IP,
507 0,
508 BRW_REGISTER_TYPE_UD,
509 BRW_VERTICAL_STRIDE_4, /* ? */
510 BRW_WIDTH_1,
511 BRW_HORIZONTAL_STRIDE_0,
512 BRW_SWIZZLE_XYZW, /* NOTE! */
513 WRITEMASK_XYZW); /* NOTE! */
514 }
515
516 static INLINE struct brw_reg brw_acc_reg( void )
517 {
518 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
519 BRW_ARF_ACCUMULATOR,
520 0);
521 }
522
523
524 static INLINE struct brw_reg brw_flag_reg( void )
525 {
526 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
527 BRW_ARF_FLAG,
528 0);
529 }
530
531
532 static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
533 {
534 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
535 BRW_ARF_MASK,
536 subnr);
537 }
538
539 static INLINE struct brw_reg brw_message_reg( GLuint nr )
540 {
541 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
542 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
543 nr,
544 0);
545 }
546
547
548
549
550 /* This is almost always called with a numeric constant argument, so
551 * make things easy to evaluate at compile time:
552 */
553 static INLINE GLuint cvt( GLuint val )
554 {
555 switch (val) {
556 case 0: return 0;
557 case 1: return 1;
558 case 2: return 2;
559 case 4: return 3;
560 case 8: return 4;
561 case 16: return 5;
562 case 32: return 6;
563 }
564 return 0;
565 }
566
567 static INLINE struct brw_reg stride( struct brw_reg reg,
568 GLuint vstride,
569 GLuint width,
570 GLuint hstride )
571 {
572 reg.vstride = cvt(vstride);
573 reg.width = cvt(width) - 1;
574 reg.hstride = cvt(hstride);
575 return reg;
576 }
577
578
579 static INLINE struct brw_reg vec16( struct brw_reg reg )
580 {
581 return stride(reg, 16,16,1);
582 }
583
584 static INLINE struct brw_reg vec8( struct brw_reg reg )
585 {
586 return stride(reg, 8,8,1);
587 }
588
589 static INLINE struct brw_reg vec4( struct brw_reg reg )
590 {
591 return stride(reg, 4,4,1);
592 }
593
594 static INLINE struct brw_reg vec2( struct brw_reg reg )
595 {
596 return stride(reg, 2,2,1);
597 }
598
599 static INLINE struct brw_reg vec1( struct brw_reg reg )
600 {
601 return stride(reg, 0,1,0);
602 }
603
604
605 static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
606 {
607 return vec1(suboffset(reg, elt));
608 }
609
610 static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
611 {
612 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
613 }
614
615
616 static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
617 GLuint x,
618 GLuint y,
619 GLuint z,
620 GLuint w)
621 {
622 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
623 BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
624 BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
625 BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
626 return reg;
627 }
628
629
630 static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
631 GLuint x )
632 {
633 return brw_swizzle(reg, x, x, x, x);
634 }
635
636 static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
637 GLuint mask )
638 {
639 reg.dw1.bits.writemask &= mask;
640 return reg;
641 }
642
643 static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
644 GLuint mask )
645 {
646 reg.dw1.bits.writemask = mask;
647 return reg;
648 }
649
650 static INLINE struct brw_reg negate( struct brw_reg reg )
651 {
652 reg.negate ^= 1;
653 return reg;
654 }
655
656 static INLINE struct brw_reg brw_abs( struct brw_reg reg )
657 {
658 reg.abs = 1;
659 return reg;
660 }
661
662 /***********************************************************************
663 */
664 static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
665 GLint offset )
666 {
667 struct brw_reg reg = brw_vec4_grf(0, 0);
668 reg.subnr = subnr;
669 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
670 reg.dw1.bits.indirect_offset = offset;
671 return reg;
672 }
673
674 static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
675 GLint offset )
676 {
677 struct brw_reg reg = brw_vec1_grf(0, 0);
678 reg.subnr = subnr;
679 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
680 reg.dw1.bits.indirect_offset = offset;
681 return reg;
682 }
683
684 static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
685 {
686 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
687 }
688
689 static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
690 {
691 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
692 }
693
694 static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
695 {
696 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
697 }
698
699 static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
700 {
701 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
702 }
703
704 static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
705 {
706 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
707 }
708
709 static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
710 {
711 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
712 }
713
714 static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
715 {
716 return brw_address_reg(ptr.addr_subnr);
717 }
718
719 static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
720 {
721 ptr.addr_offset += offset;
722 return ptr;
723 }
724
725 static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
726 {
727 struct brw_indirect ptr;
728 ptr.addr_subnr = addr_subnr;
729 ptr.addr_offset = offset;
730 ptr.pad = 0;
731 return ptr;
732 }
733
734 /** Do two brw_regs refer to the same register? */
735 static INLINE GLboolean
736 brw_same_reg(struct brw_reg r1, struct brw_reg r2)
737 {
738 return r1.file == r2.file && r1.nr == r2.nr;
739 }
740
741 static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
742 {
743 return &p->store[p->nr_insn];
744 }
745
746 void brw_pop_insn_state( struct brw_compile *p );
747 void brw_push_insn_state( struct brw_compile *p );
748 void brw_set_mask_control( struct brw_compile *p, GLuint value );
749 void brw_set_saturate( struct brw_compile *p, GLuint value );
750 void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
751 void brw_set_compression_control( struct brw_compile *p, GLboolean control );
752 void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
753 void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
754 void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
755
756 void brw_init_compile( struct brw_context *, struct brw_compile *p );
757 const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
758
759
760 /* Helpers for regular instructions:
761 */
762 #define ALU1(OP) \
763 struct brw_instruction *brw_##OP(struct brw_compile *p, \
764 struct brw_reg dest, \
765 struct brw_reg src0);
766
767 #define ALU2(OP) \
768 struct brw_instruction *brw_##OP(struct brw_compile *p, \
769 struct brw_reg dest, \
770 struct brw_reg src0, \
771 struct brw_reg src1);
772
773 ALU1(MOV)
774 ALU2(SEL)
775 ALU1(NOT)
776 ALU2(AND)
777 ALU2(OR)
778 ALU2(XOR)
779 ALU2(SHR)
780 ALU2(SHL)
781 ALU2(RSR)
782 ALU2(RSL)
783 ALU2(ASR)
784 ALU2(JMPI)
785 ALU2(ADD)
786 ALU2(MUL)
787 ALU1(FRC)
788 ALU1(RNDD)
789 ALU1(RNDZ)
790 ALU2(MAC)
791 ALU2(MACH)
792 ALU1(LZD)
793 ALU2(DP4)
794 ALU2(DPH)
795 ALU2(DP3)
796 ALU2(DP2)
797 ALU2(LINE)
798 ALU2(PLN)
799
800 #undef ALU1
801 #undef ALU2
802
803
804
805 /* Helpers for SEND instruction:
806 */
807 void brw_urb_WRITE(struct brw_compile *p,
808 struct brw_reg dest,
809 GLuint msg_reg_nr,
810 struct brw_reg src0,
811 GLboolean allocate,
812 GLboolean used,
813 GLuint msg_length,
814 GLuint response_length,
815 GLboolean eot,
816 GLboolean writes_complete,
817 GLuint offset,
818 GLuint swizzle);
819
820 void brw_ff_sync(struct brw_compile *p,
821 struct brw_reg dest,
822 GLuint msg_reg_nr,
823 struct brw_reg src0,
824 GLboolean allocate,
825 GLuint response_length,
826 GLboolean eot);
827
828 void brw_fb_WRITE(struct brw_compile *p,
829 struct brw_reg dest,
830 GLuint msg_reg_nr,
831 struct brw_reg src0,
832 GLuint binding_table_index,
833 GLuint msg_length,
834 GLuint response_length,
835 GLboolean eot);
836
837 void brw_SAMPLE(struct brw_compile *p,
838 struct brw_reg dest,
839 GLuint msg_reg_nr,
840 struct brw_reg src0,
841 GLuint binding_table_index,
842 GLuint sampler,
843 GLuint writemask,
844 GLuint msg_type,
845 GLuint response_length,
846 GLuint msg_length,
847 GLboolean eot,
848 GLuint header_present,
849 GLuint simd_mode);
850
851 void brw_math_16( struct brw_compile *p,
852 struct brw_reg dest,
853 GLuint function,
854 GLuint saturate,
855 GLuint msg_reg_nr,
856 struct brw_reg src,
857 GLuint precision );
858
859 void brw_math( struct brw_compile *p,
860 struct brw_reg dest,
861 GLuint function,
862 GLuint saturate,
863 GLuint msg_reg_nr,
864 struct brw_reg src,
865 GLuint data_type,
866 GLuint precision );
867
868 void brw_dp_READ_16( struct brw_compile *p,
869 struct brw_reg dest,
870 GLuint scratch_offset );
871
872 void brw_dp_READ_4( struct brw_compile *p,
873 struct brw_reg dest,
874 GLboolean relAddr,
875 GLuint location,
876 GLuint bind_table_index );
877
878 void brw_dp_READ_4_vs( struct brw_compile *p,
879 struct brw_reg dest,
880 GLuint oword,
881 GLboolean relAddr,
882 struct brw_reg addrReg,
883 GLuint location,
884 GLuint bind_table_index );
885
886 void brw_dp_WRITE_16( struct brw_compile *p,
887 struct brw_reg src,
888 GLuint scratch_offset );
889
890 /* If/else/endif. Works by manipulating the execution flags on each
891 * channel.
892 */
893 struct brw_instruction *brw_IF(struct brw_compile *p,
894 GLuint execute_size);
895
896 struct brw_instruction *brw_ELSE(struct brw_compile *p,
897 struct brw_instruction *if_insn);
898
899 void brw_ENDIF(struct brw_compile *p,
900 struct brw_instruction *if_or_else_insn);
901
902
903 /* DO/WHILE loops:
904 */
905 struct brw_instruction *brw_DO(struct brw_compile *p,
906 GLuint execute_size);
907
908 struct brw_instruction *brw_WHILE(struct brw_compile *p,
909 struct brw_instruction *patch_insn);
910
911 struct brw_instruction *brw_BREAK(struct brw_compile *p);
912 struct brw_instruction *brw_CONT(struct brw_compile *p);
913 /* Forward jumps:
914 */
915 void brw_land_fwd_jump(struct brw_compile *p,
916 struct brw_instruction *jmp_insn);
917
918
919
920 void brw_NOP(struct brw_compile *p);
921
922 /* Special case: there is never a destination, execution size will be
923 * taken from src0:
924 */
925 void brw_CMP(struct brw_compile *p,
926 struct brw_reg dest,
927 GLuint conditional,
928 struct brw_reg src0,
929 struct brw_reg src1);
930
931 void brw_print_reg( struct brw_reg reg );
932
933
934 /***********************************************************************
935 * brw_eu_util.c:
936 */
937
938 void brw_copy_indirect_to_indirect(struct brw_compile *p,
939 struct brw_indirect dst_ptr,
940 struct brw_indirect src_ptr,
941 GLuint count);
942
943 void brw_copy_from_indirect(struct brw_compile *p,
944 struct brw_reg dst,
945 struct brw_indirect ptr,
946 GLuint count);
947
948 void brw_copy4(struct brw_compile *p,
949 struct brw_reg dst,
950 struct brw_reg src,
951 GLuint count);
952
953 void brw_copy8(struct brw_compile *p,
954 struct brw_reg dst,
955 struct brw_reg src,
956 GLuint count);
957
958 void brw_math_invert( struct brw_compile *p,
959 struct brw_reg dst,
960 struct brw_reg src);
961
962 void brw_set_src1( struct brw_instruction *insn,
963 struct brw_reg reg );
964
965
966 /* brw_optimize.c */
967 void brw_optimize(struct brw_compile *p);
968
969 #endif