6ffcd7b5ecdf63574ba2493c6e99d2a3ddff9d9e
[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 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
81
82 static inline bool
83 brw_is_single_value_swizzle(int swiz)
84 {
85 return (swiz == BRW_SWIZZLE_XXXX ||
86 swiz == BRW_SWIZZLE_YYYY ||
87 swiz == BRW_SWIZZLE_ZZZZ ||
88 swiz == BRW_SWIZZLE_WWWW);
89 }
90
91 #define REG_SIZE (8*4)
92
93 /* These aren't hardware structs, just something useful for us to pass around:
94 *
95 * Align1 operation has a lot of control over input ranges. Used in
96 * WM programs to implement shaders decomposed into "channel serial"
97 * or "structure of array" form:
98 */
99 struct brw_reg {
100 unsigned type:4;
101 unsigned file:2;
102 unsigned nr:8;
103 unsigned subnr:5; /* :1 in align16 */
104 unsigned negate:1; /* source only */
105 unsigned abs:1; /* source only */
106 unsigned vstride:4; /* source only */
107 unsigned width:3; /* src only, align1 only */
108 unsigned hstride:2; /* align1 only */
109 unsigned address_mode:1; /* relative addressing, hopefully! */
110 unsigned pad0:1;
111
112 union {
113 struct {
114 unsigned swizzle:8; /* src only, align16 only */
115 unsigned writemask:4; /* dest only, align16 only */
116 int indirect_offset:10; /* relative addressing offset */
117 unsigned pad1:10; /* two dwords total */
118 } bits;
119
120 float f;
121 int d;
122 unsigned ud;
123 } dw1;
124 };
125
126
127 struct brw_indirect {
128 unsigned addr_subnr:4;
129 int addr_offset:10;
130 unsigned pad:18;
131 };
132
133
134 static inline int
135 type_sz(unsigned type)
136 {
137 switch(type) {
138 case BRW_REGISTER_TYPE_UD:
139 case BRW_REGISTER_TYPE_D:
140 case BRW_REGISTER_TYPE_F:
141 return 4;
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 static inline struct brw_reg
285 brw_vecn_reg(unsigned width, unsigned file, unsigned nr, unsigned subnr)
286 {
287 switch (width) {
288 case 1:
289 return brw_vec1_reg(file, nr, subnr);
290 case 2:
291 return brw_vec2_reg(file, nr, subnr);
292 case 4:
293 return brw_vec4_reg(file, nr, subnr);
294 case 8:
295 return brw_vec8_reg(file, nr, subnr);
296 case 16:
297 return brw_vec16_reg(file, nr, subnr);
298 default:
299 assert(!"Invalid register width");
300 }
301 unreachable();
302 }
303
304 static inline struct brw_reg
305 retype(struct brw_reg reg, unsigned type)
306 {
307 reg.type = type;
308 return reg;
309 }
310
311 static inline struct brw_reg
312 sechalf(struct brw_reg reg)
313 {
314 if (reg.vstride)
315 reg.nr++;
316 return reg;
317 }
318
319 static inline struct brw_reg
320 suboffset(struct brw_reg reg, unsigned delta)
321 {
322 reg.subnr += delta * type_sz(reg.type);
323 return reg;
324 }
325
326
327 static inline struct brw_reg
328 offset(struct brw_reg reg, unsigned delta)
329 {
330 reg.nr += delta;
331 return reg;
332 }
333
334
335 static inline struct brw_reg
336 byte_offset(struct brw_reg reg, unsigned bytes)
337 {
338 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
339 reg.nr = newoffset / REG_SIZE;
340 reg.subnr = newoffset % REG_SIZE;
341 return reg;
342 }
343
344
345 /** Construct unsigned word[16] register */
346 static inline struct brw_reg
347 brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
348 {
349 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
350 }
351
352 /** Construct unsigned word[8] register */
353 static inline struct brw_reg
354 brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
355 {
356 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
357 }
358
359 /** Construct unsigned word[1] register */
360 static inline struct brw_reg
361 brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
362 {
363 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
364 }
365
366 static inline struct brw_reg
367 brw_imm_reg(unsigned type)
368 {
369 return brw_reg(BRW_IMMEDIATE_VALUE,
370 0,
371 0,
372 type,
373 BRW_VERTICAL_STRIDE_0,
374 BRW_WIDTH_1,
375 BRW_HORIZONTAL_STRIDE_0,
376 0,
377 0);
378 }
379
380 /** Construct float immediate register */
381 static inline struct brw_reg
382 brw_imm_f(float f)
383 {
384 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
385 imm.dw1.f = f;
386 return imm;
387 }
388
389 /** Construct integer immediate register */
390 static inline struct brw_reg
391 brw_imm_d(int d)
392 {
393 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
394 imm.dw1.d = d;
395 return imm;
396 }
397
398 /** Construct uint immediate register */
399 static inline struct brw_reg
400 brw_imm_ud(unsigned ud)
401 {
402 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
403 imm.dw1.ud = ud;
404 return imm;
405 }
406
407 /** Construct ushort immediate register */
408 static inline struct brw_reg
409 brw_imm_uw(uint16_t uw)
410 {
411 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
412 imm.dw1.ud = uw | (uw << 16);
413 return imm;
414 }
415
416 /** Construct short immediate register */
417 static inline struct brw_reg
418 brw_imm_w(int16_t w)
419 {
420 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
421 imm.dw1.d = w | (w << 16);
422 return imm;
423 }
424
425 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
426 * numbers alias with _V and _VF below:
427 */
428
429 /** Construct vector of eight signed half-byte values */
430 static inline struct brw_reg
431 brw_imm_v(unsigned v)
432 {
433 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
434 imm.vstride = BRW_VERTICAL_STRIDE_0;
435 imm.width = BRW_WIDTH_8;
436 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
437 imm.dw1.ud = v;
438 return imm;
439 }
440
441 /** Construct vector of four 8-bit float values */
442 static inline struct brw_reg
443 brw_imm_vf(unsigned v)
444 {
445 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
446 imm.vstride = BRW_VERTICAL_STRIDE_0;
447 imm.width = BRW_WIDTH_4;
448 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
449 imm.dw1.ud = v;
450 return imm;
451 }
452
453 #define VF_ZERO 0x0
454 #define VF_ONE 0x30
455 #define VF_NEG (1<<7)
456
457 static inline struct brw_reg
458 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
459 {
460 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
461 imm.vstride = BRW_VERTICAL_STRIDE_0;
462 imm.width = BRW_WIDTH_4;
463 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
464 imm.dw1.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
465 return imm;
466 }
467
468
469 static inline struct brw_reg
470 brw_address(struct brw_reg reg)
471 {
472 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
473 }
474
475 /** Construct float[1] general-purpose register */
476 static inline struct brw_reg
477 brw_vec1_grf(unsigned nr, unsigned subnr)
478 {
479 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
480 }
481
482 /** Construct float[2] general-purpose register */
483 static inline struct brw_reg
484 brw_vec2_grf(unsigned nr, unsigned subnr)
485 {
486 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
487 }
488
489 /** Construct float[4] general-purpose register */
490 static inline struct brw_reg
491 brw_vec4_grf(unsigned nr, unsigned subnr)
492 {
493 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
494 }
495
496 /** Construct float[8] general-purpose register */
497 static inline struct brw_reg
498 brw_vec8_grf(unsigned nr, unsigned subnr)
499 {
500 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
501 }
502
503
504 static inline struct brw_reg
505 brw_uw8_grf(unsigned nr, unsigned subnr)
506 {
507 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
508 }
509
510 static inline struct brw_reg
511 brw_uw16_grf(unsigned nr, unsigned subnr)
512 {
513 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
514 }
515
516
517 /** Construct null register (usually used for setting condition codes) */
518 static inline struct brw_reg
519 brw_null_reg(void)
520 {
521 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
522 }
523
524 static inline struct brw_reg
525 brw_address_reg(unsigned subnr)
526 {
527 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
528 }
529
530 /* If/else instructions break in align16 mode if writemask & swizzle
531 * aren't xyzw. This goes against the convention for other scalar
532 * regs:
533 */
534 static inline struct brw_reg
535 brw_ip_reg(void)
536 {
537 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
538 BRW_ARF_IP,
539 0,
540 BRW_REGISTER_TYPE_UD,
541 BRW_VERTICAL_STRIDE_4, /* ? */
542 BRW_WIDTH_1,
543 BRW_HORIZONTAL_STRIDE_0,
544 BRW_SWIZZLE_XYZW, /* NOTE! */
545 WRITEMASK_XYZW); /* NOTE! */
546 }
547
548 static inline struct brw_reg
549 brw_acc_reg(void)
550 {
551 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0);
552 }
553
554 static inline struct brw_reg
555 brw_notification_1_reg(void)
556 {
557
558 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
559 BRW_ARF_NOTIFICATION_COUNT,
560 1,
561 BRW_REGISTER_TYPE_UD,
562 BRW_VERTICAL_STRIDE_0,
563 BRW_WIDTH_1,
564 BRW_HORIZONTAL_STRIDE_0,
565 BRW_SWIZZLE_XXXX,
566 WRITEMASK_X);
567 }
568
569
570 static inline struct brw_reg
571 brw_flag_reg(int reg, int subreg)
572 {
573 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
574 BRW_ARF_FLAG + reg, subreg);
575 }
576
577
578 static inline struct brw_reg
579 brw_mask_reg(unsigned subnr)
580 {
581 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
582 }
583
584 static inline struct brw_reg
585 brw_message_reg(unsigned nr)
586 {
587 assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
588 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
589 }
590
591 static inline struct brw_reg
592 brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
593 {
594 return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
595 BRW_REGISTER_TYPE_UD);
596 }
597
598 /* This is almost always called with a numeric constant argument, so
599 * make things easy to evaluate at compile time:
600 */
601 static inline unsigned cvt(unsigned val)
602 {
603 switch (val) {
604 case 0: return 0;
605 case 1: return 1;
606 case 2: return 2;
607 case 4: return 3;
608 case 8: return 4;
609 case 16: return 5;
610 case 32: return 6;
611 }
612 return 0;
613 }
614
615 static inline struct brw_reg
616 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
617 {
618 reg.vstride = cvt(vstride);
619 reg.width = cvt(width) - 1;
620 reg.hstride = cvt(hstride);
621 return reg;
622 }
623
624
625 static inline struct brw_reg
626 vec16(struct brw_reg reg)
627 {
628 return stride(reg, 16,16,1);
629 }
630
631 static inline struct brw_reg
632 vec8(struct brw_reg reg)
633 {
634 return stride(reg, 8,8,1);
635 }
636
637 static inline struct brw_reg
638 vec4(struct brw_reg reg)
639 {
640 return stride(reg, 4,4,1);
641 }
642
643 static inline struct brw_reg
644 vec2(struct brw_reg reg)
645 {
646 return stride(reg, 2,2,1);
647 }
648
649 static inline struct brw_reg
650 vec1(struct brw_reg reg)
651 {
652 return stride(reg, 0,1,0);
653 }
654
655
656 static inline struct brw_reg
657 get_element(struct brw_reg reg, unsigned elt)
658 {
659 return vec1(suboffset(reg, elt));
660 }
661
662 static inline struct brw_reg
663 get_element_ud(struct brw_reg reg, unsigned elt)
664 {
665 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
666 }
667
668 static inline struct brw_reg
669 get_element_d(struct brw_reg reg, unsigned elt)
670 {
671 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
672 }
673
674
675 static inline struct brw_reg
676 brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
677 {
678 assert(reg.file != BRW_IMMEDIATE_VALUE);
679
680 reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
681 BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
682 BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
683 BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
684 return reg;
685 }
686
687
688 static inline struct brw_reg
689 brw_swizzle1(struct brw_reg reg, unsigned x)
690 {
691 return brw_swizzle(reg, x, x, x, x);
692 }
693
694 static inline struct brw_reg
695 brw_writemask(struct brw_reg reg, unsigned mask)
696 {
697 assert(reg.file != BRW_IMMEDIATE_VALUE);
698 reg.dw1.bits.writemask &= mask;
699 return reg;
700 }
701
702 static inline struct brw_reg
703 brw_set_writemask(struct brw_reg reg, unsigned mask)
704 {
705 assert(reg.file != BRW_IMMEDIATE_VALUE);
706 reg.dw1.bits.writemask = mask;
707 return reg;
708 }
709
710 static inline struct brw_reg
711 negate(struct brw_reg reg)
712 {
713 reg.negate ^= 1;
714 return reg;
715 }
716
717 static inline struct brw_reg
718 brw_abs(struct brw_reg reg)
719 {
720 reg.abs = 1;
721 reg.negate = 0;
722 return reg;
723 }
724
725 /************************************************************************/
726
727 static inline struct brw_reg
728 brw_vec4_indirect(unsigned subnr, int offset)
729 {
730 struct brw_reg reg = brw_vec4_grf(0, 0);
731 reg.subnr = subnr;
732 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
733 reg.dw1.bits.indirect_offset = offset;
734 return reg;
735 }
736
737 static inline struct brw_reg
738 brw_vec1_indirect(unsigned subnr, int offset)
739 {
740 struct brw_reg reg = brw_vec1_grf(0, 0);
741 reg.subnr = subnr;
742 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
743 reg.dw1.bits.indirect_offset = offset;
744 return reg;
745 }
746
747 static inline struct brw_reg
748 deref_4f(struct brw_indirect ptr, int offset)
749 {
750 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
751 }
752
753 static inline struct brw_reg
754 deref_1f(struct brw_indirect ptr, int offset)
755 {
756 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
757 }
758
759 static inline struct brw_reg
760 deref_4b(struct brw_indirect ptr, int offset)
761 {
762 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
763 }
764
765 static inline struct brw_reg
766 deref_1uw(struct brw_indirect ptr, int offset)
767 {
768 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
769 }
770
771 static inline struct brw_reg
772 deref_1d(struct brw_indirect ptr, int offset)
773 {
774 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
775 }
776
777 static inline struct brw_reg
778 deref_1ud(struct brw_indirect ptr, int offset)
779 {
780 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
781 }
782
783 static inline struct brw_reg
784 get_addr_reg(struct brw_indirect ptr)
785 {
786 return brw_address_reg(ptr.addr_subnr);
787 }
788
789 static inline struct brw_indirect
790 brw_indirect_offset(struct brw_indirect ptr, int offset)
791 {
792 ptr.addr_offset += offset;
793 return ptr;
794 }
795
796 static inline struct brw_indirect
797 brw_indirect(unsigned addr_subnr, int offset)
798 {
799 struct brw_indirect ptr;
800 ptr.addr_subnr = addr_subnr;
801 ptr.addr_offset = offset;
802 ptr.pad = 0;
803 return ptr;
804 }
805
806 #ifdef __cplusplus
807 }
808 #endif
809
810 #endif