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