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 gen_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 gen7, MRFs are no longer used, and contiguous GRFs are used instead.  We
65  * haven't converted our compiler to be aware of this, so it asks for MRFs and
66  * brw_eu_emit.c quietly converts them to be accesses of the top GRFs.  The
67  * register allocators have to be careful of this to avoid corrupting the "MRF"s
68  * with actual GRF allocations.
69  */
70 #define GEN7_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_UV:
331    case BRW_REGISTER_TYPE_V:
332    case BRW_REGISTER_TYPE_HF:
333       return 2;
334    case BRW_REGISTER_TYPE_UB:
335    case BRW_REGISTER_TYPE_B:
336       return 1;
337    default:
338       unreachable("not reached");
339    }
340 }
341 
342 static inline enum brw_reg_type
get_exec_type(const enum brw_reg_type type)343 get_exec_type(const enum brw_reg_type type)
344 {
345    switch (type) {
346    case BRW_REGISTER_TYPE_B:
347    case BRW_REGISTER_TYPE_V:
348       return BRW_REGISTER_TYPE_W;
349    case BRW_REGISTER_TYPE_UB:
350    case BRW_REGISTER_TYPE_UV:
351       return BRW_REGISTER_TYPE_UW;
352    case BRW_REGISTER_TYPE_VF:
353       return BRW_REGISTER_TYPE_F;
354    default:
355       return type;
356    }
357 }
358 
359 /**
360  * Return an integer type of the requested size and signedness.
361  */
362 static inline enum brw_reg_type
brw_int_type(unsigned sz,bool is_signed)363 brw_int_type(unsigned sz, bool is_signed)
364 {
365    switch (sz) {
366    case 1:
367       return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
368    case 2:
369       return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
370    case 4:
371       return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
372    case 8:
373       return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
374    default:
375       unreachable("Not reached.");
376    }
377 }
378 
379 static inline bool
type_is_unsigned_int(enum brw_reg_type tp)380 type_is_unsigned_int(enum brw_reg_type tp)
381 {
382    return tp == BRW_REGISTER_TYPE_UB ||
383           tp == BRW_REGISTER_TYPE_UW ||
384           tp == BRW_REGISTER_TYPE_UD ||
385           tp == BRW_REGISTER_TYPE_UQ;
386 }
387 
388 /**
389  * Construct a brw_reg.
390  * \param file      one of the BRW_x_REGISTER_FILE values
391  * \param nr        register number/index
392  * \param subnr     register sub number
393  * \param negate    register negate modifier
394  * \param abs       register abs modifier
395  * \param type      one of BRW_REGISTER_TYPE_x
396  * \param vstride   one of BRW_VERTICAL_STRIDE_x
397  * \param width     one of BRW_WIDTH_x
398  * \param hstride   one of BRW_HORIZONTAL_STRIDE_x
399  * \param swizzle   one of BRW_SWIZZLE_x
400  * \param writemask WRITEMASK_X/Y/Z/W bitfield
401  */
402 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)403 brw_reg(enum brw_reg_file file,
404         unsigned nr,
405         unsigned subnr,
406         unsigned negate,
407         unsigned abs,
408         enum brw_reg_type type,
409         unsigned vstride,
410         unsigned width,
411         unsigned hstride,
412         unsigned swizzle,
413         unsigned writemask)
414 {
415    struct brw_reg reg;
416    if (file == BRW_GENERAL_REGISTER_FILE)
417       assert(nr < BRW_MAX_GRF);
418    else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
419       assert(nr <= BRW_ARF_TIMESTAMP);
420    /* Asserting on the MRF register number requires to know the hardware gen
421     * (gen6 has 24 MRF registers), which we don't know here, so we assert
422     * for that in the generators and in brw_eu_emit.c
423     */
424 
425    reg.type = type;
426    reg.file = file;
427    reg.negate = negate;
428    reg.abs = abs;
429    reg.address_mode = BRW_ADDRESS_DIRECT;
430    reg.pad0 = 0;
431    reg.subnr = subnr * type_sz(type);
432    reg.nr = nr;
433 
434    /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
435     * set swizzle and writemask to W, as the lower bits of subnr will
436     * be lost when converted to align16.  This is probably too much to
437     * keep track of as you'd want it adjusted by suboffset(), etc.
438     * Perhaps fix up when converting to align16?
439     */
440    reg.swizzle = swizzle;
441    reg.writemask = writemask;
442    reg.indirect_offset = 0;
443    reg.vstride = vstride;
444    reg.width = width;
445    reg.hstride = hstride;
446    reg.pad1 = 0;
447    return reg;
448 }
449 
450 /** Construct float[16] register */
451 static inline struct brw_reg
brw_vec16_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)452 brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
453 {
454    return brw_reg(file,
455                   nr,
456                   subnr,
457                   0,
458                   0,
459                   BRW_REGISTER_TYPE_F,
460                   BRW_VERTICAL_STRIDE_16,
461                   BRW_WIDTH_16,
462                   BRW_HORIZONTAL_STRIDE_1,
463                   BRW_SWIZZLE_XYZW,
464                   WRITEMASK_XYZW);
465 }
466 
467 /** Construct float[8] register */
468 static inline struct brw_reg
brw_vec8_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)469 brw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
470 {
471    return brw_reg(file,
472                   nr,
473                   subnr,
474                   0,
475                   0,
476                   BRW_REGISTER_TYPE_F,
477                   BRW_VERTICAL_STRIDE_8,
478                   BRW_WIDTH_8,
479                   BRW_HORIZONTAL_STRIDE_1,
480                   BRW_SWIZZLE_XYZW,
481                   WRITEMASK_XYZW);
482 }
483 
484 /** Construct float[4] register */
485 static inline struct brw_reg
brw_vec4_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)486 brw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
487 {
488    return brw_reg(file,
489                   nr,
490                   subnr,
491                   0,
492                   0,
493                   BRW_REGISTER_TYPE_F,
494                   BRW_VERTICAL_STRIDE_4,
495                   BRW_WIDTH_4,
496                   BRW_HORIZONTAL_STRIDE_1,
497                   BRW_SWIZZLE_XYZW,
498                   WRITEMASK_XYZW);
499 }
500 
501 /** Construct float[2] register */
502 static inline struct brw_reg
brw_vec2_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)503 brw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
504 {
505    return brw_reg(file,
506                   nr,
507                   subnr,
508                   0,
509                   0,
510                   BRW_REGISTER_TYPE_F,
511                   BRW_VERTICAL_STRIDE_2,
512                   BRW_WIDTH_2,
513                   BRW_HORIZONTAL_STRIDE_1,
514                   BRW_SWIZZLE_XYXY,
515                   WRITEMASK_XY);
516 }
517 
518 /** Construct float[1] register */
519 static inline struct brw_reg
brw_vec1_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)520 brw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
521 {
522    return brw_reg(file,
523                   nr,
524                   subnr,
525                   0,
526                   0,
527                   BRW_REGISTER_TYPE_F,
528                   BRW_VERTICAL_STRIDE_0,
529                   BRW_WIDTH_1,
530                   BRW_HORIZONTAL_STRIDE_0,
531                   BRW_SWIZZLE_XXXX,
532                   WRITEMASK_X);
533 }
534 
535 static inline struct brw_reg
brw_vecn_reg(unsigned width,enum brw_reg_file file,unsigned nr,unsigned subnr)536 brw_vecn_reg(unsigned width, enum brw_reg_file file,
537              unsigned nr, unsigned subnr)
538 {
539    switch (width) {
540    case 1:
541       return brw_vec1_reg(file, nr, subnr);
542    case 2:
543       return brw_vec2_reg(file, nr, subnr);
544    case 4:
545       return brw_vec4_reg(file, nr, subnr);
546    case 8:
547       return brw_vec8_reg(file, nr, subnr);
548    case 16:
549       return brw_vec16_reg(file, nr, subnr);
550    default:
551       unreachable("Invalid register width");
552    }
553 }
554 
555 static inline struct brw_reg
retype(struct brw_reg reg,enum brw_reg_type type)556 retype(struct brw_reg reg, enum brw_reg_type type)
557 {
558    reg.type = type;
559    return reg;
560 }
561 
562 static inline struct brw_reg
firsthalf(struct brw_reg reg)563 firsthalf(struct brw_reg reg)
564 {
565    return reg;
566 }
567 
568 static inline struct brw_reg
sechalf(struct brw_reg reg)569 sechalf(struct brw_reg reg)
570 {
571    if (reg.vstride)
572       reg.nr++;
573    return reg;
574 }
575 
576 static inline struct brw_reg
offset(struct brw_reg reg,unsigned delta)577 offset(struct brw_reg reg, unsigned delta)
578 {
579    reg.nr += delta;
580    return reg;
581 }
582 
583 
584 static inline struct brw_reg
byte_offset(struct brw_reg reg,unsigned bytes)585 byte_offset(struct brw_reg reg, unsigned bytes)
586 {
587    unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
588    reg.nr = newoffset / REG_SIZE;
589    reg.subnr = newoffset % REG_SIZE;
590    return reg;
591 }
592 
593 static inline struct brw_reg
suboffset(struct brw_reg reg,unsigned delta)594 suboffset(struct brw_reg reg, unsigned delta)
595 {
596    return byte_offset(reg, delta * type_sz(reg.type));
597 }
598 
599 /** Construct unsigned word[16] register */
600 static inline struct brw_reg
brw_uw16_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)601 brw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
602 {
603    return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
604 }
605 
606 /** Construct unsigned word[8] register */
607 static inline struct brw_reg
brw_uw8_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)608 brw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
609 {
610    return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
611 }
612 
613 /** Construct unsigned word[1] register */
614 static inline struct brw_reg
brw_uw1_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)615 brw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
616 {
617    return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
618 }
619 
620 static inline struct brw_reg
brw_ud1_reg(enum brw_reg_file file,unsigned nr,unsigned subnr)621 brw_ud1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
622 {
623    return retype(brw_vec1_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
624 }
625 
626 static inline struct brw_reg
brw_imm_reg(enum brw_reg_type type)627 brw_imm_reg(enum brw_reg_type type)
628 {
629    return brw_reg(BRW_IMMEDIATE_VALUE,
630                   0,
631                   0,
632                   0,
633                   0,
634                   type,
635                   BRW_VERTICAL_STRIDE_0,
636                   BRW_WIDTH_1,
637                   BRW_HORIZONTAL_STRIDE_0,
638                   0,
639                   0);
640 }
641 
642 /** Construct float immediate register */
643 static inline struct brw_reg
brw_imm_df(double df)644 brw_imm_df(double df)
645 {
646    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
647    imm.df = df;
648    return imm;
649 }
650 
651 static inline struct brw_reg
brw_imm_u64(uint64_t u64)652 brw_imm_u64(uint64_t u64)
653 {
654    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
655    imm.u64 = u64;
656    return imm;
657 }
658 
659 static inline struct brw_reg
brw_imm_f(float f)660 brw_imm_f(float f)
661 {
662    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
663    imm.f = f;
664    return imm;
665 }
666 
667 /** Construct int64_t immediate register */
668 static inline struct brw_reg
brw_imm_q(int64_t q)669 brw_imm_q(int64_t q)
670 {
671    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_Q);
672    imm.d64 = q;
673    return imm;
674 }
675 
676 /** Construct int64_t immediate register */
677 static inline struct brw_reg
brw_imm_uq(uint64_t uq)678 brw_imm_uq(uint64_t uq)
679 {
680    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
681    imm.u64 = uq;
682    return imm;
683 }
684 
685 /** Construct integer immediate register */
686 static inline struct brw_reg
brw_imm_d(int d)687 brw_imm_d(int d)
688 {
689    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
690    imm.d = d;
691    return imm;
692 }
693 
694 /** Construct uint immediate register */
695 static inline struct brw_reg
brw_imm_ud(unsigned ud)696 brw_imm_ud(unsigned ud)
697 {
698    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
699    imm.ud = ud;
700    return imm;
701 }
702 
703 /** Construct ushort immediate register */
704 static inline struct brw_reg
brw_imm_uw(uint16_t uw)705 brw_imm_uw(uint16_t uw)
706 {
707    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
708    imm.ud = uw | (uw << 16);
709    return imm;
710 }
711 
712 /** Construct short immediate register */
713 static inline struct brw_reg
brw_imm_w(int16_t w)714 brw_imm_w(int16_t w)
715 {
716    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
717    imm.ud = (uint16_t)w | (uint32_t)(uint16_t)w << 16;
718    return imm;
719 }
720 
721 /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
722  * numbers alias with _V and _VF below:
723  */
724 
725 /** Construct vector of eight signed half-byte values */
726 static inline struct brw_reg
brw_imm_v(unsigned v)727 brw_imm_v(unsigned v)
728 {
729    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
730    imm.ud = v;
731    return imm;
732 }
733 
734 /** Construct vector of eight unsigned half-byte values */
735 static inline struct brw_reg
brw_imm_uv(unsigned uv)736 brw_imm_uv(unsigned uv)
737 {
738    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
739    imm.ud = uv;
740    return imm;
741 }
742 
743 /** Construct vector of four 8-bit float values */
744 static inline struct brw_reg
brw_imm_vf(unsigned v)745 brw_imm_vf(unsigned v)
746 {
747    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
748    imm.ud = v;
749    return imm;
750 }
751 
752 static inline struct brw_reg
brw_imm_vf4(unsigned v0,unsigned v1,unsigned v2,unsigned v3)753 brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
754 {
755    struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
756    imm.vstride = BRW_VERTICAL_STRIDE_0;
757    imm.width = BRW_WIDTH_4;
758    imm.hstride = BRW_HORIZONTAL_STRIDE_1;
759    imm.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
760    return imm;
761 }
762 
763 
764 static inline struct brw_reg
brw_address(struct brw_reg reg)765 brw_address(struct brw_reg reg)
766 {
767    return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
768 }
769 
770 /** Construct float[1] general-purpose register */
771 static inline struct brw_reg
brw_vec1_grf(unsigned nr,unsigned subnr)772 brw_vec1_grf(unsigned nr, unsigned subnr)
773 {
774    return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
775 }
776 
777 /** Construct float[2] general-purpose register */
778 static inline struct brw_reg
brw_vec2_grf(unsigned nr,unsigned subnr)779 brw_vec2_grf(unsigned nr, unsigned subnr)
780 {
781    return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
782 }
783 
784 /** Construct float[4] general-purpose register */
785 static inline struct brw_reg
brw_vec4_grf(unsigned nr,unsigned subnr)786 brw_vec4_grf(unsigned nr, unsigned subnr)
787 {
788    return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
789 }
790 
791 /** Construct float[8] general-purpose register */
792 static inline struct brw_reg
brw_vec8_grf(unsigned nr,unsigned subnr)793 brw_vec8_grf(unsigned nr, unsigned subnr)
794 {
795    return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
796 }
797 
798 /** Construct float[16] general-purpose register */
799 static inline struct brw_reg
brw_vec16_grf(unsigned nr,unsigned subnr)800 brw_vec16_grf(unsigned nr, unsigned subnr)
801 {
802    return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
803 }
804 
805 static inline struct brw_reg
brw_vecn_grf(unsigned width,unsigned nr,unsigned subnr)806 brw_vecn_grf(unsigned width, unsigned nr, unsigned subnr)
807 {
808    return brw_vecn_reg(width, BRW_GENERAL_REGISTER_FILE, nr, subnr);
809 }
810 
811 
812 static inline struct brw_reg
brw_uw8_grf(unsigned nr,unsigned subnr)813 brw_uw8_grf(unsigned nr, unsigned subnr)
814 {
815    return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
816 }
817 
818 static inline struct brw_reg
brw_uw16_grf(unsigned nr,unsigned subnr)819 brw_uw16_grf(unsigned nr, unsigned subnr)
820 {
821    return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
822 }
823 
824 
825 /** Construct null register (usually used for setting condition codes) */
826 static inline struct brw_reg
brw_null_reg(void)827 brw_null_reg(void)
828 {
829    return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
830 }
831 
832 static inline struct brw_reg
brw_null_vec(unsigned width)833 brw_null_vec(unsigned width)
834 {
835    return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
836 }
837 
838 static inline struct brw_reg
brw_address_reg(unsigned subnr)839 brw_address_reg(unsigned subnr)
840 {
841    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
842 }
843 
844 static inline struct brw_reg
brw_tdr_reg(void)845 brw_tdr_reg(void)
846 {
847    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_TDR, 0);
848 }
849 
850 /* If/else instructions break in align16 mode if writemask & swizzle
851  * aren't xyzw.  This goes against the convention for other scalar
852  * regs:
853  */
854 static inline struct brw_reg
brw_ip_reg(void)855 brw_ip_reg(void)
856 {
857    return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
858                   BRW_ARF_IP,
859                   0,
860                   0,
861                   0,
862                   BRW_REGISTER_TYPE_UD,
863                   BRW_VERTICAL_STRIDE_4, /* ? */
864                   BRW_WIDTH_1,
865                   BRW_HORIZONTAL_STRIDE_0,
866                   BRW_SWIZZLE_XYZW, /* NOTE! */
867                   WRITEMASK_XYZW); /* NOTE! */
868 }
869 
870 static inline struct brw_reg
brw_notification_reg(void)871 brw_notification_reg(void)
872 {
873    return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
874                   BRW_ARF_NOTIFICATION_COUNT,
875                   0,
876                   0,
877                   0,
878                   BRW_REGISTER_TYPE_UD,
879                   BRW_VERTICAL_STRIDE_0,
880                   BRW_WIDTH_1,
881                   BRW_HORIZONTAL_STRIDE_0,
882                   BRW_SWIZZLE_XXXX,
883                   WRITEMASK_X);
884 }
885 
886 static inline struct brw_reg
brw_cr0_reg(unsigned subnr)887 brw_cr0_reg(unsigned subnr)
888 {
889    return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_CONTROL, subnr);
890 }
891 
892 static inline struct brw_reg
brw_sr0_reg(unsigned subnr)893 brw_sr0_reg(unsigned subnr)
894 {
895    return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_STATE, subnr);
896 }
897 
898 static inline struct brw_reg
brw_acc_reg(unsigned width)899 brw_acc_reg(unsigned width)
900 {
901    return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
902                        BRW_ARF_ACCUMULATOR, 0);
903 }
904 
905 static inline struct brw_reg
brw_flag_reg(int reg,int subreg)906 brw_flag_reg(int reg, int subreg)
907 {
908    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
909                       BRW_ARF_FLAG + reg, subreg);
910 }
911 
912 static inline struct brw_reg
brw_flag_subreg(unsigned subreg)913 brw_flag_subreg(unsigned subreg)
914 {
915    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
916                       BRW_ARF_FLAG + subreg / 2, subreg % 2);
917 }
918 
919 /**
920  * Return the mask register present in Gen4-5, or the related register present
921  * in Gen7.5 and later hardware referred to as "channel enable" register in
922  * the documentation.
923  */
924 static inline struct brw_reg
brw_mask_reg(unsigned subnr)925 brw_mask_reg(unsigned subnr)
926 {
927    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
928 }
929 
930 static inline struct brw_reg
brw_vmask_reg()931 brw_vmask_reg()
932 {
933    return brw_sr0_reg(3);
934 }
935 
936 static inline struct brw_reg
brw_dmask_reg()937 brw_dmask_reg()
938 {
939    return brw_sr0_reg(2);
940 }
941 
942 static inline struct brw_reg
brw_mask_stack_reg(unsigned subnr)943 brw_mask_stack_reg(unsigned subnr)
944 {
945    return suboffset(retype(brw_vec16_reg(BRW_ARCHITECTURE_REGISTER_FILE,
946                                          BRW_ARF_MASK_STACK, 0),
947                            BRW_REGISTER_TYPE_UB), subnr);
948 }
949 
950 static inline struct brw_reg
brw_mask_stack_depth_reg(unsigned subnr)951 brw_mask_stack_depth_reg(unsigned subnr)
952 {
953    return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
954                       BRW_ARF_MASK_STACK_DEPTH, subnr);
955 }
956 
957 static inline struct brw_reg
brw_message_reg(unsigned nr)958 brw_message_reg(unsigned nr)
959 {
960    return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
961 }
962 
963 static inline struct brw_reg
brw_uvec_mrf(unsigned width,unsigned nr,unsigned subnr)964 brw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
965 {
966    return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
967                  BRW_REGISTER_TYPE_UD);
968 }
969 
970 /* This is almost always called with a numeric constant argument, so
971  * make things easy to evaluate at compile time:
972  */
cvt(unsigned val)973 static inline unsigned cvt(unsigned val)
974 {
975    switch (val) {
976    case 0: return 0;
977    case 1: return 1;
978    case 2: return 2;
979    case 4: return 3;
980    case 8: return 4;
981    case 16: return 5;
982    case 32: return 6;
983    }
984    return 0;
985 }
986 
987 static inline struct brw_reg
stride(struct brw_reg reg,unsigned vstride,unsigned width,unsigned hstride)988 stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
989 {
990    reg.vstride = cvt(vstride);
991    reg.width = cvt(width) - 1;
992    reg.hstride = cvt(hstride);
993    return reg;
994 }
995 
996 /**
997  * Multiply the vertical and horizontal stride of a register by the given
998  * factor \a s.
999  */
1000 static inline struct brw_reg
spread(struct brw_reg reg,unsigned s)1001 spread(struct brw_reg reg, unsigned s)
1002 {
1003    if (s) {
1004       assert(util_is_power_of_two_nonzero(s));
1005 
1006       if (reg.hstride)
1007          reg.hstride += cvt(s) - 1;
1008 
1009       if (reg.vstride)
1010          reg.vstride += cvt(s) - 1;
1011 
1012       return reg;
1013    } else {
1014       return stride(reg, 0, 1, 0);
1015    }
1016 }
1017 
1018 /**
1019  * Reinterpret each channel of register \p reg as a vector of values of the
1020  * given smaller type and take the i-th subcomponent from each.
1021  */
1022 static inline struct brw_reg
subscript(struct brw_reg reg,enum brw_reg_type type,unsigned i)1023 subscript(struct brw_reg reg, enum brw_reg_type type, unsigned i)
1024 {
1025    if (reg.file == IMM)
1026       return reg;
1027 
1028    unsigned scale = type_sz(reg.type) / type_sz(type);
1029    assert(scale >= 1 && i < scale);
1030 
1031    return suboffset(retype(spread(reg, scale), type), i);
1032 }
1033 
1034 static inline struct brw_reg
vec16(struct brw_reg reg)1035 vec16(struct brw_reg reg)
1036 {
1037    return stride(reg, 16,16,1);
1038 }
1039 
1040 static inline struct brw_reg
vec8(struct brw_reg reg)1041 vec8(struct brw_reg reg)
1042 {
1043    return stride(reg, 8,8,1);
1044 }
1045 
1046 static inline struct brw_reg
vec4(struct brw_reg reg)1047 vec4(struct brw_reg reg)
1048 {
1049    return stride(reg, 4,4,1);
1050 }
1051 
1052 static inline struct brw_reg
vec2(struct brw_reg reg)1053 vec2(struct brw_reg reg)
1054 {
1055    return stride(reg, 2,2,1);
1056 }
1057 
1058 static inline struct brw_reg
vec1(struct brw_reg reg)1059 vec1(struct brw_reg reg)
1060 {
1061    return stride(reg, 0,1,0);
1062 }
1063 
1064 
1065 static inline struct brw_reg
get_element(struct brw_reg reg,unsigned elt)1066 get_element(struct brw_reg reg, unsigned elt)
1067 {
1068    return vec1(suboffset(reg, elt));
1069 }
1070 
1071 static inline struct brw_reg
get_element_ud(struct brw_reg reg,unsigned elt)1072 get_element_ud(struct brw_reg reg, unsigned elt)
1073 {
1074    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
1075 }
1076 
1077 static inline struct brw_reg
get_element_d(struct brw_reg reg,unsigned elt)1078 get_element_d(struct brw_reg reg, unsigned elt)
1079 {
1080    return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
1081 }
1082 
1083 static inline struct brw_reg
brw_swizzle(struct brw_reg reg,unsigned swz)1084 brw_swizzle(struct brw_reg reg, unsigned swz)
1085 {
1086    if (reg.file == BRW_IMMEDIATE_VALUE)
1087       reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
1088    else
1089       reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
1090 
1091    return reg;
1092 }
1093 
1094 static inline struct brw_reg
brw_writemask(struct brw_reg reg,unsigned mask)1095 brw_writemask(struct brw_reg reg, unsigned mask)
1096 {
1097    assert(reg.file != BRW_IMMEDIATE_VALUE);
1098    reg.writemask &= mask;
1099    return reg;
1100 }
1101 
1102 static inline struct brw_reg
brw_set_writemask(struct brw_reg reg,unsigned mask)1103 brw_set_writemask(struct brw_reg reg, unsigned mask)
1104 {
1105    assert(reg.file != BRW_IMMEDIATE_VALUE);
1106    reg.writemask = mask;
1107    return reg;
1108 }
1109 
1110 static inline unsigned
brw_writemask_for_size(unsigned n)1111 brw_writemask_for_size(unsigned n)
1112 {
1113    return (1 << n) - 1;
1114 }
1115 
1116 static inline unsigned
brw_writemask_for_component_packing(unsigned n,unsigned first_component)1117 brw_writemask_for_component_packing(unsigned n, unsigned first_component)
1118 {
1119    assert(first_component + n <= 4);
1120    return (((1 << n) - 1) << first_component);
1121 }
1122 
1123 static inline struct brw_reg
negate(struct brw_reg reg)1124 negate(struct brw_reg reg)
1125 {
1126    reg.negate ^= 1;
1127    return reg;
1128 }
1129 
1130 static inline struct brw_reg
brw_abs(struct brw_reg reg)1131 brw_abs(struct brw_reg reg)
1132 {
1133    reg.abs = 1;
1134    reg.negate = 0;
1135    return reg;
1136 }
1137 
1138 /************************************************************************/
1139 
1140 static inline struct brw_reg
brw_vec4_indirect(unsigned subnr,int offset)1141 brw_vec4_indirect(unsigned subnr, int offset)
1142 {
1143    struct brw_reg reg =  brw_vec4_grf(0, 0);
1144    reg.subnr = subnr;
1145    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1146    reg.indirect_offset = offset;
1147    return reg;
1148 }
1149 
1150 static inline struct brw_reg
brw_vec1_indirect(unsigned subnr,int offset)1151 brw_vec1_indirect(unsigned subnr, int offset)
1152 {
1153    struct brw_reg reg =  brw_vec1_grf(0, 0);
1154    reg.subnr = subnr;
1155    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1156    reg.indirect_offset = offset;
1157    return reg;
1158 }
1159 
1160 static inline struct brw_reg
brw_VxH_indirect(unsigned subnr,int offset)1161 brw_VxH_indirect(unsigned subnr, int offset)
1162 {
1163    struct brw_reg reg = brw_vec1_grf(0, 0);
1164    reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
1165    reg.subnr = subnr;
1166    reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1167    reg.indirect_offset = offset;
1168    return reg;
1169 }
1170 
1171 static inline struct brw_reg
deref_4f(struct brw_indirect ptr,int offset)1172 deref_4f(struct brw_indirect ptr, int offset)
1173 {
1174    return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1175 }
1176 
1177 static inline struct brw_reg
deref_1f(struct brw_indirect ptr,int offset)1178 deref_1f(struct brw_indirect ptr, int offset)
1179 {
1180    return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1181 }
1182 
1183 static inline struct brw_reg
deref_4b(struct brw_indirect ptr,int offset)1184 deref_4b(struct brw_indirect ptr, int offset)
1185 {
1186    return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
1187 }
1188 
1189 static inline struct brw_reg
deref_1uw(struct brw_indirect ptr,int offset)1190 deref_1uw(struct brw_indirect ptr, int offset)
1191 {
1192    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
1193 }
1194 
1195 static inline struct brw_reg
deref_1d(struct brw_indirect ptr,int offset)1196 deref_1d(struct brw_indirect ptr, int offset)
1197 {
1198    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
1199 }
1200 
1201 static inline struct brw_reg
deref_1ud(struct brw_indirect ptr,int offset)1202 deref_1ud(struct brw_indirect ptr, int offset)
1203 {
1204    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
1205 }
1206 
1207 static inline struct brw_reg
get_addr_reg(struct brw_indirect ptr)1208 get_addr_reg(struct brw_indirect ptr)
1209 {
1210    return brw_address_reg(ptr.addr_subnr);
1211 }
1212 
1213 static inline struct brw_indirect
brw_indirect_offset(struct brw_indirect ptr,int offset)1214 brw_indirect_offset(struct brw_indirect ptr, int offset)
1215 {
1216    ptr.addr_offset += offset;
1217    return ptr;
1218 }
1219 
1220 static inline struct brw_indirect
brw_indirect(unsigned addr_subnr,int offset)1221 brw_indirect(unsigned addr_subnr, int offset)
1222 {
1223    struct brw_indirect ptr;
1224    ptr.addr_subnr = addr_subnr;
1225    ptr.addr_offset = offset;
1226    ptr.pad = 0;
1227    return ptr;
1228 }
1229 
1230 static inline bool
region_matches(struct brw_reg reg,enum brw_vertical_stride v,enum brw_width w,enum brw_horizontal_stride h)1231 region_matches(struct brw_reg reg, enum brw_vertical_stride v,
1232                enum brw_width w, enum brw_horizontal_stride h)
1233 {
1234    return reg.vstride == v &&
1235           reg.width == w &&
1236           reg.hstride == h;
1237 }
1238 
1239 #define has_scalar_region(reg) \
1240    region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1241                   BRW_HORIZONTAL_STRIDE_0)
1242 
1243 /* brw_packed_float.c */
1244 int brw_float_to_vf(float f);
1245 float brw_vf_to_float(unsigned char vf);
1246 
1247 #ifdef __cplusplus
1248 }
1249 #endif
1250 
1251 #endif
1252