1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics 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 <keithw@vmware.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 "util/compiler.h"
47 #include "util/glheader.h"
48 #include "util/macros.h"
49 #include "util/rounding.h"
50 #include "util/u_math.h"
51 #include "brw_eu_defines.h"
52 #include "brw_reg_type.h"
53
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57
58 struct intel_device_info;
59
60 /** Size of general purpose register space in REG_SIZE units */
61 #define BRW_MAX_GRF 128
62 #define XE2_MAX_GRF 256
63
64 /**
65 * BRW hardware swizzles.
66 * Only defines XYZW to ensure it can be contained in 2 bits
67 */
68 #define BRW_SWIZZLE_X 0
69 #define BRW_SWIZZLE_Y 1
70 #define BRW_SWIZZLE_Z 2
71 #define BRW_SWIZZLE_W 3
72
73 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
74 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
75
76 #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
77 #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
78 #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
79 #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
80 #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
81 #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
82 #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
83 #define BRW_SWIZZLE_YXYX BRW_SWIZZLE4(1,0,1,0)
84 #define BRW_SWIZZLE_XZXZ BRW_SWIZZLE4(0,2,0,2)
85 #define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
86 #define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
87 #define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
88 #define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
89 #define BRW_SWIZZLE_WZWZ BRW_SWIZZLE4(3,2,3,2)
90 #define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
91 #define BRW_SWIZZLE_XXZZ BRW_SWIZZLE4(0,0,2,2)
92 #define BRW_SWIZZLE_YYWW BRW_SWIZZLE4(1,1,3,3)
93 #define BRW_SWIZZLE_YXWZ BRW_SWIZZLE4(1,0,3,2)
94
95 #define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
96 #define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
97
98 static inline bool
brw_is_single_value_swizzle(unsigned swiz)99 brw_is_single_value_swizzle(unsigned swiz)
100 {
101 return (swiz == BRW_SWIZZLE_XXXX ||
102 swiz == BRW_SWIZZLE_YYYY ||
103 swiz == BRW_SWIZZLE_ZZZZ ||
104 swiz == BRW_SWIZZLE_WWWW);
105 }
106
107 /**
108 * Compute the swizzle obtained from the application of \p swz0 on the result
109 * of \p swz1. The argument ordering is expected to match function
110 * composition.
111 */
112 static inline unsigned
brw_compose_swizzle(unsigned swz0,unsigned swz1)113 brw_compose_swizzle(unsigned swz0, unsigned swz1)
114 {
115 return BRW_SWIZZLE4(
116 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)),
117 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)),
118 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)),
119 BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3)));
120 }
121
122 /**
123 * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
124 * (AKA image).
125 */
126 static inline unsigned
brw_apply_swizzle_to_mask(unsigned swz,unsigned mask)127 brw_apply_swizzle_to_mask(unsigned swz, unsigned mask)
128 {
129 unsigned result = 0;
130
131 for (unsigned i = 0; i < 4; i++) {
132 if (mask & (1 << BRW_GET_SWZ(swz, i)))
133 result |= 1 << i;
134 }
135
136 return result;
137 }
138
139 /**
140 * Return the result of applying the inverse of swizzle \p swz to shuffle the
141 * bits of \p mask (AKA preimage). Useful to find out which components are
142 * read from a swizzled source given the instruction writemask.
143 */
144 static inline unsigned
brw_apply_inv_swizzle_to_mask(unsigned swz,unsigned mask)145 brw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask)
146 {
147 unsigned result = 0;
148
149 for (unsigned i = 0; i < 4; i++) {
150 if (mask & (1 << i))
151 result |= 1 << BRW_GET_SWZ(swz, i);
152 }
153
154 return result;
155 }
156
157 /**
158 * Construct an identity swizzle for the set of enabled channels given by \p
159 * mask. The result will only reference channels enabled in the provided \p
160 * mask, assuming that \p mask is non-zero. The constructed swizzle will
161 * satisfy the property that for any instruction OP and any mask:
162 *
163 * brw_OP(p, brw_writemask(dst, mask),
164 * brw_swizzle(src, brw_swizzle_for_mask(mask)));
165 *
166 * will be equivalent to the same instruction without swizzle:
167 *
168 * brw_OP(p, brw_writemask(dst, mask), src);
169 */
170 static inline unsigned
brw_swizzle_for_mask(unsigned mask)171 brw_swizzle_for_mask(unsigned mask)
172 {
173 unsigned last = (mask ? ffs(mask) - 1 : 0);
174 unsigned swz[4];
175
176 for (unsigned i = 0; i < 4; i++)
177 last = swz[i] = (mask & (1 << i) ? i : last);
178
179 return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
180 }
181
182 /**
183 * Construct an identity swizzle for the first \p n components of a vector.
184 * When only a subset of channels of a vec4 are used we don't want to
185 * reference the other channels, as that will tell optimization passes that
186 * those other channels are used.
187 */
188 static inline unsigned
brw_swizzle_for_size(unsigned n)189 brw_swizzle_for_size(unsigned n)
190 {
191 return brw_swizzle_for_mask((1 << n) - 1);
192 }
193
194 /**
195 * Converse of brw_swizzle_for_mask(). Returns the mask of components
196 * accessed by the specified swizzle \p swz.
197 */
198 static inline unsigned
brw_mask_for_swizzle(unsigned swz)199 brw_mask_for_swizzle(unsigned swz)
200 {
201 return brw_apply_inv_swizzle_to_mask(swz, ~0);
202 }
203
204 uint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz);
205
206 #define REG_SIZE (8*4)
207
208 /* These aren't hardware structs, just something useful for us to pass around:
209 *
210 * Align1 operation has a lot of control over input ranges. Used in
211 * WM programs to implement shaders decomposed into "channel serial"
212 * or "structure of array" form:
213 */
214 struct brw_reg {
215 union {
216 struct {
217 enum brw_reg_type type:4;
218 enum brw_reg_file file:3; /* :2 hardware format */
219 unsigned negate:1; /* source only */
220 unsigned abs:1; /* source only */
221 unsigned address_mode:1; /* relative addressing, hopefully! */
222 unsigned pad0:17;
223 unsigned subnr:5; /* :1 in align16 */
224 };
225 uint32_t bits;
226 };
227
228 union {
229 struct {
230 unsigned nr;
231 unsigned swizzle:8; /* src only, align16 only */
232 unsigned writemask:4; /* dest only, align16 only */
233 int indirect_offset:10; /* relative addressing offset */
234 unsigned vstride:4; /* source only */
235 unsigned width:3; /* src only, align1 only */
236 unsigned hstride:2; /* align1 only */
237 unsigned pad1:1;
238 };
239
240 double df;
241 uint64_t u64;
242 int64_t d64;
243 float f;
244 int d;
245 unsigned ud;
246 };
247 };
248
249 static inline unsigned
phys_nr(const struct intel_device_info * devinfo,const struct brw_reg reg)250 phys_nr(const struct intel_device_info *devinfo, const struct brw_reg reg)
251 {
252 if (devinfo->ver >= 20) {
253 if (reg.file == BRW_GENERAL_REGISTER_FILE)
254 return reg.nr / 2;
255 else if (reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
256 reg.nr >= BRW_ARF_ACCUMULATOR &&
257 reg.nr < BRW_ARF_FLAG)
258 return BRW_ARF_ACCUMULATOR + (reg.nr - BRW_ARF_ACCUMULATOR) / 2;
259 else
260 return reg.nr;
261 } else {
262 return reg.nr;
263 }
264 }
265
266 static inline unsigned
phys_subnr(const struct intel_device_info * devinfo,const struct brw_reg reg)267 phys_subnr(const struct intel_device_info *devinfo, const struct brw_reg reg)
268 {
269 if (devinfo->ver >= 20) {
270 if (reg.file == BRW_GENERAL_REGISTER_FILE ||
271 (reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
272 reg.nr >= BRW_ARF_ACCUMULATOR &&
273 reg.nr < BRW_ARF_FLAG))
274 return (reg.nr & 1) * REG_SIZE + reg.subnr;
275 else
276 return reg.subnr;
277 } else {
278 return reg.subnr;
279 }
280 }
281
282 static inline bool
brw_regs_equal(const struct brw_reg * a,const struct brw_reg * b)283 brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
284 {
285 return a->bits == b->bits && a->u64 == b->u64;
286 }
287
288 static inline bool
brw_regs_negative_equal(const struct brw_reg * a,const struct brw_reg * b)289 brw_regs_negative_equal(const struct brw_reg *a, const struct brw_reg *b)
290 {
291 if (a->file == IMM) {
292 if (a->bits != b->bits)
293 return false;
294
295 switch ((enum brw_reg_type) a->type) {
296 case BRW_REGISTER_TYPE_UQ:
297 case BRW_REGISTER_TYPE_Q:
298 return a->d64 == -b->d64;
299 case BRW_REGISTER_TYPE_DF:
300 return a->df == -b->df;
301 case BRW_REGISTER_TYPE_UD:
302 case BRW_REGISTER_TYPE_D:
303 return a->d == -b->d;
304 case BRW_REGISTER_TYPE_F:
305 return a->f == -b->f;
306 case BRW_REGISTER_TYPE_VF:
307 /* It is tempting to treat 0 as a negation of 0 (and -0 as a negation
308 * of -0). There are occasions where 0 or -0 is used and the exact
309 * bit pattern is desired. At the very least, changing this to allow
310 * 0 as a negation of 0 causes some fp64 tests to fail on IVB.
311 */
312 return a->ud == (b->ud ^ 0x80808080);
313 case BRW_REGISTER_TYPE_UW:
314 case BRW_REGISTER_TYPE_W:
315 case BRW_REGISTER_TYPE_UV:
316 case BRW_REGISTER_TYPE_V:
317 case BRW_REGISTER_TYPE_HF:
318 /* FINISHME: Implement support for these types once there is
319 * something in the compiler that can generate them. Until then,
320 * they cannot be tested.
321 */
322 return false;
323 case BRW_REGISTER_TYPE_UB:
324 case BRW_REGISTER_TYPE_B:
325 case BRW_REGISTER_TYPE_NF:
326 default:
327 unreachable("not reached");
328 }
329 } else {
330 struct brw_reg tmp = *a;
331
332 tmp.negate = !tmp.negate;
333
334 return brw_regs_equal(&tmp, b);
335 }
336 }
337
338 struct brw_indirect {
339 unsigned addr_subnr:4;
340 int addr_offset:10;
341 unsigned pad:18;
342 };
343
344
345 static inline unsigned
type_sz(unsigned type)346 type_sz(unsigned type)
347 {
348 switch(type) {
349 case BRW_REGISTER_TYPE_UQ:
350 case BRW_REGISTER_TYPE_Q:
351 case BRW_REGISTER_TYPE_DF:
352 case BRW_REGISTER_TYPE_NF:
353 return 8;
354 case BRW_REGISTER_TYPE_UD:
355 case BRW_REGISTER_TYPE_D:
356 case BRW_REGISTER_TYPE_F:
357 case BRW_REGISTER_TYPE_VF:
358 return 4;
359 case BRW_REGISTER_TYPE_UW:
360 case BRW_REGISTER_TYPE_W:
361 case BRW_REGISTER_TYPE_HF:
362 /* [U]V components are 4-bit, but HW unpacks them to 16-bit (2 bytes) */
363 case BRW_REGISTER_TYPE_UV:
364 case BRW_REGISTER_TYPE_V:
365 return 2;
366 case BRW_REGISTER_TYPE_UB:
367 case BRW_REGISTER_TYPE_B:
368 return 1;
369 default:
370 unreachable("not reached");
371 }
372 }
373
374 static inline enum brw_reg_type
get_exec_type(const enum brw_reg_type type)375 get_exec_type(const enum brw_reg_type type)
376 {
377 switch (type) {
378 case BRW_REGISTER_TYPE_B:
379 case BRW_REGISTER_TYPE_V:
380 return BRW_REGISTER_TYPE_W;
381 case BRW_REGISTER_TYPE_UB:
382 case BRW_REGISTER_TYPE_UV:
383 return BRW_REGISTER_TYPE_UW;
384 case BRW_REGISTER_TYPE_VF:
385 return BRW_REGISTER_TYPE_F;
386 default:
387 return type;
388 }
389 }
390
391 /**
392 * Return an integer type of the requested size and signedness.
393 */
394 static inline enum brw_reg_type
brw_int_type(unsigned sz,bool is_signed)395 brw_int_type(unsigned sz, bool is_signed)
396 {
397 switch (sz) {
398 case 1:
399 return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
400 case 2:
401 return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
402 case 4:
403 return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
404 case 8:
405 return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
406 default:
407 unreachable("Not reached.");
408 }
409 }
410
411 /**
412 * Construct a brw_reg.
413 * \param file one of the BRW_x_REGISTER_FILE values
414 * \param nr register number/index
415 * \param subnr register sub number
416 * \param negate register negate modifier
417 * \param abs register abs modifier
418 * \param type one of BRW_REGISTER_TYPE_x
419 * \param vstride one of BRW_VERTICAL_STRIDE_x
420 * \param width one of BRW_WIDTH_x
421 * \param hstride one of BRW_HORIZONTAL_STRIDE_x
422 * \param swizzle one of BRW_SWIZZLE_x
423 * \param writemask WRITEMASK_X/Y/Z/W bitfield
424 */
425 static inline struct brw_reg
brw_reg(enum brw_reg_file file,unsigned nr,unsigned subnr,unsigned negate,unsigned abs,enum brw_reg_type type,unsigned vstride,unsigned width,unsigned hstride,unsigned swizzle,unsigned writemask)426 brw_reg(enum brw_reg_file file,
427 unsigned nr,
428 unsigned subnr,
429 unsigned negate,
430 unsigned abs,
431 enum brw_reg_type type,
432 unsigned vstride,
433 unsigned width,
434 unsigned hstride,
435 unsigned swizzle,
436 unsigned writemask)
437 {
438 struct brw_reg reg;
439 if (file == BRW_GENERAL_REGISTER_FILE)
440 assert(nr < XE2_MAX_GRF);
441 else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
442 assert(nr <= BRW_ARF_TIMESTAMP);
443
444 reg.type = type;
445 reg.file = file;
446 reg.negate = negate;
447 reg.abs = abs;
448 reg.address_mode = BRW_ADDRESS_DIRECT;
449 reg.pad0 = 0;
450 reg.subnr = subnr * type_sz(type);
451 reg.nr = nr;
452
453 /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
454 * set swizzle and writemask to W, as the lower bits of subnr will
455 * be lost when converted to align16. This is probably too much to
456 * keep track of as you'd want it adjusted by suboffset(), etc.
457 * Perhaps fix up when converting to align16?
458 */
459 reg.swizzle = swizzle;
460 reg.writemask = writemask;
461 reg.indirect_offset = 0;
462 reg.vstride = vstride;
463 reg.width = width;
464 reg.hstride = hstride;
465 reg.pad1 = 0;
466 return reg;
467 }
468
469 /** Construct float[16] register */
470 static inline struct brw_reg
brw_vec16_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)471 brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
472 {
473 return brw_reg(file,
474 nr,
475 subnr,
476 0,
477 0,
478 BRW_REGISTER_TYPE_F,
479 BRW_VERTICAL_STRIDE_16,
480 BRW_WIDTH_16,
481 BRW_HORIZONTAL_STRIDE_1,
482 BRW_SWIZZLE_XYZW,
483 WRITEMASK_XYZW);
484 }
485
486 /** Construct float[8] register */
487 static inline struct brw_reg
brw_vec8_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)488 brw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
489 {
490 return brw_reg(file,
491 nr,
492 subnr,
493 0,
494 0,
495 BRW_REGISTER_TYPE_F,
496 BRW_VERTICAL_STRIDE_8,
497 BRW_WIDTH_8,
498 BRW_HORIZONTAL_STRIDE_1,
499 BRW_SWIZZLE_XYZW,
500 WRITEMASK_XYZW);
501 }
502
503 /** Construct float[4] register */
504 static inline struct brw_reg
brw_vec4_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)505 brw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
506 {
507 return brw_reg(file,
508 nr,
509 subnr,
510 0,
511 0,
512 BRW_REGISTER_TYPE_F,
513 BRW_VERTICAL_STRIDE_4,
514 BRW_WIDTH_4,
515 BRW_HORIZONTAL_STRIDE_1,
516 BRW_SWIZZLE_XYZW,
517 WRITEMASK_XYZW);
518 }
519
520 /** Construct float[2] register */
521 static inline struct brw_reg
brw_vec2_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)522 brw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
523 {
524 return brw_reg(file,
525 nr,
526 subnr,
527 0,
528 0,
529 BRW_REGISTER_TYPE_F,
530 BRW_VERTICAL_STRIDE_2,
531 BRW_WIDTH_2,
532 BRW_HORIZONTAL_STRIDE_1,
533 BRW_SWIZZLE_XYXY,
534 WRITEMASK_XY);
535 }
536
537 /** Construct float[1] register */
538 static inline struct brw_reg
brw_vec1_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)539 brw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
540 {
541 return brw_reg(file,
542 nr,
543 subnr,
544 0,
545 0,
546 BRW_REGISTER_TYPE_F,
547 BRW_VERTICAL_STRIDE_0,
548 BRW_WIDTH_1,
549 BRW_HORIZONTAL_STRIDE_0,
550 BRW_SWIZZLE_XXXX,
551 WRITEMASK_X);
552 }
553
554 static inline struct brw_reg
brw_vecn_reg(unsigned width,enum brw_reg_file file,unsigned nr,unsigned subnr)555 brw_vecn_reg(unsigned width, enum brw_reg_file file,
556 unsigned nr, unsigned subnr)
557 {
558 switch (width) {
559 case 1:
560 return brw_vec1_reg(file, nr, subnr);
561 case 2:
562 return brw_vec2_reg(file, nr, subnr);
563 case 4:
564 return brw_vec4_reg(file, nr, subnr);
565 case 8:
566 return brw_vec8_reg(file, nr, subnr);
567 case 16:
568 return brw_vec16_reg(file, nr, subnr);
569 default:
570 unreachable("Invalid register width");
571 }
572 }
573
574 static inline struct brw_reg
retype(struct brw_reg reg,enum brw_reg_type type)575 retype(struct brw_reg reg, enum brw_reg_type type)
576 {
577 reg.type = type;
578 return reg;
579 }
580
581 static inline struct brw_reg
firsthalf(struct brw_reg reg)582 firsthalf(struct brw_reg reg)
583 {
584 return reg;
585 }
586
587 static inline struct brw_reg
sechalf(struct brw_reg reg)588 sechalf(struct brw_reg reg)
589 {
590 if (reg.vstride)
591 reg.nr++;
592 return reg;
593 }
594
595 static inline struct brw_reg
offset(struct brw_reg reg,unsigned delta)596 offset(struct brw_reg reg, unsigned delta)
597 {
598 reg.nr += delta;
599 return reg;
600 }
601
602
603 static inline struct brw_reg
byte_offset(struct brw_reg reg,unsigned bytes)604 byte_offset(struct brw_reg reg, unsigned bytes)
605 {
606 unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
607 reg.nr = newoffset / REG_SIZE;
608 reg.subnr = newoffset % REG_SIZE;
609 return reg;
610 }
611
612 static inline struct brw_reg
suboffset(struct brw_reg reg,unsigned delta)613 suboffset(struct brw_reg reg, unsigned delta)
614 {
615 return byte_offset(reg, delta * type_sz(reg.type));
616 }
617
618 /** Construct unsigned word[16] register */
619 static inline struct brw_reg
brw_uw16_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)620 brw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
621 {
622 return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
623 }
624
625 /** Construct unsigned word[8] register */
626 static inline struct brw_reg
brw_uw8_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)627 brw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
628 {
629 return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
630 }
631
632 /** Construct unsigned word[1] register */
633 static inline struct brw_reg
brw_uw1_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)634 brw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
635 {
636 return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
637 }
638
639 static inline struct brw_reg
brw_ud8_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)640 brw_ud8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
641 {
642 return retype(brw_vec8_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
643 }
644
645 static inline struct brw_reg
brw_ud1_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)646 brw_ud1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
647 {
648 return retype(brw_vec1_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
649 }
650
651 static inline struct brw_reg
brw_imm_reg(enum brw_reg_type type)652 brw_imm_reg(enum brw_reg_type type)
653 {
654 return brw_reg(BRW_IMMEDIATE_VALUE,
655 0,
656 0,
657 0,
658 0,
659 type,
660 BRW_VERTICAL_STRIDE_0,
661 BRW_WIDTH_1,
662 BRW_HORIZONTAL_STRIDE_0,
663 0,
664 0);
665 }
666
667 /** Construct float immediate register */
668 static inline struct brw_reg
brw_imm_df(double df)669 brw_imm_df(double df)
670 {
671 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
672 imm.df = df;
673 return imm;
674 }
675
676 static inline struct brw_reg
brw_imm_u64(uint64_t u64)677 brw_imm_u64(uint64_t u64)
678 {
679 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
680 imm.u64 = u64;
681 return imm;
682 }
683
684 static inline struct brw_reg
brw_imm_f(float f)685 brw_imm_f(float f)
686 {
687 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
688 imm.f = f;
689 return imm;
690 }
691
692 /** Construct int64_t immediate register */
693 static inline struct brw_reg
brw_imm_q(int64_t q)694 brw_imm_q(int64_t q)
695 {
696 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_Q);
697 imm.d64 = q;
698 return imm;
699 }
700
701 /** Construct int64_t immediate register */
702 static inline struct brw_reg
brw_imm_uq(uint64_t uq)703 brw_imm_uq(uint64_t uq)
704 {
705 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
706 imm.u64 = uq;
707 return imm;
708 }
709
710 /** Construct integer immediate register */
711 static inline struct brw_reg
brw_imm_d(int d)712 brw_imm_d(int d)
713 {
714 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
715 imm.d = d;
716 return imm;
717 }
718
719 /** Construct uint immediate register */
720 static inline struct brw_reg
brw_imm_ud(unsigned ud)721 brw_imm_ud(unsigned ud)
722 {
723 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
724 imm.ud = ud;
725 return imm;
726 }
727
728 /** Construct ushort immediate register */
729 static inline struct brw_reg
brw_imm_uw(uint16_t uw)730 brw_imm_uw(uint16_t uw)
731 {
732 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
733 imm.ud = uw | (uw << 16);
734 return imm;
735 }
736
737 /** Construct short immediate register */
738 static inline struct brw_reg
brw_imm_w(int16_t w)739 brw_imm_w(int16_t w)
740 {
741 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
742 imm.ud = (uint16_t)w | (uint32_t)(uint16_t)w << 16;
743 return imm;
744 }
745
746 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
747 * numbers alias with _V and _VF below:
748 */
749
750 /** Construct vector of eight signed half-byte values */
751 static inline struct brw_reg
brw_imm_v(unsigned v)752 brw_imm_v(unsigned v)
753 {
754 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
755 imm.ud = v;
756 return imm;
757 }
758
759 /** Construct vector of eight unsigned half-byte values */
760 static inline struct brw_reg
brw_imm_uv(unsigned uv)761 brw_imm_uv(unsigned uv)
762 {
763 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
764 imm.ud = uv;
765 return imm;
766 }
767
768 /** Construct vector of four 8-bit float values */
769 static inline struct brw_reg
brw_imm_vf(unsigned v)770 brw_imm_vf(unsigned v)
771 {
772 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
773 imm.ud = v;
774 return imm;
775 }
776
777 static inline struct brw_reg
brw_imm_vf4(unsigned v0,unsigned v1,unsigned v2,unsigned v3)778 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
779 {
780 struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
781 imm.vstride = BRW_VERTICAL_STRIDE_0;
782 imm.width = BRW_WIDTH_4;
783 imm.hstride = BRW_HORIZONTAL_STRIDE_1;
784 imm.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
785 return imm;
786 }
787
788
789 static inline struct brw_reg
brw_address(struct brw_reg reg)790 brw_address(struct brw_reg reg)
791 {
792 return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
793 }
794
795 /** Construct float[1] general-purpose register */
796 static inline struct brw_reg
brw_vec1_grf(unsigned nr,unsigned subnr)797 brw_vec1_grf(unsigned nr, unsigned subnr)
798 {
799 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
800 }
801
802 static inline struct brw_reg
xe2_vec1_grf(unsigned nr,unsigned subnr)803 xe2_vec1_grf(unsigned nr, unsigned subnr)
804 {
805 return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
806 }
807
808 /** Construct float[2] general-purpose register */
809 static inline struct brw_reg
brw_vec2_grf(unsigned nr,unsigned subnr)810 brw_vec2_grf(unsigned nr, unsigned subnr)
811 {
812 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
813 }
814
815 static inline struct brw_reg
xe2_vec2_grf(unsigned nr,unsigned subnr)816 xe2_vec2_grf(unsigned nr, unsigned subnr)
817 {
818 return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
819 }
820
821 /** Construct float[4] general-purpose register */
822 static inline struct brw_reg
brw_vec4_grf(unsigned nr,unsigned subnr)823 brw_vec4_grf(unsigned nr, unsigned subnr)
824 {
825 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
826 }
827
828 static inline struct brw_reg
xe2_vec4_grf(unsigned nr,unsigned subnr)829 xe2_vec4_grf(unsigned nr, unsigned subnr)
830 {
831 return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
832 }
833
834 /** Construct float[8] general-purpose register */
835 static inline struct brw_reg
brw_vec8_grf(unsigned nr,unsigned subnr)836 brw_vec8_grf(unsigned nr, unsigned subnr)
837 {
838 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
839 }
840
841 static inline struct brw_reg
xe2_vec8_grf(unsigned nr,unsigned subnr)842 xe2_vec8_grf(unsigned nr, unsigned subnr)
843 {
844 return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
845 }
846
847 /** Construct float[16] general-purpose register */
848 static inline struct brw_reg
brw_vec16_grf(unsigned nr,unsigned subnr)849 brw_vec16_grf(unsigned nr, unsigned subnr)
850 {
851 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
852 }
853
854 static inline struct brw_reg
xe2_vec16_grf(unsigned nr,unsigned subnr)855 xe2_vec16_grf(unsigned nr, unsigned subnr)
856 {
857 return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, 2 * nr + subnr / 8, subnr % 8);
858 }
859
860 static inline struct brw_reg
brw_vecn_grf(unsigned width,unsigned nr,unsigned subnr)861 brw_vecn_grf(unsigned width, unsigned nr, unsigned subnr)
862 {
863 return brw_vecn_reg(width, BRW_GENERAL_REGISTER_FILE, nr, subnr);
864 }
865
866 static inline struct brw_reg
xe2_vecn_grf(unsigned width,unsigned nr,unsigned subnr)867 xe2_vecn_grf(unsigned width, unsigned nr, unsigned subnr)
868 {
869 return brw_vecn_reg(width, BRW_GENERAL_REGISTER_FILE, nr + subnr / 8, subnr % 8);
870 }
871
872 static inline struct brw_reg
brw_uw1_grf(unsigned nr,unsigned subnr)873 brw_uw1_grf(unsigned nr, unsigned subnr)
874 {
875 return brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
876 }
877
878 static inline struct brw_reg
brw_uw8_grf(unsigned nr,unsigned subnr)879 brw_uw8_grf(unsigned nr, unsigned subnr)
880 {
881 return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
882 }
883
884 static inline struct brw_reg
brw_uw16_grf(unsigned nr,unsigned subnr)885 brw_uw16_grf(unsigned nr, unsigned subnr)
886 {
887 return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
888 }
889
890 static inline struct brw_reg
brw_ud8_grf(unsigned nr,unsigned subnr)891 brw_ud8_grf(unsigned nr, unsigned subnr)
892 {
893 return brw_ud8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
894 }
895
896 static inline struct brw_reg
brw_ud1_grf(unsigned nr,unsigned subnr)897 brw_ud1_grf(unsigned nr, unsigned subnr)
898 {
899 return brw_ud1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
900 }
901
902
903 /** Construct null register (usually used for setting condition codes) */
904 static inline struct brw_reg
brw_null_reg(void)905 brw_null_reg(void)
906 {
907 return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
908 }
909
910 static inline struct brw_reg
brw_null_vec(unsigned width)911 brw_null_vec(unsigned width)
912 {
913 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
914 }
915
916 static inline struct brw_reg
brw_address_reg(unsigned subnr)917 brw_address_reg(unsigned subnr)
918 {
919 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
920 }
921
922 static inline struct brw_reg
brw_tdr_reg(void)923 brw_tdr_reg(void)
924 {
925 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_TDR, 0);
926 }
927
928 /* If/else instructions break in align16 mode if writemask & swizzle
929 * aren't xyzw. This goes against the convention for other scalar
930 * regs:
931 */
932 static inline struct brw_reg
brw_ip_reg(void)933 brw_ip_reg(void)
934 {
935 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
936 BRW_ARF_IP,
937 0,
938 0,
939 0,
940 BRW_REGISTER_TYPE_UD,
941 BRW_VERTICAL_STRIDE_4, /* ? */
942 BRW_WIDTH_1,
943 BRW_HORIZONTAL_STRIDE_0,
944 BRW_SWIZZLE_XYZW, /* NOTE! */
945 WRITEMASK_XYZW); /* NOTE! */
946 }
947
948 static inline struct brw_reg
brw_notification_reg(void)949 brw_notification_reg(void)
950 {
951 return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
952 BRW_ARF_NOTIFICATION_COUNT,
953 0,
954 0,
955 0,
956 BRW_REGISTER_TYPE_UD,
957 BRW_VERTICAL_STRIDE_0,
958 BRW_WIDTH_1,
959 BRW_HORIZONTAL_STRIDE_0,
960 BRW_SWIZZLE_XXXX,
961 WRITEMASK_X);
962 }
963
964 static inline struct brw_reg
brw_cr0_reg(unsigned subnr)965 brw_cr0_reg(unsigned subnr)
966 {
967 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_CONTROL, subnr);
968 }
969
970 static inline struct brw_reg
brw_sr0_reg(unsigned subnr)971 brw_sr0_reg(unsigned subnr)
972 {
973 return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_STATE, subnr);
974 }
975
976 static inline struct brw_reg
brw_acc_reg(unsigned width)977 brw_acc_reg(unsigned width)
978 {
979 return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
980 BRW_ARF_ACCUMULATOR, 0);
981 }
982
983 static inline struct brw_reg
brw_flag_reg(int reg,int subreg)984 brw_flag_reg(int reg, int subreg)
985 {
986 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
987 BRW_ARF_FLAG + reg, subreg);
988 }
989
990 static inline struct brw_reg
brw_flag_subreg(unsigned subreg)991 brw_flag_subreg(unsigned subreg)
992 {
993 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
994 BRW_ARF_FLAG + subreg / 2, subreg % 2);
995 }
996
997 /**
998 * Return the mask register present in Gfx4-5, or the related register present
999 * in Gfx7.5 and later hardware referred to as "channel enable" register in
1000 * the documentation.
1001 */
1002 static inline struct brw_reg
brw_mask_reg(unsigned subnr)1003 brw_mask_reg(unsigned subnr)
1004 {
1005 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
1006 }
1007
1008 static inline struct brw_reg
brw_vmask_reg()1009 brw_vmask_reg()
1010 {
1011 return brw_sr0_reg(3);
1012 }
1013
1014 static inline struct brw_reg
brw_dmask_reg()1015 brw_dmask_reg()
1016 {
1017 return brw_sr0_reg(2);
1018 }
1019
1020 static inline struct brw_reg
brw_mask_stack_reg(unsigned subnr)1021 brw_mask_stack_reg(unsigned subnr)
1022 {
1023 return suboffset(retype(brw_vec16_reg(BRW_ARCHITECTURE_REGISTER_FILE,
1024 BRW_ARF_MASK_STACK, 0),
1025 BRW_REGISTER_TYPE_UB), subnr);
1026 }
1027
1028 static inline struct brw_reg
brw_mask_stack_depth_reg(unsigned subnr)1029 brw_mask_stack_depth_reg(unsigned subnr)
1030 {
1031 return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
1032 BRW_ARF_MASK_STACK_DEPTH, subnr);
1033 }
1034
1035 /* This is almost always called with a numeric constant argument, so
1036 * make things easy to evaluate at compile time:
1037 */
cvt(unsigned val)1038 static inline unsigned cvt(unsigned val)
1039 {
1040 switch (val) {
1041 case 0: return 0;
1042 case 1: return 1;
1043 case 2: return 2;
1044 case 4: return 3;
1045 case 8: return 4;
1046 case 16: return 5;
1047 case 32: return 6;
1048 }
1049 return 0;
1050 }
1051
1052 static inline struct brw_reg
stride(struct brw_reg reg,unsigned vstride,unsigned width,unsigned hstride)1053 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
1054 {
1055 reg.vstride = cvt(vstride);
1056 reg.width = cvt(width) - 1;
1057 reg.hstride = cvt(hstride);
1058 return reg;
1059 }
1060
1061 /**
1062 * Multiply the vertical and horizontal stride of a register by the given
1063 * factor \a s.
1064 */
1065 static inline struct brw_reg
spread(struct brw_reg reg,unsigned s)1066 spread(struct brw_reg reg, unsigned s)
1067 {
1068 if (s) {
1069 assert(util_is_power_of_two_nonzero(s));
1070
1071 if (reg.hstride)
1072 reg.hstride += cvt(s) - 1;
1073
1074 if (reg.vstride)
1075 reg.vstride += cvt(s) - 1;
1076
1077 return reg;
1078 } else {
1079 return stride(reg, 0, 1, 0);
1080 }
1081 }
1082
1083 /**
1084 * Reinterpret each channel of register \p reg as a vector of values of the
1085 * given smaller type and take the i-th subcomponent from each.
1086 */
1087 static inline struct brw_reg
subscript(struct brw_reg reg,enum brw_reg_type type,unsigned i)1088 subscript(struct brw_reg reg, enum brw_reg_type type, unsigned i)
1089 {
1090 unsigned scale = type_sz(reg.type) / type_sz(type);
1091 assert(scale >= 1 && i < scale);
1092
1093 if (reg.file == IMM) {
1094 unsigned bit_size = type_sz(type) * 8;
1095 reg.u64 >>= i * bit_size;
1096 reg.u64 &= BITFIELD64_MASK(bit_size);
1097 if (bit_size <= 16)
1098 reg.u64 |= reg.u64 << 16;
1099 return retype(reg, type);
1100 }
1101
1102 return suboffset(retype(spread(reg, scale), type), i);
1103 }
1104
1105 static inline struct brw_reg
vec16(struct brw_reg reg)1106 vec16(struct brw_reg reg)
1107 {
1108 return stride(reg, 16,16,1);
1109 }
1110
1111 static inline struct brw_reg
vec8(struct brw_reg reg)1112 vec8(struct brw_reg reg)
1113 {
1114 return stride(reg, 8,8,1);
1115 }
1116
1117 static inline struct brw_reg
vec4(struct brw_reg reg)1118 vec4(struct brw_reg reg)
1119 {
1120 return stride(reg, 4,4,1);
1121 }
1122
1123 static inline struct brw_reg
vec2(struct brw_reg reg)1124 vec2(struct brw_reg reg)
1125 {
1126 return stride(reg, 2,2,1);
1127 }
1128
1129 static inline struct brw_reg
vec1(struct brw_reg reg)1130 vec1(struct brw_reg reg)
1131 {
1132 return stride(reg, 0,1,0);
1133 }
1134
1135
1136 static inline struct brw_reg
get_element(struct brw_reg reg,unsigned elt)1137 get_element(struct brw_reg reg, unsigned elt)
1138 {
1139 return vec1(suboffset(reg, elt));
1140 }
1141
1142 static inline struct brw_reg
get_element_ud(struct brw_reg reg,unsigned elt)1143 get_element_ud(struct brw_reg reg, unsigned elt)
1144 {
1145 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
1146 }
1147
1148 static inline struct brw_reg
get_element_d(struct brw_reg reg,unsigned elt)1149 get_element_d(struct brw_reg reg, unsigned elt)
1150 {
1151 return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
1152 }
1153
1154 static inline struct brw_reg
brw_swizzle(struct brw_reg reg,unsigned swz)1155 brw_swizzle(struct brw_reg reg, unsigned swz)
1156 {
1157 if (reg.file == BRW_IMMEDIATE_VALUE)
1158 reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
1159 else
1160 reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
1161
1162 return reg;
1163 }
1164
1165 static inline struct brw_reg
brw_writemask(struct brw_reg reg,unsigned mask)1166 brw_writemask(struct brw_reg reg, unsigned mask)
1167 {
1168 assert(reg.file != BRW_IMMEDIATE_VALUE);
1169 reg.writemask &= mask;
1170 return reg;
1171 }
1172
1173 static inline struct brw_reg
brw_set_writemask(struct brw_reg reg,unsigned mask)1174 brw_set_writemask(struct brw_reg reg, unsigned mask)
1175 {
1176 assert(reg.file != BRW_IMMEDIATE_VALUE);
1177 reg.writemask = mask;
1178 return reg;
1179 }
1180
1181 static inline unsigned
brw_writemask_for_size(unsigned n)1182 brw_writemask_for_size(unsigned n)
1183 {
1184 return (1 << n) - 1;
1185 }
1186
1187 static inline unsigned
brw_writemask_for_component_packing(unsigned n,unsigned first_component)1188 brw_writemask_for_component_packing(unsigned n, unsigned first_component)
1189 {
1190 assert(first_component + n <= 4);
1191 return (((1 << n) - 1) << first_component);
1192 }
1193
1194 static inline struct brw_reg
negate(struct brw_reg reg)1195 negate(struct brw_reg reg)
1196 {
1197 reg.negate ^= 1;
1198 return reg;
1199 }
1200
1201 static inline struct brw_reg
brw_abs(struct brw_reg reg)1202 brw_abs(struct brw_reg reg)
1203 {
1204 reg.abs = 1;
1205 reg.negate = 0;
1206 return reg;
1207 }
1208
1209 /************************************************************************/
1210
1211 static inline struct brw_reg
brw_vec4_indirect(unsigned subnr,int offset)1212 brw_vec4_indirect(unsigned subnr, int offset)
1213 {
1214 struct brw_reg reg = brw_vec4_grf(0, 0);
1215 reg.subnr = subnr;
1216 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1217 reg.indirect_offset = offset;
1218 return reg;
1219 }
1220
1221 static inline struct brw_reg
brw_vec1_indirect(unsigned subnr,int offset)1222 brw_vec1_indirect(unsigned subnr, int offset)
1223 {
1224 struct brw_reg reg = brw_vec1_grf(0, 0);
1225 reg.subnr = subnr;
1226 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1227 reg.indirect_offset = offset;
1228 return reg;
1229 }
1230
1231 static inline struct brw_reg
brw_VxH_indirect(unsigned subnr,int offset)1232 brw_VxH_indirect(unsigned subnr, int offset)
1233 {
1234 struct brw_reg reg = brw_vec1_grf(0, 0);
1235 reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
1236 reg.subnr = subnr;
1237 reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1238 reg.indirect_offset = offset;
1239 return reg;
1240 }
1241
1242 static inline struct brw_reg
deref_4f(struct brw_indirect ptr,int offset)1243 deref_4f(struct brw_indirect ptr, int offset)
1244 {
1245 return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1246 }
1247
1248 static inline struct brw_reg
deref_1f(struct brw_indirect ptr,int offset)1249 deref_1f(struct brw_indirect ptr, int offset)
1250 {
1251 return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1252 }
1253
1254 static inline struct brw_reg
deref_4b(struct brw_indirect ptr,int offset)1255 deref_4b(struct brw_indirect ptr, int offset)
1256 {
1257 return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
1258 }
1259
1260 static inline struct brw_reg
deref_1uw(struct brw_indirect ptr,int offset)1261 deref_1uw(struct brw_indirect ptr, int offset)
1262 {
1263 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
1264 }
1265
1266 static inline struct brw_reg
deref_1d(struct brw_indirect ptr,int offset)1267 deref_1d(struct brw_indirect ptr, int offset)
1268 {
1269 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
1270 }
1271
1272 static inline struct brw_reg
deref_1ud(struct brw_indirect ptr,int offset)1273 deref_1ud(struct brw_indirect ptr, int offset)
1274 {
1275 return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
1276 }
1277
1278 static inline struct brw_reg
get_addr_reg(struct brw_indirect ptr)1279 get_addr_reg(struct brw_indirect ptr)
1280 {
1281 return brw_address_reg(ptr.addr_subnr);
1282 }
1283
1284 static inline struct brw_indirect
brw_indirect_offset(struct brw_indirect ptr,int offset)1285 brw_indirect_offset(struct brw_indirect ptr, int offset)
1286 {
1287 ptr.addr_offset += offset;
1288 return ptr;
1289 }
1290
1291 static inline struct brw_indirect
brw_indirect(unsigned addr_subnr,int offset)1292 brw_indirect(unsigned addr_subnr, int offset)
1293 {
1294 struct brw_indirect ptr;
1295 ptr.addr_subnr = addr_subnr;
1296 ptr.addr_offset = offset;
1297 ptr.pad = 0;
1298 return ptr;
1299 }
1300
1301 static inline bool
region_matches(struct brw_reg reg,enum brw_vertical_stride v,enum brw_width w,enum brw_horizontal_stride h)1302 region_matches(struct brw_reg reg, enum brw_vertical_stride v,
1303 enum brw_width w, enum brw_horizontal_stride h)
1304 {
1305 return reg.vstride == v &&
1306 reg.width == w &&
1307 reg.hstride == h;
1308 }
1309
1310 #define has_scalar_region(reg) \
1311 region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1312 BRW_HORIZONTAL_STRIDE_0)
1313
1314 /**
1315 * Return the size in bytes per data element of register \p reg on the
1316 * corresponding register file.
1317 */
1318 static inline unsigned
element_sz(struct brw_reg reg)1319 element_sz(struct brw_reg reg)
1320 {
1321 if (reg.file == BRW_IMMEDIATE_VALUE || has_scalar_region(reg)) {
1322 return type_sz(reg.type);
1323
1324 } else if (reg.width == BRW_WIDTH_1 &&
1325 reg.hstride == BRW_HORIZONTAL_STRIDE_0) {
1326 assert(reg.vstride != BRW_VERTICAL_STRIDE_0);
1327 return type_sz(reg.type) << (reg.vstride - 1);
1328
1329 } else {
1330 assert(reg.hstride != BRW_HORIZONTAL_STRIDE_0);
1331 assert(reg.vstride == reg.hstride + reg.width);
1332 return type_sz(reg.type) << (reg.hstride - 1);
1333 }
1334 }
1335
1336 /* brw_packed_float.c */
1337 int brw_float_to_vf(float f);
1338 float brw_vf_to_float(unsigned char vf);
1339
1340 #ifdef __cplusplus
1341 }
1342 #endif
1343
1344 #endif
1345