• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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