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