972ccf6bc42bbbd2cd261de9f3208594dd3452b5
[mesa.git] / src / mesa / drivers / dri / i965 / brw_reg.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 /** @file brw_reg.h
33 *
34 * This file defines struct brw_reg, which is our representation for EU
35 * registers. They're not a hardware specific format, just an abstraction
36 * that intends to capture the full flexibility of the hardware registers.
37 *
38 * The brw_eu_emit.c layer's brw_set_dest/brw_set_src[01] functions encode
39 * the abstract brw_reg type into the actual hardware instruction encoding.
40 */
41
42 #ifndef BRW_REG_H
43 #define BRW_REG_H
44
45 #include <stdbool.h>
46 #include "program/prog_instruction.h"
47 #include "brw_defines.h"
48
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52
53 /** Number of general purpose registers (VS, WM, etc) */
54 #define BRW_MAX_GRF 128
55
56 /**
57 * First GRF used for the MRF hack.
58 *
59 * On gen7, MRFs are no longer used, and contiguous GRFs are used instead. We
60 * haven't converted our compiler to be aware of this, so it asks for MRFs and
61 * brw_eu_emit.c quietly converts them to be accesses of the top GRFs. The
62 * register allocators have to be careful of this to avoid corrupting the "MRF"s
63 * with actual GRF allocations.
64 */
65 #define GEN7_MRF_HACK_START 112
66
67 /** Number of message register file registers */
68 #define BRW_MAX_MRF 16
69
70 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
71 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
72
73 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
74 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
75 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
76 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
77 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
78 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
79 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
80
81 static inline bool
82 brw_is_single_value_swizzle(int swiz)
83 {
84 return (swiz == BRW_SWIZZLE_XXXX ||
85 swiz == BRW_SWIZZLE_YYYY ||
86 swiz == BRW_SWIZZLE_ZZZZ ||
87 swiz == BRW_SWIZZLE_WWWW);
88 }
89
90 #define REG_SIZE (8*4)
91
92 /* These aren't hardware structs, just something useful for us to pass around:
93 *
94 * Align1 operation has a lot of control over input ranges. Used in
95 * WM programs to implement shaders decomposed into "channel serial"
96 * or "structure of array" form:
97 */
98 struct brw_reg {
99 unsigned type:4;
100 unsigned file:2;
101 unsigned nr:8;
102 unsigned subnr:5; /* :1 in align16 */
103 unsigned negate:1; /* source only */
104 unsigned abs:1; /* source only */
105 unsigned vstride:4; /* source only */
106 unsigned width:3; /* src only, align1 only */
107 unsigned hstride:2; /* align1 only */
108 unsigned address_mode:1; /* relative addressing, hopefully! */
109 unsigned pad0:1;
110
111 union {
112 struct {
113 unsigned swizzle:8; /* src only, align16 only */
114 unsigned writemask:4; /* dest only, align16 only */
115 int indirect_offset:10; /* relative addressing offset */
116 unsigned pad1:10; /* two dwords total */
117 } bits;
118
119 float f;
120 int d;
121 unsigned ud;
122 } dw1;
123 };
124
125
126 struct brw_indirect {
127 unsigned addr_subnr:4;
128 int addr_offset:10;
129 unsigned pad:18;
130 };
131
132
133 static inline int
134 type_sz(unsigned type)
135 {
136 switch(type) {
137 case BRW_REGISTER_TYPE_UD:
138 case BRW_REGISTER_TYPE_D:
139 case BRW_REGISTER_TYPE_F:
140 return 4;
141 case BRW_REGISTER_TYPE_HF:
142 case BRW_REGISTER_TYPE_UW:
143 case BRW_REGISTER_TYPE_W:
144 return 2;
145 case BRW_REGISTER_TYPE_UB:
146 case BRW_REGISTER_TYPE_B:
147 return 1;
148 default:
149 return 0;
150 }
151 }
152
153 /**
154 * Construct a brw_reg.
155 * \param file one of the BRW_x_REGISTER_FILE values
156 * \param nr register number/index
157 * \param subnr register sub number
158 * \param type one of BRW_REGISTER_TYPE_x
159 * \param vstride one of BRW_VERTICAL_STRIDE_x
160 * \param width one of BRW_WIDTH_x
161 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
162 * \param swizzle one of BRW_SWIZZLE_x
163 * \param writemask WRITEMASK_X/Y/Z/W bitfield
164 */
165 static inline struct brw_reg
166 brw_reg(unsigned file,
167 unsigned nr,
168 unsigned subnr,
169 unsigned type,
170 unsigned vstride,
171 unsigned width,
172 unsigned hstride,
173 unsigned swizzle,
174 unsigned writemask)
175 {
176 struct brw_reg reg;
177 if (file == BRW_GENERAL_REGISTER_FILE)
178 assert(nr < BRW_MAX_GRF);
179 else if (file == BRW_MESSAGE_REGISTER_FILE)
180 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
181 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
182 assert(nr <= BRW_ARF_TIMESTAMP);
183
184 reg.type = type;
185 reg.file = file;
186 reg.nr = nr;
187 reg.subnr = subnr * type_sz(type);
188 reg.negate = 0;
189 reg.abs = 0;
190 reg.vstride = vstride;
191 reg.width = width;
192 reg.hstride = hstride;
193 reg.address_mode = BRW_ADDRESS_DIRECT;
194 reg.pad0 = 0;
195
196 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
197 * set swizzle and writemask to W, as the lower bits of subnr will
198 * be lost when converted to align16. This is probably too much to
199 * keep track of as you'd want it adjusted by suboffset(), etc.
200 * Perhaps fix up when converting to align16?
201 */
202 reg.dw1.bits.swizzle = swizzle;
203 reg.dw1.bits.writemask = writemask;
204 reg.dw1.bits.indirect_offset = 0;
205 reg.dw1.bits.pad1 = 0;
206 return reg;
207 }
208
209 /** Construct float[16] register */
210 static inline struct brw_reg
211 brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
212 {
213 return brw_reg(file,
214 nr,
215 subnr,
216 BRW_REGISTER_TYPE_F,
217 BRW_VERTICAL_STRIDE_16,
218 BRW_WIDTH_16,
219 BRW_HORIZONTAL_STRIDE_1,
220 BRW_SWIZZLE_XYZW,
221 WRITEMASK_XYZW);
222 }
223
224 /** Construct float[8] register */
225 static inline struct brw_reg
226 brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
227 {
228 return brw_reg(file,
229 nr,
230 subnr,
231 BRW_REGISTER_TYPE_F,
232 BRW_VERTICAL_STRIDE_8,
233 BRW_WIDTH_8,
234 BRW_HORIZONTAL_STRIDE_1,
235 BRW_SWIZZLE_XYZW,
236 WRITEMASK_XYZW);
237 }
238
239 /** Construct float[4] register */
240 static inline struct brw_reg
241 brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
242 {
243 return brw_reg(file,
244 nr,
245 subnr,
246 BRW_REGISTER_TYPE_F,
247 BRW_VERTICAL_STRIDE_4,
248 BRW_WIDTH_4,
249 BRW_HORIZONTAL_STRIDE_1,
250 BRW_SWIZZLE_XYZW,
251 WRITEMASK_XYZW);
252 }
253
254 /** Construct float[2] register */
255 static inline struct brw_reg
256 brw_vec2_reg(unsigned file, unsigned nr, unsigned 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
271 brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
272 {
273 return brw_reg(file,
274 nr,
275 subnr,
276 BRW_REGISTER_TYPE_F,
277 BRW_VERTICAL_STRIDE_0,
278 BRW_WIDTH_1,
279 BRW_HORIZONTAL_STRIDE_0,
280 BRW_SWIZZLE_XXXX,
281 WRITEMASK_X);
282 }
283
284
285 static inline struct brw_reg
286 retype(struct brw_reg reg, unsigned type)
287 {
288 reg.type = type;
289 return reg;
290 }
291
292 static inline struct brw_reg
293 sechalf(struct brw_reg reg)
294 {
295 if (reg.vstride)
296 reg.nr++;
297 return reg;
298 }
299
300 static inline struct brw_reg
301 suboffset(struct brw_reg reg, unsigned delta)
302 {
303 reg.subnr += delta * type_sz(reg.type);
304 return reg;
305 }
306
307
308 static inline struct brw_reg
309 offset(struct brw_reg reg, unsigned delta)
310 {
311 reg.nr += delta;
312 return reg;
313 }
314
315
316 static inline struct brw_reg
317 byte_offset(struct brw_reg reg, unsigned bytes)
318 {
319 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
320 reg.nr = newoffset / REG_SIZE;
321 reg.subnr = newoffset % REG_SIZE;
322 return reg;
323 }
324
325
326 /** Construct unsigned word[16] register */
327 static inline struct brw_reg
328 brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
329 {
330 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
331 }
332
333 /** Construct unsigned word[8] register */
334 static inline struct brw_reg
335 brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
336 {
337 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
338 }
339
340 /** Construct unsigned word[1] register */
341 static inline struct brw_reg
342 brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
343 {
344 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
345 }
346
347 /** Construct unsigned dword[1] register */
348 static inline struct brw_reg
349 brw_ud1_reg(unsigned file, unsigned nr, unsigned subnr)
350 {
351 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UD), subnr);
352 }
353
354 static inline struct brw_reg
355 brw_imm_reg(unsigned type)
356 {
357 return brw_reg(BRW_IMMEDIATE_VALUE,
358 0,
359 0,
360 type,
361 BRW_VERTICAL_STRIDE_0,
362 BRW_WIDTH_1,
363 BRW_HORIZONTAL_STRIDE_0,
364 0,
365 0);
366 }
367
368 /** Construct float immediate register */
369 static inline struct brw_reg
370 brw_imm_f(float f)
371 {
372 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
373 imm.dw1.f = f;
374 return imm;
375 }
376
377 /** Construct integer immediate register */
378 static inline struct brw_reg
379 brw_imm_d(int d)
380 {
381 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
382 imm.dw1.d = d;
383 return imm;
384 }
385
386 /** Construct uint immediate register */
387 static inline struct brw_reg
388 brw_imm_ud(unsigned ud)
389 {
390 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
391 imm.dw1.ud = ud;
392 return imm;
393 }
394
395 /** Construct ushort immediate register */
396 static inline struct brw_reg
397 brw_imm_uw(uint16_t uw)
398 {
399 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
400 imm.dw1.ud = uw | (uw << 16);
401 return imm;
402 }
403
404 /** Construct short immediate register */
405 static inline struct brw_reg
406 brw_imm_w(int16_t w)
407 {
408 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
409 imm.dw1.d = w | (w << 16);
410 return imm;
411 }
412
413 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
414 * numbers alias with _V and _VF below:
415 */
416
417 /** Construct vector of eight signed half-byte values */
418 static inline struct brw_reg
419 brw_imm_v(unsigned v)
420 {
421 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
422 imm.vstride = BRW_VERTICAL_STRIDE_0;
423 imm.width = BRW_WIDTH_8;
424 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
425 imm.dw1.ud = v;
426 return imm;
427 }
428
429 /** Construct vector of four 8-bit float values */
430 static inline struct brw_reg
431 brw_imm_vf(unsigned v)
432 {
433 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
434 imm.vstride = BRW_VERTICAL_STRIDE_0;
435 imm.width = BRW_WIDTH_4;
436 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
437 imm.dw1.ud = v;
438 return imm;
439 }
440
441 #define VF_ZERO 0x0
442 #define VF_ONE 0x30
443 #define VF_NEG (1<<7)
444
445 static inline struct brw_reg
446 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
447 {
448 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
449 imm.vstride = BRW_VERTICAL_STRIDE_0;
450 imm.width = BRW_WIDTH_4;
451 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
452 imm.dw1.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
453 return imm;
454 }
455
456
457 static inline struct brw_reg
458 brw_address(struct brw_reg reg)
459 {
460 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
461 }
462
463 /** Construct float[1] general-purpose register */
464 static inline struct brw_reg
465 brw_vec1_grf(unsigned nr, unsigned subnr)
466 {
467 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
468 }
469
470 /** Construct float[2] general-purpose register */
471 static inline struct brw_reg
472 brw_vec2_grf(unsigned nr, unsigned subnr)
473 {
474 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
475 }
476
477 /** Construct float[4] general-purpose register */
478 static inline struct brw_reg
479 brw_vec4_grf(unsigned nr, unsigned subnr)
480 {
481 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
482 }
483
484 /** Construct float[8] general-purpose register */
485 static inline struct brw_reg
486 brw_vec8_grf(unsigned nr, unsigned subnr)
487 {
488 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
489 }
490
491
492 static inline struct brw_reg
493 brw_uw8_grf(unsigned nr, unsigned subnr)
494 {
495 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
496 }
497
498 static inline struct brw_reg
499 brw_uw16_grf(unsigned nr, unsigned subnr)
500 {
501 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
502 }
503
504
505 /** Construct null register (usually used for setting condition codes) */
506 static inline struct brw_reg
507 brw_null_reg(void)
508 {
509 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
510 }
511
512 static inline struct brw_reg
513 brw_address_reg(unsigned subnr)
514 {
515 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
516 }
517
518 /* If/else instructions break in align16 mode if writemask & swizzle
519 * aren't xyzw. This goes against the convention for other scalar
520 * regs:
521 */
522 static inline struct brw_reg
523 brw_ip_reg(void)
524 {
525 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
526 BRW_ARF_IP,
527 0,
528 BRW_REGISTER_TYPE_UD,
529 BRW_VERTICAL_STRIDE_4, /* ? */
530 BRW_WIDTH_1,
531 BRW_HORIZONTAL_STRIDE_0,
532 BRW_SWIZZLE_XYZW, /* NOTE! */
533 WRITEMASK_XYZW); /* NOTE! */
534 }
535
536 static inline struct brw_reg
537 brw_acc_reg(void)
538 {
539 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0);
540 }
541
542 static inline struct brw_reg
543 brw_notification_1_reg(void)
544 {
545
546 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
547 BRW_ARF_NOTIFICATION_COUNT,
548 1,
549 BRW_REGISTER_TYPE_UD,
550 BRW_VERTICAL_STRIDE_0,
551 BRW_WIDTH_1,
552 BRW_HORIZONTAL_STRIDE_0,
553 BRW_SWIZZLE_XXXX,
554 WRITEMASK_X);
555 }
556
557
558 static inline struct brw_reg
559 brw_flag_reg(int reg, int subreg)
560 {
561 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
562 BRW_ARF_FLAG + reg, subreg);
563 }
564
565
566 static inline struct brw_reg
567 brw_mask_reg(unsigned subnr)
568 {
569 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
570 }
571
572 static inline struct brw_reg
573 brw_message_reg(unsigned nr)
574 {
575 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
576 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
577 }
578
579
580 /* This is almost always called with a numeric constant argument, so
581 * make things easy to evaluate at compile time:
582 */
583 static inline unsigned cvt(unsigned val)
584 {
585 switch (val) {
586 case 0: return 0;
587 case 1: return 1;
588 case 2: return 2;
589 case 4: return 3;
590 case 8: return 4;
591 case 16: return 5;
592 case 32: return 6;
593 }
594 return 0;
595 }
596
597 static inline struct brw_reg
598 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
599 {
600 reg.vstride = cvt(vstride);
601 reg.width = cvt(width) - 1;
602 reg.hstride = cvt(hstride);
603 return reg;
604 }
605
606
607 static inline struct brw_reg
608 vec16(struct brw_reg reg)
609 {
610 return stride(reg, 16,16,1);
611 }
612
613 static inline struct brw_reg
614 vec8(struct brw_reg reg)
615 {
616 return stride(reg, 8,8,1);
617 }
618
619 static inline struct brw_reg
620 vec4(struct brw_reg reg)
621 {
622 return stride(reg, 4,4,1);
623 }
624
625 static inline struct brw_reg
626 vec2(struct brw_reg reg)
627 {
628 return stride(reg, 2,2,1);
629 }
630
631 static inline struct brw_reg
632 vec1(struct brw_reg reg)
633 {
634 return stride(reg, 0,1,0);
635 }
636
637
638 static inline struct brw_reg
639 get_element(struct brw_reg reg, unsigned elt)
640 {
641 return vec1(suboffset(reg, elt));
642 }
643
644 static inline struct brw_reg
645 get_element_ud(struct brw_reg reg, unsigned elt)
646 {
647 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
648 }
649
650 static inline struct brw_reg
651 get_element_d(struct brw_reg reg, unsigned elt)
652 {
653 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
654 }
655
656
657 static inline struct brw_reg
658 brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
659 {
660 assert(reg.file != BRW_IMMEDIATE_VALUE);
661
662 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
663 BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
664 BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
665 BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
666 return reg;
667 }
668
669
670 static inline struct brw_reg
671 brw_swizzle1(struct brw_reg reg, unsigned x)
672 {
673 return brw_swizzle(reg, x, x, x, x);
674 }
675
676 static inline struct brw_reg
677 brw_writemask(struct brw_reg reg, unsigned mask)
678 {
679 assert(reg.file != BRW_IMMEDIATE_VALUE);
680 reg.dw1.bits.writemask &= mask;
681 return reg;
682 }
683
684 static inline struct brw_reg
685 brw_set_writemask(struct brw_reg reg, unsigned mask)
686 {
687 assert(reg.file != BRW_IMMEDIATE_VALUE);
688 reg.dw1.bits.writemask = mask;
689 return reg;
690 }
691
692 static inline struct brw_reg
693 negate(struct brw_reg reg)
694 {
695 reg.negate ^= 1;
696 return reg;
697 }
698
699 static inline struct brw_reg
700 brw_abs(struct brw_reg reg)
701 {
702 reg.abs = 1;
703 reg.negate = 0;
704 return reg;
705 }
706
707 /************************************************************************/
708
709 static inline struct brw_reg
710 brw_vec4_indirect(unsigned subnr, int offset)
711 {
712 struct brw_reg reg = brw_vec4_grf(0, 0);
713 reg.subnr = subnr;
714 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
715 reg.dw1.bits.indirect_offset = offset;
716 return reg;
717 }
718
719 static inline struct brw_reg
720 brw_vec1_indirect(unsigned subnr, int offset)
721 {
722 struct brw_reg reg = brw_vec1_grf(0, 0);
723 reg.subnr = subnr;
724 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
725 reg.dw1.bits.indirect_offset = offset;
726 return reg;
727 }
728
729 static inline struct brw_reg
730 deref_4f(struct brw_indirect ptr, int offset)
731 {
732 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
733 }
734
735 static inline struct brw_reg
736 deref_1f(struct brw_indirect ptr, int offset)
737 {
738 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
739 }
740
741 static inline struct brw_reg
742 deref_4b(struct brw_indirect ptr, int offset)
743 {
744 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
745 }
746
747 static inline struct brw_reg
748 deref_1uw(struct brw_indirect ptr, int offset)
749 {
750 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
751 }
752
753 static inline struct brw_reg
754 deref_1d(struct brw_indirect ptr, int offset)
755 {
756 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
757 }
758
759 static inline struct brw_reg
760 deref_1ud(struct brw_indirect ptr, int offset)
761 {
762 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
763 }
764
765 static inline struct brw_reg
766 get_addr_reg(struct brw_indirect ptr)
767 {
768 return brw_address_reg(ptr.addr_subnr);
769 }
770
771 static inline struct brw_indirect
772 brw_indirect_offset(struct brw_indirect ptr, int offset)
773 {
774 ptr.addr_offset += offset;
775 return ptr;
776 }
777
778 static inline struct brw_indirect
779 brw_indirect(unsigned addr_subnr, int offset)
780 {
781 struct brw_indirect ptr;
782 ptr.addr_subnr = addr_subnr;
783 ptr.addr_offset = offset;
784 ptr.pad = 0;
785 return ptr;
786 }
787
788 /** Do two brw_regs refer to the same register? */
789 static inline bool
790 brw_same_reg(struct brw_reg r1, struct brw_reg r2)
791 {
792 return r1.file == r2.file && r1.nr == r2.nr;
793 }
794
795 void brw_print_reg(struct brw_reg reg);
796
797 #ifdef __cplusplus
798 }
799 #endif
800
801 #endif