2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics to
4 develop this 3D driver.
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:
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.
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.
26 **********************************************************************/
29 * Keith Whitwell <keithw@vmware.com>
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.
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.
46 #include "main/compiler.h"
47 #include "main/macros.h"
48 #include "program/prog_instruction.h"
49 #include "brw_eu_defines.h"
50 #include "brw_reg_type.h"
56 struct gen_device_info
;
58 /** Number of general purpose registers (VS, WM, etc) */
59 #define BRW_MAX_GRF 128
62 * First GRF used for the MRF hack.
64 * On gen7, MRFs are no longer used, and contiguous GRFs are used instead. We
65 * haven't converted our compiler to be aware of this, so it asks for MRFs and
66 * brw_eu_emit.c quietly converts them to be accesses of the top GRFs. The
67 * register allocators have to be careful of this to avoid corrupting the "MRF"s
68 * with actual GRF allocations.
70 #define GEN7_MRF_HACK_START 112
72 /** Number of message register file registers */
73 #define BRW_MAX_MRF(gen) (gen == 6 ? 24 : 16)
75 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
76 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
78 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
79 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
80 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
81 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
82 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
83 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
84 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
85 #define BRW_SWIZZLE_YXYX BRW_SWIZZLE4(1,0,1,0)
86 #define BRW_SWIZZLE_XZXZ BRW_SWIZZLE4(0,2,0,2)
87 #define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
88 #define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
89 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
90 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
91 #define BRW_SWIZZLE_WZWZ BRW_SWIZZLE4(3,2,3,2)
92 #define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
93 #define BRW_SWIZZLE_XXZZ BRW_SWIZZLE4(0,0,2,2)
94 #define BRW_SWIZZLE_YYWW BRW_SWIZZLE4(1,1,3,3)
95 #define BRW_SWIZZLE_YXWZ BRW_SWIZZLE4(1,0,3,2)
97 #define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
98 #define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
101 brw_is_single_value_swizzle(unsigned swiz
)
103 return (swiz
== BRW_SWIZZLE_XXXX
||
104 swiz
== BRW_SWIZZLE_YYYY
||
105 swiz
== BRW_SWIZZLE_ZZZZ
||
106 swiz
== BRW_SWIZZLE_WWWW
);
110 * Compute the swizzle obtained from the application of \p swz0 on the result
111 * of \p swz1. The argument ordering is expected to match function
114 static inline unsigned
115 brw_compose_swizzle(unsigned swz0
, unsigned swz1
)
118 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 0)),
119 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 1)),
120 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 2)),
121 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 3)));
125 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
128 static inline unsigned
129 brw_apply_swizzle_to_mask(unsigned swz
, unsigned mask
)
133 for (unsigned i
= 0; i
< 4; i
++) {
134 if (mask
& (1 << BRW_GET_SWZ(swz
, i
)))
142 * Return the result of applying the inverse of swizzle \p swz to shuffle the
143 * bits of \p mask (AKA preimage). Useful to find out which components are
144 * read from a swizzled source given the instruction writemask.
146 static inline unsigned
147 brw_apply_inv_swizzle_to_mask(unsigned swz
, unsigned mask
)
151 for (unsigned i
= 0; i
< 4; i
++) {
153 result
|= 1 << BRW_GET_SWZ(swz
, i
);
160 * Construct an identity swizzle for the set of enabled channels given by \p
161 * mask. The result will only reference channels enabled in the provided \p
162 * mask, assuming that \p mask is non-zero. The constructed swizzle will
163 * satisfy the property that for any instruction OP and any mask:
165 * brw_OP(p, brw_writemask(dst, mask),
166 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
168 * will be equivalent to the same instruction without swizzle:
170 * brw_OP(p, brw_writemask(dst, mask), src);
172 static inline unsigned
173 brw_swizzle_for_mask(unsigned mask
)
175 unsigned last
= (mask
? ffs(mask
) - 1 : 0);
178 for (unsigned i
= 0; i
< 4; i
++)
179 last
= swz
[i
] = (mask
& (1 << i
) ? i
: last
);
181 return BRW_SWIZZLE4(swz
[0], swz
[1], swz
[2], swz
[3]);
185 * Construct an identity swizzle for the first \p n components of a vector.
186 * When only a subset of channels of a vec4 are used we don't want to
187 * reference the other channels, as that will tell optimization passes that
188 * those other channels are used.
190 static inline unsigned
191 brw_swizzle_for_size(unsigned n
)
193 return brw_swizzle_for_mask((1 << n
) - 1);
197 * Converse of brw_swizzle_for_mask(). Returns the mask of components
198 * accessed by the specified swizzle \p swz.
200 static inline unsigned
201 brw_mask_for_swizzle(unsigned swz
)
203 return brw_apply_inv_swizzle_to_mask(swz
, ~0);
206 uint32_t brw_swizzle_immediate(enum brw_reg_type type
, uint32_t x
, unsigned swz
);
208 #define REG_SIZE (8*4)
210 /* These aren't hardware structs, just something useful for us to pass around:
212 * Align1 operation has a lot of control over input ranges. Used in
213 * WM programs to implement shaders decomposed into "channel serial"
214 * or "structure of array" form:
219 enum brw_reg_type type
:4;
220 enum brw_reg_file file
:3; /* :2 hardware format */
221 unsigned negate
:1; /* source only */
222 unsigned abs
:1; /* source only */
223 unsigned address_mode
:1; /* relative addressing, hopefully! */
225 unsigned subnr
:5; /* :1 in align16 */
233 unsigned swizzle
:8; /* src only, align16 only */
234 unsigned writemask
:4; /* dest only, align16 only */
235 int indirect_offset
:10; /* relative addressing offset */
236 unsigned vstride
:4; /* source only */
237 unsigned width
:3; /* src only, align1 only */
238 unsigned hstride
:2; /* align1 only */
252 brw_regs_equal(const struct brw_reg
*a
, const struct brw_reg
*b
)
254 return a
->bits
== b
->bits
&& a
->u64
== b
->u64
;
258 brw_regs_negative_equal(const struct brw_reg
*a
, const struct brw_reg
*b
)
260 if (a
->file
== IMM
) {
261 if (a
->bits
!= b
->bits
)
264 switch ((enum brw_reg_type
) a
->type
) {
265 case BRW_REGISTER_TYPE_UQ
:
266 case BRW_REGISTER_TYPE_Q
:
267 return a
->d64
== -b
->d64
;
268 case BRW_REGISTER_TYPE_DF
:
269 return a
->df
== -b
->df
;
270 case BRW_REGISTER_TYPE_UD
:
271 case BRW_REGISTER_TYPE_D
:
272 return a
->d
== -b
->d
;
273 case BRW_REGISTER_TYPE_F
:
274 return a
->f
== -b
->f
;
275 case BRW_REGISTER_TYPE_VF
:
276 /* It is tempting to treat 0 as a negation of 0 (and -0 as a negation
277 * of -0). There are occasions where 0 or -0 is used and the exact
278 * bit pattern is desired. At the very least, changing this to allow
279 * 0 as a negation of 0 causes some fp64 tests to fail on IVB.
281 return a
->ud
== (b
->ud
^ 0x80808080);
282 case BRW_REGISTER_TYPE_UW
:
283 case BRW_REGISTER_TYPE_W
:
284 case BRW_REGISTER_TYPE_UV
:
285 case BRW_REGISTER_TYPE_V
:
286 case BRW_REGISTER_TYPE_HF
:
287 /* FINISHME: Implement support for these types once there is
288 * something in the compiler that can generate them. Until then,
289 * they cannot be tested.
292 case BRW_REGISTER_TYPE_UB
:
293 case BRW_REGISTER_TYPE_B
:
294 case BRW_REGISTER_TYPE_NF
:
296 unreachable("not reached");
299 struct brw_reg tmp
= *a
;
301 tmp
.negate
= !tmp
.negate
;
303 return brw_regs_equal(&tmp
, b
);
307 struct brw_indirect
{
308 unsigned addr_subnr
:4;
314 static inline unsigned
315 type_sz(unsigned type
)
318 case BRW_REGISTER_TYPE_UQ
:
319 case BRW_REGISTER_TYPE_Q
:
320 case BRW_REGISTER_TYPE_DF
:
322 case BRW_REGISTER_TYPE_UD
:
323 case BRW_REGISTER_TYPE_D
:
324 case BRW_REGISTER_TYPE_F
:
325 case BRW_REGISTER_TYPE_VF
:
327 case BRW_REGISTER_TYPE_UW
:
328 case BRW_REGISTER_TYPE_W
:
329 case BRW_REGISTER_TYPE_UV
:
330 case BRW_REGISTER_TYPE_V
:
331 case BRW_REGISTER_TYPE_HF
:
333 case BRW_REGISTER_TYPE_UB
:
334 case BRW_REGISTER_TYPE_B
:
337 unreachable("not reached");
341 static inline enum brw_reg_type
342 get_exec_type(const enum brw_reg_type type
)
345 case BRW_REGISTER_TYPE_B
:
346 case BRW_REGISTER_TYPE_V
:
347 return BRW_REGISTER_TYPE_W
;
348 case BRW_REGISTER_TYPE_UB
:
349 case BRW_REGISTER_TYPE_UV
:
350 return BRW_REGISTER_TYPE_UW
;
351 case BRW_REGISTER_TYPE_VF
:
352 return BRW_REGISTER_TYPE_F
;
359 * Return an integer type of the requested size and signedness.
361 static inline enum brw_reg_type
362 brw_int_type(unsigned sz
, bool is_signed
)
366 return (is_signed
? BRW_REGISTER_TYPE_B
: BRW_REGISTER_TYPE_UB
);
368 return (is_signed
? BRW_REGISTER_TYPE_W
: BRW_REGISTER_TYPE_UW
);
370 return (is_signed
? BRW_REGISTER_TYPE_D
: BRW_REGISTER_TYPE_UD
);
372 return (is_signed
? BRW_REGISTER_TYPE_Q
: BRW_REGISTER_TYPE_UQ
);
374 unreachable("Not reached.");
379 type_is_unsigned_int(enum brw_reg_type tp
)
381 return tp
== BRW_REGISTER_TYPE_UB
||
382 tp
== BRW_REGISTER_TYPE_UW
||
383 tp
== BRW_REGISTER_TYPE_UD
||
384 tp
== BRW_REGISTER_TYPE_UQ
;
388 * Construct a brw_reg.
389 * \param file one of the BRW_x_REGISTER_FILE values
390 * \param nr register number/index
391 * \param subnr register sub number
392 * \param negate register negate modifier
393 * \param abs register abs modifier
394 * \param type one of BRW_REGISTER_TYPE_x
395 * \param vstride one of BRW_VERTICAL_STRIDE_x
396 * \param width one of BRW_WIDTH_x
397 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
398 * \param swizzle one of BRW_SWIZZLE_x
399 * \param writemask WRITEMASK_X/Y/Z/W bitfield
401 static inline struct brw_reg
402 brw_reg(enum brw_reg_file file
,
407 enum brw_reg_type type
,
415 if (file
== BRW_GENERAL_REGISTER_FILE
)
416 assert(nr
< BRW_MAX_GRF
);
417 else if (file
== BRW_ARCHITECTURE_REGISTER_FILE
)
418 assert(nr
<= BRW_ARF_TIMESTAMP
);
419 /* Asserting on the MRF register number requires to know the hardware gen
420 * (gen6 has 24 MRF registers), which we don't know here, so we assert
421 * for that in the generators and in brw_eu_emit.c
428 reg
.address_mode
= BRW_ADDRESS_DIRECT
;
430 reg
.subnr
= subnr
* type_sz(type
);
433 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
434 * set swizzle and writemask to W, as the lower bits of subnr will
435 * be lost when converted to align16. This is probably too much to
436 * keep track of as you'd want it adjusted by suboffset(), etc.
437 * Perhaps fix up when converting to align16?
439 reg
.swizzle
= swizzle
;
440 reg
.writemask
= writemask
;
441 reg
.indirect_offset
= 0;
442 reg
.vstride
= vstride
;
444 reg
.hstride
= hstride
;
449 /** Construct float[16] register */
450 static inline struct brw_reg
451 brw_vec16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
459 BRW_VERTICAL_STRIDE_16
,
461 BRW_HORIZONTAL_STRIDE_1
,
466 /** Construct float[8] register */
467 static inline struct brw_reg
468 brw_vec8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
476 BRW_VERTICAL_STRIDE_8
,
478 BRW_HORIZONTAL_STRIDE_1
,
483 /** Construct float[4] register */
484 static inline struct brw_reg
485 brw_vec4_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
493 BRW_VERTICAL_STRIDE_4
,
495 BRW_HORIZONTAL_STRIDE_1
,
500 /** Construct float[2] register */
501 static inline struct brw_reg
502 brw_vec2_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
510 BRW_VERTICAL_STRIDE_2
,
512 BRW_HORIZONTAL_STRIDE_1
,
517 /** Construct float[1] register */
518 static inline struct brw_reg
519 brw_vec1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
527 BRW_VERTICAL_STRIDE_0
,
529 BRW_HORIZONTAL_STRIDE_0
,
534 static inline struct brw_reg
535 brw_vecn_reg(unsigned width
, enum brw_reg_file file
,
536 unsigned nr
, unsigned subnr
)
540 return brw_vec1_reg(file
, nr
, subnr
);
542 return brw_vec2_reg(file
, nr
, subnr
);
544 return brw_vec4_reg(file
, nr
, subnr
);
546 return brw_vec8_reg(file
, nr
, subnr
);
548 return brw_vec16_reg(file
, nr
, subnr
);
550 unreachable("Invalid register width");
554 static inline struct brw_reg
555 retype(struct brw_reg reg
, enum brw_reg_type type
)
561 static inline struct brw_reg
562 firsthalf(struct brw_reg reg
)
567 static inline struct brw_reg
568 sechalf(struct brw_reg reg
)
575 static inline struct brw_reg
576 offset(struct brw_reg reg
, unsigned delta
)
583 static inline struct brw_reg
584 byte_offset(struct brw_reg reg
, unsigned bytes
)
586 unsigned newoffset
= reg
.nr
* REG_SIZE
+ reg
.subnr
+ bytes
;
587 reg
.nr
= newoffset
/ REG_SIZE
;
588 reg
.subnr
= newoffset
% REG_SIZE
;
592 static inline struct brw_reg
593 suboffset(struct brw_reg reg
, unsigned delta
)
595 return byte_offset(reg
, delta
* type_sz(reg
.type
));
598 /** Construct unsigned word[16] register */
599 static inline struct brw_reg
600 brw_uw16_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
602 return suboffset(retype(brw_vec16_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
605 /** Construct unsigned word[8] register */
606 static inline struct brw_reg
607 brw_uw8_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
609 return suboffset(retype(brw_vec8_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
612 /** Construct unsigned word[1] register */
613 static inline struct brw_reg
614 brw_uw1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
616 return suboffset(retype(brw_vec1_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
619 static inline struct brw_reg
620 brw_ud1_reg(enum brw_reg_file file
, unsigned nr
, unsigned subnr
)
622 return retype(brw_vec1_reg(file
, nr
, subnr
), BRW_REGISTER_TYPE_UD
);
625 static inline struct brw_reg
626 brw_imm_reg(enum brw_reg_type type
)
628 return brw_reg(BRW_IMMEDIATE_VALUE
,
634 BRW_VERTICAL_STRIDE_0
,
636 BRW_HORIZONTAL_STRIDE_0
,
641 /** Construct float immediate register */
642 static inline struct brw_reg
643 brw_imm_df(double df
)
645 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_DF
);
650 static inline struct brw_reg
651 brw_imm_u64(uint64_t u64
)
653 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UQ
);
658 static inline struct brw_reg
661 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_F
);
666 /** Construct int64_t immediate register */
667 static inline struct brw_reg
670 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_Q
);
675 /** Construct int64_t immediate register */
676 static inline struct brw_reg
677 brw_imm_uq(uint64_t uq
)
679 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UQ
);
684 /** Construct integer immediate register */
685 static inline struct brw_reg
688 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_D
);
693 /** Construct uint immediate register */
694 static inline struct brw_reg
695 brw_imm_ud(unsigned ud
)
697 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UD
);
702 /** Construct ushort immediate register */
703 static inline struct brw_reg
704 brw_imm_uw(uint16_t uw
)
706 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UW
);
707 imm
.ud
= uw
| (uw
<< 16);
711 /** Construct short immediate register */
712 static inline struct brw_reg
715 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_W
);
716 imm
.ud
= (uint16_t)w
| (uint32_t)(uint16_t)w
<< 16;
720 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
721 * numbers alias with _V and _VF below:
724 /** Construct vector of eight signed half-byte values */
725 static inline struct brw_reg
726 brw_imm_v(unsigned v
)
728 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_V
);
733 /** Construct vector of eight unsigned half-byte values */
734 static inline struct brw_reg
735 brw_imm_uv(unsigned uv
)
737 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UV
);
742 /** Construct vector of four 8-bit float values */
743 static inline struct brw_reg
744 brw_imm_vf(unsigned v
)
746 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
751 static inline struct brw_reg
752 brw_imm_vf4(unsigned v0
, unsigned v1
, unsigned v2
, unsigned v3
)
754 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
755 imm
.vstride
= BRW_VERTICAL_STRIDE_0
;
756 imm
.width
= BRW_WIDTH_4
;
757 imm
.hstride
= BRW_HORIZONTAL_STRIDE_1
;
758 imm
.ud
= ((v0
<< 0) | (v1
<< 8) | (v2
<< 16) | (v3
<< 24));
763 static inline struct brw_reg
764 brw_address(struct brw_reg reg
)
766 return brw_imm_uw(reg
.nr
* REG_SIZE
+ reg
.subnr
);
769 /** Construct float[1] general-purpose register */
770 static inline struct brw_reg
771 brw_vec1_grf(unsigned nr
, unsigned subnr
)
773 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
776 /** Construct float[2] general-purpose register */
777 static inline struct brw_reg
778 brw_vec2_grf(unsigned nr
, unsigned subnr
)
780 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
783 /** Construct float[4] general-purpose register */
784 static inline struct brw_reg
785 brw_vec4_grf(unsigned nr
, unsigned subnr
)
787 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
790 /** Construct float[8] general-purpose register */
791 static inline struct brw_reg
792 brw_vec8_grf(unsigned nr
, unsigned subnr
)
794 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
797 /** Construct float[16] general-purpose register */
798 static inline struct brw_reg
799 brw_vec16_grf(unsigned nr
, unsigned subnr
)
801 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
804 static inline struct brw_reg
805 brw_vecn_grf(unsigned width
, unsigned nr
, unsigned subnr
)
807 return brw_vecn_reg(width
, BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
811 static inline struct brw_reg
812 brw_uw8_grf(unsigned nr
, unsigned subnr
)
814 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
817 static inline struct brw_reg
818 brw_uw16_grf(unsigned nr
, unsigned subnr
)
820 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
824 /** Construct null register (usually used for setting condition codes) */
825 static inline struct brw_reg
828 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
831 static inline struct brw_reg
832 brw_null_vec(unsigned width
)
834 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
837 static inline struct brw_reg
838 brw_address_reg(unsigned subnr
)
840 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_ADDRESS
, subnr
);
843 static inline struct brw_reg
846 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_TDR
, 0);
849 /* If/else instructions break in align16 mode if writemask & swizzle
850 * aren't xyzw. This goes against the convention for other scalar
853 static inline struct brw_reg
856 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
861 BRW_REGISTER_TYPE_UD
,
862 BRW_VERTICAL_STRIDE_4
, /* ? */
864 BRW_HORIZONTAL_STRIDE_0
,
865 BRW_SWIZZLE_XYZW
, /* NOTE! */
866 WRITEMASK_XYZW
); /* NOTE! */
869 static inline struct brw_reg
870 brw_notification_reg(void)
872 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
873 BRW_ARF_NOTIFICATION_COUNT
,
877 BRW_REGISTER_TYPE_UD
,
878 BRW_VERTICAL_STRIDE_0
,
880 BRW_HORIZONTAL_STRIDE_0
,
885 static inline struct brw_reg
886 brw_cr0_reg(unsigned subnr
)
888 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_CONTROL
, subnr
);
891 static inline struct brw_reg
892 brw_sr0_reg(unsigned subnr
)
894 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_STATE
, subnr
);
897 static inline struct brw_reg
898 brw_acc_reg(unsigned width
)
900 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
,
901 BRW_ARF_ACCUMULATOR
, 0);
904 static inline struct brw_reg
905 brw_flag_reg(int reg
, int subreg
)
907 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
908 BRW_ARF_FLAG
+ reg
, subreg
);
911 static inline struct brw_reg
912 brw_flag_subreg(unsigned subreg
)
914 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
915 BRW_ARF_FLAG
+ subreg
/ 2, subreg
% 2);
919 * Return the mask register present in Gen4-5, or the related register present
920 * in Gen7.5 and later hardware referred to as "channel enable" register in
923 static inline struct brw_reg
924 brw_mask_reg(unsigned subnr
)
926 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_MASK
, subnr
);
929 static inline struct brw_reg
932 return brw_sr0_reg(3);
935 static inline struct brw_reg
938 return brw_sr0_reg(2);
941 static inline struct brw_reg
942 brw_message_reg(unsigned nr
)
944 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, nr
, 0);
947 static inline struct brw_reg
948 brw_uvec_mrf(unsigned width
, unsigned nr
, unsigned subnr
)
950 return retype(brw_vecn_reg(width
, BRW_MESSAGE_REGISTER_FILE
, nr
, subnr
),
951 BRW_REGISTER_TYPE_UD
);
954 /* This is almost always called with a numeric constant argument, so
955 * make things easy to evaluate at compile time:
957 static inline unsigned cvt(unsigned val
)
971 static inline struct brw_reg
972 stride(struct brw_reg reg
, unsigned vstride
, unsigned width
, unsigned hstride
)
974 reg
.vstride
= cvt(vstride
);
975 reg
.width
= cvt(width
) - 1;
976 reg
.hstride
= cvt(hstride
);
981 * Multiply the vertical and horizontal stride of a register by the given
984 static inline struct brw_reg
985 spread(struct brw_reg reg
, unsigned s
)
988 assert(_mesa_is_pow_two(s
));
991 reg
.hstride
+= cvt(s
) - 1;
994 reg
.vstride
+= cvt(s
) - 1;
998 return stride(reg
, 0, 1, 0);
1003 * Reinterpret each channel of register \p reg as a vector of values of the
1004 * given smaller type and take the i-th subcomponent from each.
1006 static inline struct brw_reg
1007 subscript(struct brw_reg reg
, enum brw_reg_type type
, unsigned i
)
1009 if (reg
.file
== IMM
)
1012 unsigned scale
= type_sz(reg
.type
) / type_sz(type
);
1013 assert(scale
>= 1 && i
< scale
);
1015 return suboffset(retype(spread(reg
, scale
), type
), i
);
1018 static inline struct brw_reg
1019 vec16(struct brw_reg reg
)
1021 return stride(reg
, 16,16,1);
1024 static inline struct brw_reg
1025 vec8(struct brw_reg reg
)
1027 return stride(reg
, 8,8,1);
1030 static inline struct brw_reg
1031 vec4(struct brw_reg reg
)
1033 return stride(reg
, 4,4,1);
1036 static inline struct brw_reg
1037 vec2(struct brw_reg reg
)
1039 return stride(reg
, 2,2,1);
1042 static inline struct brw_reg
1043 vec1(struct brw_reg reg
)
1045 return stride(reg
, 0,1,0);
1049 static inline struct brw_reg
1050 get_element(struct brw_reg reg
, unsigned elt
)
1052 return vec1(suboffset(reg
, elt
));
1055 static inline struct brw_reg
1056 get_element_ud(struct brw_reg reg
, unsigned elt
)
1058 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_UD
), elt
));
1061 static inline struct brw_reg
1062 get_element_d(struct brw_reg reg
, unsigned elt
)
1064 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_D
), elt
));
1067 static inline struct brw_reg
1068 brw_swizzle(struct brw_reg reg
, unsigned swz
)
1070 if (reg
.file
== BRW_IMMEDIATE_VALUE
)
1071 reg
.ud
= brw_swizzle_immediate(reg
.type
, reg
.ud
, swz
);
1073 reg
.swizzle
= brw_compose_swizzle(swz
, reg
.swizzle
);
1078 static inline struct brw_reg
1079 brw_writemask(struct brw_reg reg
, unsigned mask
)
1081 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
1082 reg
.writemask
&= mask
;
1086 static inline struct brw_reg
1087 brw_set_writemask(struct brw_reg reg
, unsigned mask
)
1089 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
1090 reg
.writemask
= mask
;
1094 static inline unsigned
1095 brw_writemask_for_size(unsigned n
)
1097 return (1 << n
) - 1;
1100 static inline unsigned
1101 brw_writemask_for_component_packing(unsigned n
, unsigned first_component
)
1103 assert(first_component
+ n
<= 4);
1104 return (((1 << n
) - 1) << first_component
);
1107 static inline struct brw_reg
1108 negate(struct brw_reg reg
)
1114 static inline struct brw_reg
1115 brw_abs(struct brw_reg reg
)
1122 /************************************************************************/
1124 static inline struct brw_reg
1125 brw_vec4_indirect(unsigned subnr
, int offset
)
1127 struct brw_reg reg
= brw_vec4_grf(0, 0);
1129 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1130 reg
.indirect_offset
= offset
;
1134 static inline struct brw_reg
1135 brw_vec1_indirect(unsigned subnr
, int offset
)
1137 struct brw_reg reg
= brw_vec1_grf(0, 0);
1139 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1140 reg
.indirect_offset
= offset
;
1144 static inline struct brw_reg
1145 brw_VxH_indirect(unsigned subnr
, int offset
)
1147 struct brw_reg reg
= brw_vec1_grf(0, 0);
1148 reg
.vstride
= BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
;
1150 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
1151 reg
.indirect_offset
= offset
;
1155 static inline struct brw_reg
1156 deref_4f(struct brw_indirect ptr
, int offset
)
1158 return brw_vec4_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1161 static inline struct brw_reg
1162 deref_1f(struct brw_indirect ptr
, int offset
)
1164 return brw_vec1_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
1167 static inline struct brw_reg
1168 deref_4b(struct brw_indirect ptr
, int offset
)
1170 return retype(deref_4f(ptr
, offset
), BRW_REGISTER_TYPE_B
);
1173 static inline struct brw_reg
1174 deref_1uw(struct brw_indirect ptr
, int offset
)
1176 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UW
);
1179 static inline struct brw_reg
1180 deref_1d(struct brw_indirect ptr
, int offset
)
1182 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_D
);
1185 static inline struct brw_reg
1186 deref_1ud(struct brw_indirect ptr
, int offset
)
1188 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UD
);
1191 static inline struct brw_reg
1192 get_addr_reg(struct brw_indirect ptr
)
1194 return brw_address_reg(ptr
.addr_subnr
);
1197 static inline struct brw_indirect
1198 brw_indirect_offset(struct brw_indirect ptr
, int offset
)
1200 ptr
.addr_offset
+= offset
;
1204 static inline struct brw_indirect
1205 brw_indirect(unsigned addr_subnr
, int offset
)
1207 struct brw_indirect ptr
;
1208 ptr
.addr_subnr
= addr_subnr
;
1209 ptr
.addr_offset
= offset
;
1215 region_matches(struct brw_reg reg
, enum brw_vertical_stride v
,
1216 enum brw_width w
, enum brw_horizontal_stride h
)
1218 return reg
.vstride
== v
&&
1223 #define has_scalar_region(reg) \
1224 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1225 BRW_HORIZONTAL_STRIDE_0)
1227 /* brw_packed_float.c */
1228 int brw_float_to_vf(float f
);
1229 float brw_vf_to_float(unsigned char vf
);