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