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/imports.h"
47 #include "main/compiler.h"
48 #include "main/macros.h"
49 #include "program/prog_instruction.h"
50 #include "brw_defines.h"
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 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_YZXW BRW_SWIZZLE4(1,2,0,3)
86 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
87 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
90 brw_is_single_value_swizzle(unsigned swiz
)
92 return (swiz
== BRW_SWIZZLE_XXXX
||
93 swiz
== BRW_SWIZZLE_YYYY
||
94 swiz
== BRW_SWIZZLE_ZZZZ
||
95 swiz
== BRW_SWIZZLE_WWWW
);
99 * Compute the swizzle obtained from the application of \p swz0 on the result
100 * of \p swz1. The argument ordering is expected to match function
103 static inline unsigned
104 brw_compose_swizzle(unsigned swz0
, unsigned swz1
)
107 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 0)),
108 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 1)),
109 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 2)),
110 BRW_GET_SWZ(swz1
, BRW_GET_SWZ(swz0
, 3)));
114 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
117 static inline unsigned
118 brw_apply_swizzle_to_mask(unsigned swz
, unsigned mask
)
122 for (unsigned i
= 0; i
< 4; i
++) {
123 if (mask
& (1 << BRW_GET_SWZ(swz
, i
)))
131 * Return the result of applying the inverse of swizzle \p swz to shuffle the
132 * bits of \p mask (AKA preimage). Useful to find out which components are
133 * read from a swizzled source given the instruction writemask.
135 static inline unsigned
136 brw_apply_inv_swizzle_to_mask(unsigned swz
, unsigned mask
)
140 for (unsigned i
= 0; i
< 4; i
++) {
142 result
|= 1 << BRW_GET_SWZ(swz
, i
);
149 * Construct an identity swizzle for the set of enabled channels given by \p
150 * mask. The result will only reference channels enabled in the provided \p
151 * mask, assuming that \p mask is non-zero. The constructed swizzle will
152 * satisfy the property that for any instruction OP and any mask:
154 * brw_OP(p, brw_writemask(dst, mask),
155 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
157 * will be equivalent to the same instruction without swizzle:
159 * brw_OP(p, brw_writemask(dst, mask), src);
161 static inline unsigned
162 brw_swizzle_for_mask(unsigned mask
)
164 unsigned last
= (mask
? ffs(mask
) - 1 : 0);
167 for (unsigned i
= 0; i
< 4; i
++)
168 last
= swz
[i
] = (mask
& (1 << i
) ? i
: last
);
170 return BRW_SWIZZLE4(swz
[0], swz
[1], swz
[2], swz
[3]);
174 * Construct an identity swizzle for the first \p n components of a vector.
175 * When only a subset of channels of a vec4 are used we don't want to
176 * reference the other channels, as that will tell optimization passes that
177 * those other channels are used.
179 static inline unsigned
180 brw_swizzle_for_size(unsigned n
)
182 return brw_swizzle_for_mask((1 << n
) - 1);
186 * Converse of brw_swizzle_for_mask(). Returns the mask of components
187 * accessed by the specified swizzle \p swz.
189 static inline unsigned
190 brw_mask_for_swizzle(unsigned swz
)
192 return brw_apply_inv_swizzle_to_mask(swz
, ~0);
195 enum PACKED brw_reg_type
{
196 BRW_REGISTER_TYPE_UD
= 0,
198 BRW_REGISTER_TYPE_UW
,
202 /** Non-immediates only: @{ */
203 BRW_REGISTER_TYPE_UB
,
207 /** Immediates only: @{ */
208 BRW_REGISTER_TYPE_UV
,
210 BRW_REGISTER_TYPE_VF
,
213 BRW_REGISTER_TYPE_DF
, /* Gen7+ (no immediates until Gen8+) */
216 BRW_REGISTER_TYPE_HF
,
217 BRW_REGISTER_TYPE_UQ
,
221 unsigned brw_reg_type_to_hw_type(const struct brw_context
*brw
,
222 enum brw_reg_type type
, unsigned file
);
223 const char *brw_reg_type_letters(unsigned brw_reg_type
);
225 #define REG_SIZE (8*4)
227 /* These aren't hardware structs, just something useful for us to pass around:
229 * Align1 operation has a lot of control over input ranges. Used in
230 * WM programs to implement shaders decomposed into "channel serial"
231 * or "structure of array" form:
234 enum brw_reg_type type
:4;
237 unsigned subnr
:5; /* :1 in align16 */
238 unsigned negate
:1; /* source only */
239 unsigned abs
:1; /* source only */
240 unsigned vstride
:4; /* source only */
241 unsigned width
:3; /* src only, align1 only */
242 unsigned hstride
:2; /* align1 only */
243 unsigned address_mode
:1; /* relative addressing, hopefully! */
248 unsigned swizzle
:8; /* src only, align16 only */
249 unsigned writemask
:4; /* dest only, align16 only */
250 int indirect_offset
:10; /* relative addressing offset */
251 unsigned pad1
:10; /* two dwords total */
261 struct brw_indirect
{
262 unsigned addr_subnr
:4;
269 type_sz(unsigned type
)
272 case BRW_REGISTER_TYPE_UQ
:
273 case BRW_REGISTER_TYPE_Q
:
275 case BRW_REGISTER_TYPE_UD
:
276 case BRW_REGISTER_TYPE_D
:
277 case BRW_REGISTER_TYPE_F
:
279 case BRW_REGISTER_TYPE_UW
:
280 case BRW_REGISTER_TYPE_W
:
282 case BRW_REGISTER_TYPE_UB
:
283 case BRW_REGISTER_TYPE_B
:
291 type_is_signed(unsigned type
)
294 case BRW_REGISTER_TYPE_D
:
295 case BRW_REGISTER_TYPE_W
:
296 case BRW_REGISTER_TYPE_F
:
297 case BRW_REGISTER_TYPE_B
:
298 case BRW_REGISTER_TYPE_V
:
299 case BRW_REGISTER_TYPE_VF
:
300 case BRW_REGISTER_TYPE_DF
:
301 case BRW_REGISTER_TYPE_HF
:
302 case BRW_REGISTER_TYPE_Q
:
305 case BRW_REGISTER_TYPE_UD
:
306 case BRW_REGISTER_TYPE_UW
:
307 case BRW_REGISTER_TYPE_UB
:
308 case BRW_REGISTER_TYPE_UV
:
309 case BRW_REGISTER_TYPE_UQ
:
313 unreachable("not reached");
318 * Construct a brw_reg.
319 * \param file one of the BRW_x_REGISTER_FILE values
320 * \param nr register number/index
321 * \param subnr register sub number
322 * \param negate register negate modifier
323 * \param abs register abs modifier
324 * \param type one of BRW_REGISTER_TYPE_x
325 * \param vstride one of BRW_VERTICAL_STRIDE_x
326 * \param width one of BRW_WIDTH_x
327 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
328 * \param swizzle one of BRW_SWIZZLE_x
329 * \param writemask WRITEMASK_X/Y/Z/W bitfield
331 static inline struct brw_reg
332 brw_reg(unsigned file
,
337 enum brw_reg_type type
,
345 if (file
== BRW_GENERAL_REGISTER_FILE
)
346 assert(nr
< BRW_MAX_GRF
);
347 else if (file
== BRW_MESSAGE_REGISTER_FILE
)
348 assert((nr
& ~(1 << 7)) < BRW_MAX_MRF
);
349 else if (file
== BRW_ARCHITECTURE_REGISTER_FILE
)
350 assert(nr
<= BRW_ARF_TIMESTAMP
);
355 reg
.subnr
= subnr
* type_sz(type
);
358 reg
.vstride
= vstride
;
360 reg
.hstride
= hstride
;
361 reg
.address_mode
= BRW_ADDRESS_DIRECT
;
364 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
365 * set swizzle and writemask to W, as the lower bits of subnr will
366 * be lost when converted to align16. This is probably too much to
367 * keep track of as you'd want it adjusted by suboffset(), etc.
368 * Perhaps fix up when converting to align16?
370 reg
.dw1
.bits
.swizzle
= swizzle
;
371 reg
.dw1
.bits
.writemask
= writemask
;
372 reg
.dw1
.bits
.indirect_offset
= 0;
373 reg
.dw1
.bits
.pad1
= 0;
377 /** Construct float[16] register */
378 static inline struct brw_reg
379 brw_vec16_reg(unsigned file
, unsigned nr
, unsigned subnr
)
387 BRW_VERTICAL_STRIDE_16
,
389 BRW_HORIZONTAL_STRIDE_1
,
394 /** Construct float[8] register */
395 static inline struct brw_reg
396 brw_vec8_reg(unsigned file
, unsigned nr
, unsigned subnr
)
404 BRW_VERTICAL_STRIDE_8
,
406 BRW_HORIZONTAL_STRIDE_1
,
411 /** Construct float[4] register */
412 static inline struct brw_reg
413 brw_vec4_reg(unsigned file
, unsigned nr
, unsigned subnr
)
421 BRW_VERTICAL_STRIDE_4
,
423 BRW_HORIZONTAL_STRIDE_1
,
428 /** Construct float[2] register */
429 static inline struct brw_reg
430 brw_vec2_reg(unsigned file
, unsigned nr
, unsigned subnr
)
438 BRW_VERTICAL_STRIDE_2
,
440 BRW_HORIZONTAL_STRIDE_1
,
445 /** Construct float[1] register */
446 static inline struct brw_reg
447 brw_vec1_reg(unsigned file
, unsigned nr
, unsigned subnr
)
455 BRW_VERTICAL_STRIDE_0
,
457 BRW_HORIZONTAL_STRIDE_0
,
462 static inline struct brw_reg
463 brw_vecn_reg(unsigned width
, unsigned file
, unsigned nr
, unsigned subnr
)
467 return brw_vec1_reg(file
, nr
, subnr
);
469 return brw_vec2_reg(file
, nr
, subnr
);
471 return brw_vec4_reg(file
, nr
, subnr
);
473 return brw_vec8_reg(file
, nr
, subnr
);
475 return brw_vec16_reg(file
, nr
, subnr
);
477 unreachable("Invalid register width");
481 static inline struct brw_reg
482 retype(struct brw_reg reg
, enum brw_reg_type type
)
488 static inline struct brw_reg
489 firsthalf(struct brw_reg reg
)
494 static inline struct brw_reg
495 sechalf(struct brw_reg reg
)
502 static inline struct brw_reg
503 suboffset(struct brw_reg reg
, unsigned delta
)
505 reg
.subnr
+= delta
* type_sz(reg
.type
);
510 static inline struct brw_reg
511 offset(struct brw_reg reg
, unsigned delta
)
518 static inline struct brw_reg
519 byte_offset(struct brw_reg reg
, unsigned bytes
)
521 unsigned newoffset
= reg
.nr
* REG_SIZE
+ reg
.subnr
+ bytes
;
522 reg
.nr
= newoffset
/ REG_SIZE
;
523 reg
.subnr
= newoffset
% REG_SIZE
;
528 /** Construct unsigned word[16] register */
529 static inline struct brw_reg
530 brw_uw16_reg(unsigned file
, unsigned nr
, unsigned subnr
)
532 return suboffset(retype(brw_vec16_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
535 /** Construct unsigned word[8] register */
536 static inline struct brw_reg
537 brw_uw8_reg(unsigned file
, unsigned nr
, unsigned subnr
)
539 return suboffset(retype(brw_vec8_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
542 /** Construct unsigned word[1] register */
543 static inline struct brw_reg
544 brw_uw1_reg(unsigned file
, unsigned nr
, unsigned subnr
)
546 return suboffset(retype(brw_vec1_reg(file
, nr
, 0), BRW_REGISTER_TYPE_UW
), subnr
);
549 static inline struct brw_reg
550 brw_imm_reg(enum brw_reg_type type
)
552 return brw_reg(BRW_IMMEDIATE_VALUE
,
558 BRW_VERTICAL_STRIDE_0
,
560 BRW_HORIZONTAL_STRIDE_0
,
565 /** Construct float immediate register */
566 static inline struct brw_reg
569 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_F
);
574 /** Construct integer immediate register */
575 static inline struct brw_reg
578 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_D
);
583 /** Construct uint immediate register */
584 static inline struct brw_reg
585 brw_imm_ud(unsigned ud
)
587 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UD
);
592 /** Construct ushort immediate register */
593 static inline struct brw_reg
594 brw_imm_uw(uint16_t uw
)
596 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_UW
);
597 imm
.dw1
.ud
= uw
| (uw
<< 16);
601 /** Construct short immediate register */
602 static inline struct brw_reg
605 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_W
);
606 imm
.dw1
.d
= w
| (w
<< 16);
610 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
611 * numbers alias with _V and _VF below:
614 /** Construct vector of eight signed half-byte values */
615 static inline struct brw_reg
616 brw_imm_v(unsigned v
)
618 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_V
);
619 imm
.vstride
= BRW_VERTICAL_STRIDE_0
;
620 imm
.width
= BRW_WIDTH_8
;
621 imm
.hstride
= BRW_HORIZONTAL_STRIDE_1
;
626 /** Construct vector of four 8-bit float values */
627 static inline struct brw_reg
628 brw_imm_vf(unsigned v
)
630 struct brw_reg imm
= brw_imm_reg(BRW_REGISTER_TYPE_VF
);
631 imm
.vstride
= BRW_VERTICAL_STRIDE_0
;
632 imm
.width
= BRW_WIDTH_4
;
633 imm
.hstride
= BRW_HORIZONTAL_STRIDE_1
;
639 * Convert an integer into a "restricted" 8-bit float, used in vector
640 * immediates. The 8-bit floating point format has a sign bit, an
641 * excess-3 3-bit exponent, and a 4-bit mantissa. All integer values
642 * from -31 to 31 can be represented exactly.
644 static inline uint8_t
650 return 1 << 7 | int_to_float8(-x
);
652 const unsigned exponent
= _mesa_logbase2(x
);
653 const unsigned mantissa
= (x
- (1 << exponent
)) << (4 - exponent
);
654 assert(exponent
<= 4);
655 return (exponent
+ 3) << 4 | mantissa
;
660 * Construct a floating-point packed vector immediate from its integer
661 * values. \sa int_to_float8()
663 static inline struct brw_reg
664 brw_imm_vf4(int v0
, int v1
, int v2
, int v3
)
666 return brw_imm_vf((int_to_float8(v0
) << 0) |
667 (int_to_float8(v1
) << 8) |
668 (int_to_float8(v2
) << 16) |
669 (int_to_float8(v3
) << 24));
673 static inline struct brw_reg
674 brw_address(struct brw_reg reg
)
676 return brw_imm_uw(reg
.nr
* REG_SIZE
+ reg
.subnr
);
679 /** Construct float[1] general-purpose register */
680 static inline struct brw_reg
681 brw_vec1_grf(unsigned nr
, unsigned subnr
)
683 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
686 /** Construct float[2] general-purpose register */
687 static inline struct brw_reg
688 brw_vec2_grf(unsigned nr
, unsigned subnr
)
690 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
693 /** Construct float[4] general-purpose register */
694 static inline struct brw_reg
695 brw_vec4_grf(unsigned nr
, unsigned subnr
)
697 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
700 /** Construct float[8] general-purpose register */
701 static inline struct brw_reg
702 brw_vec8_grf(unsigned nr
, unsigned subnr
)
704 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
708 static inline struct brw_reg
709 brw_uw8_grf(unsigned nr
, unsigned subnr
)
711 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
714 static inline struct brw_reg
715 brw_uw16_grf(unsigned nr
, unsigned subnr
)
717 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, nr
, subnr
);
721 /** Construct null register (usually used for setting condition codes) */
722 static inline struct brw_reg
725 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
728 static inline struct brw_reg
729 brw_null_vec(unsigned width
)
731 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_NULL
, 0);
734 static inline struct brw_reg
735 brw_address_reg(unsigned subnr
)
737 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_ADDRESS
, subnr
);
740 /* If/else instructions break in align16 mode if writemask & swizzle
741 * aren't xyzw. This goes against the convention for other scalar
744 static inline struct brw_reg
747 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
752 BRW_REGISTER_TYPE_UD
,
753 BRW_VERTICAL_STRIDE_4
, /* ? */
755 BRW_HORIZONTAL_STRIDE_0
,
756 BRW_SWIZZLE_XYZW
, /* NOTE! */
757 WRITEMASK_XYZW
); /* NOTE! */
760 static inline struct brw_reg
761 brw_acc_reg(unsigned width
)
763 return brw_vecn_reg(width
, BRW_ARCHITECTURE_REGISTER_FILE
,
764 BRW_ARF_ACCUMULATOR
, 0);
767 static inline struct brw_reg
768 brw_flag_reg(int reg
, int subreg
)
770 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
,
771 BRW_ARF_FLAG
+ reg
, subreg
);
775 static inline struct brw_reg
776 brw_mask_reg(unsigned subnr
)
778 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE
, BRW_ARF_MASK
, subnr
);
781 static inline struct brw_reg
782 brw_message_reg(unsigned nr
)
784 assert((nr
& ~(1 << 7)) < BRW_MAX_MRF
);
785 return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, nr
, 0);
788 static inline struct brw_reg
789 brw_uvec_mrf(unsigned width
, unsigned nr
, unsigned subnr
)
791 return retype(brw_vecn_reg(width
, BRW_MESSAGE_REGISTER_FILE
, nr
, subnr
),
792 BRW_REGISTER_TYPE_UD
);
795 /* This is almost always called with a numeric constant argument, so
796 * make things easy to evaluate at compile time:
798 static inline unsigned cvt(unsigned val
)
812 static inline struct brw_reg
813 stride(struct brw_reg reg
, unsigned vstride
, unsigned width
, unsigned hstride
)
815 reg
.vstride
= cvt(vstride
);
816 reg
.width
= cvt(width
) - 1;
817 reg
.hstride
= cvt(hstride
);
822 * Multiply the vertical and horizontal stride of a register by the given
825 static inline struct brw_reg
826 spread(struct brw_reg reg
, unsigned s
)
829 assert(is_power_of_two(s
));
832 reg
.hstride
+= cvt(s
) - 1;
835 reg
.vstride
+= cvt(s
) - 1;
839 return stride(reg
, 0, 1, 0);
843 static inline struct brw_reg
844 vec16(struct brw_reg reg
)
846 return stride(reg
, 16,16,1);
849 static inline struct brw_reg
850 vec8(struct brw_reg reg
)
852 return stride(reg
, 8,8,1);
855 static inline struct brw_reg
856 vec4(struct brw_reg reg
)
858 return stride(reg
, 4,4,1);
861 static inline struct brw_reg
862 vec2(struct brw_reg reg
)
864 return stride(reg
, 2,2,1);
867 static inline struct brw_reg
868 vec1(struct brw_reg reg
)
870 return stride(reg
, 0,1,0);
874 static inline struct brw_reg
875 get_element(struct brw_reg reg
, unsigned elt
)
877 return vec1(suboffset(reg
, elt
));
880 static inline struct brw_reg
881 get_element_ud(struct brw_reg reg
, unsigned elt
)
883 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_UD
), elt
));
886 static inline struct brw_reg
887 get_element_d(struct brw_reg reg
, unsigned elt
)
889 return vec1(suboffset(retype(reg
, BRW_REGISTER_TYPE_D
), elt
));
893 static inline struct brw_reg
894 brw_swizzle(struct brw_reg reg
, unsigned x
, unsigned y
, unsigned z
, unsigned w
)
896 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
898 reg
.dw1
.bits
.swizzle
= BRW_SWIZZLE4(BRW_GET_SWZ(reg
.dw1
.bits
.swizzle
, x
),
899 BRW_GET_SWZ(reg
.dw1
.bits
.swizzle
, y
),
900 BRW_GET_SWZ(reg
.dw1
.bits
.swizzle
, z
),
901 BRW_GET_SWZ(reg
.dw1
.bits
.swizzle
, w
));
906 static inline struct brw_reg
907 brw_swizzle1(struct brw_reg reg
, unsigned x
)
909 return brw_swizzle(reg
, x
, x
, x
, x
);
912 static inline struct brw_reg
913 brw_writemask(struct brw_reg reg
, unsigned mask
)
915 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
916 reg
.dw1
.bits
.writemask
&= mask
;
920 static inline struct brw_reg
921 brw_set_writemask(struct brw_reg reg
, unsigned mask
)
923 assert(reg
.file
!= BRW_IMMEDIATE_VALUE
);
924 reg
.dw1
.bits
.writemask
= mask
;
928 static inline struct brw_reg
929 negate(struct brw_reg reg
)
935 static inline struct brw_reg
936 brw_abs(struct brw_reg reg
)
943 /************************************************************************/
945 static inline struct brw_reg
946 brw_vec4_indirect(unsigned subnr
, int offset
)
948 struct brw_reg reg
= brw_vec4_grf(0, 0);
950 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
951 reg
.dw1
.bits
.indirect_offset
= offset
;
955 static inline struct brw_reg
956 brw_vec1_indirect(unsigned subnr
, int offset
)
958 struct brw_reg reg
= brw_vec1_grf(0, 0);
960 reg
.address_mode
= BRW_ADDRESS_REGISTER_INDIRECT_REGISTER
;
961 reg
.dw1
.bits
.indirect_offset
= offset
;
965 static inline struct brw_reg
966 deref_4f(struct brw_indirect ptr
, int offset
)
968 return brw_vec4_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
971 static inline struct brw_reg
972 deref_1f(struct brw_indirect ptr
, int offset
)
974 return brw_vec1_indirect(ptr
.addr_subnr
, ptr
.addr_offset
+ offset
);
977 static inline struct brw_reg
978 deref_4b(struct brw_indirect ptr
, int offset
)
980 return retype(deref_4f(ptr
, offset
), BRW_REGISTER_TYPE_B
);
983 static inline struct brw_reg
984 deref_1uw(struct brw_indirect ptr
, int offset
)
986 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UW
);
989 static inline struct brw_reg
990 deref_1d(struct brw_indirect ptr
, int offset
)
992 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_D
);
995 static inline struct brw_reg
996 deref_1ud(struct brw_indirect ptr
, int offset
)
998 return retype(deref_1f(ptr
, offset
), BRW_REGISTER_TYPE_UD
);
1001 static inline struct brw_reg
1002 get_addr_reg(struct brw_indirect ptr
)
1004 return brw_address_reg(ptr
.addr_subnr
);
1007 static inline struct brw_indirect
1008 brw_indirect_offset(struct brw_indirect ptr
, int offset
)
1010 ptr
.addr_offset
+= offset
;
1014 static inline struct brw_indirect
1015 brw_indirect(unsigned addr_subnr
, int offset
)
1017 struct brw_indirect ptr
;
1018 ptr
.addr_subnr
= addr_subnr
;
1019 ptr
.addr_offset
= offset
;
1025 region_matches(struct brw_reg reg
, enum brw_vertical_stride v
,
1026 enum brw_width w
, enum brw_horizontal_stride h
)
1028 return reg
.vstride
== v
&&
1033 #define has_scalar_region(reg) \
1034 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1035 BRW_HORIZONTAL_STRIDE_0)
1037 /* brw_packed_float.c */
1038 int brw_float_to_vf(float f
);
1039 float brw_vf_to_float(unsigned char vf
);