1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3bf215546Sopenharmony_ci Intel funded Tungsten Graphics to
4bf215546Sopenharmony_ci develop this 3D driver.
5bf215546Sopenharmony_ci
6bf215546Sopenharmony_ci Permission is hereby granted, free of charge, to any person obtaining
7bf215546Sopenharmony_ci a copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci distribute, sublicense, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci the following conditions:
13bf215546Sopenharmony_ci
14bf215546Sopenharmony_ci The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci next paragraph) shall be included in all copies or substantial
16bf215546Sopenharmony_ci portions of the Software.
17bf215546Sopenharmony_ci
18bf215546Sopenharmony_ci THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19bf215546Sopenharmony_ci EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21bf215546Sopenharmony_ci IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22bf215546Sopenharmony_ci LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23bf215546Sopenharmony_ci OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24bf215546Sopenharmony_ci WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci **********************************************************************/
27bf215546Sopenharmony_ci /*
28bf215546Sopenharmony_ci  * Authors:
29bf215546Sopenharmony_ci  *   Keith Whitwell <keithw@vmware.com>
30bf215546Sopenharmony_ci  */
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci/** @file brw_reg.h
33bf215546Sopenharmony_ci *
34bf215546Sopenharmony_ci * This file defines struct brw_reg, which is our representation for EU
35bf215546Sopenharmony_ci * registers.  They're not a hardware specific format, just an abstraction
36bf215546Sopenharmony_ci * that intends to capture the full flexibility of the hardware registers.
37bf215546Sopenharmony_ci *
38bf215546Sopenharmony_ci * The brw_eu_emit.c layer's brw_set_dest/brw_set_src[01] functions encode
39bf215546Sopenharmony_ci * the abstract brw_reg type into the actual hardware instruction encoding.
40bf215546Sopenharmony_ci */
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci#ifndef BRW_REG_H
43bf215546Sopenharmony_ci#define BRW_REG_H
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci#include <stdbool.h>
46bf215546Sopenharmony_ci#include "util/compiler.h"
47bf215546Sopenharmony_ci#include "main/macros.h"
48bf215546Sopenharmony_ci#include "program/prog_instruction.h"
49bf215546Sopenharmony_ci#include "brw_eu_defines.h"
50bf215546Sopenharmony_ci#include "brw_reg_type.h"
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci#ifdef __cplusplus
53bf215546Sopenharmony_ciextern "C" {
54bf215546Sopenharmony_ci#endif
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_cistruct intel_device_info;
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci/** Number of general purpose registers (VS, WM, etc) */
59bf215546Sopenharmony_ci#define BRW_MAX_GRF 128
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci/**
62bf215546Sopenharmony_ci * First GRF used for the MRF hack.
63bf215546Sopenharmony_ci *
64bf215546Sopenharmony_ci * On gfx7, MRFs are no longer used, and contiguous GRFs are used instead.  We
65bf215546Sopenharmony_ci * haven't converted our compiler to be aware of this, so it asks for MRFs and
66bf215546Sopenharmony_ci * brw_eu_emit.c quietly converts them to be accesses of the top GRFs.  The
67bf215546Sopenharmony_ci * register allocators have to be careful of this to avoid corrupting the "MRF"s
68bf215546Sopenharmony_ci * with actual GRF allocations.
69bf215546Sopenharmony_ci */
70bf215546Sopenharmony_ci#define GFX7_MRF_HACK_START 112
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci/** Number of message register file registers */
73bf215546Sopenharmony_ci#define BRW_MAX_MRF(gen) (gen == 6 ? 24 : 16)
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
76bf215546Sopenharmony_ci#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci#define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
79bf215546Sopenharmony_ci#define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
80bf215546Sopenharmony_ci#define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
81bf215546Sopenharmony_ci#define BRW_SWIZZLE_YYYY      BRW_SWIZZLE4(1,1,1,1)
82bf215546Sopenharmony_ci#define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
83bf215546Sopenharmony_ci#define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
84bf215546Sopenharmony_ci#define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
85bf215546Sopenharmony_ci#define BRW_SWIZZLE_YXYX      BRW_SWIZZLE4(1,0,1,0)
86bf215546Sopenharmony_ci#define BRW_SWIZZLE_XZXZ      BRW_SWIZZLE4(0,2,0,2)
87bf215546Sopenharmony_ci#define BRW_SWIZZLE_YZXW      BRW_SWIZZLE4(1,2,0,3)
88bf215546Sopenharmony_ci#define BRW_SWIZZLE_YWYW      BRW_SWIZZLE4(1,3,1,3)
89bf215546Sopenharmony_ci#define BRW_SWIZZLE_ZXYW      BRW_SWIZZLE4(2,0,1,3)
90bf215546Sopenharmony_ci#define BRW_SWIZZLE_ZWZW      BRW_SWIZZLE4(2,3,2,3)
91bf215546Sopenharmony_ci#define BRW_SWIZZLE_WZWZ      BRW_SWIZZLE4(3,2,3,2)
92bf215546Sopenharmony_ci#define BRW_SWIZZLE_WZYX      BRW_SWIZZLE4(3,2,1,0)
93bf215546Sopenharmony_ci#define BRW_SWIZZLE_XXZZ      BRW_SWIZZLE4(0,0,2,2)
94bf215546Sopenharmony_ci#define BRW_SWIZZLE_YYWW      BRW_SWIZZLE4(1,1,3,3)
95bf215546Sopenharmony_ci#define BRW_SWIZZLE_YXWZ      BRW_SWIZZLE4(1,0,3,2)
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci#define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
98bf215546Sopenharmony_ci#define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_cistatic inline bool
101bf215546Sopenharmony_cibrw_is_single_value_swizzle(unsigned swiz)
102bf215546Sopenharmony_ci{
103bf215546Sopenharmony_ci   return (swiz == BRW_SWIZZLE_XXXX ||
104bf215546Sopenharmony_ci           swiz == BRW_SWIZZLE_YYYY ||
105bf215546Sopenharmony_ci           swiz == BRW_SWIZZLE_ZZZZ ||
106bf215546Sopenharmony_ci           swiz == BRW_SWIZZLE_WWWW);
107bf215546Sopenharmony_ci}
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci/**
110bf215546Sopenharmony_ci * Compute the swizzle obtained from the application of \p swz0 on the result
111bf215546Sopenharmony_ci * of \p swz1.  The argument ordering is expected to match function
112bf215546Sopenharmony_ci * composition.
113bf215546Sopenharmony_ci */
114bf215546Sopenharmony_cistatic inline unsigned
115bf215546Sopenharmony_cibrw_compose_swizzle(unsigned swz0, unsigned swz1)
116bf215546Sopenharmony_ci{
117bf215546Sopenharmony_ci   return BRW_SWIZZLE4(
118bf215546Sopenharmony_ci      BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)),
119bf215546Sopenharmony_ci      BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)),
120bf215546Sopenharmony_ci      BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)),
121bf215546Sopenharmony_ci      BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3)));
122bf215546Sopenharmony_ci}
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci/**
125bf215546Sopenharmony_ci * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
126bf215546Sopenharmony_ci * (AKA image).
127bf215546Sopenharmony_ci */
128bf215546Sopenharmony_cistatic inline unsigned
129bf215546Sopenharmony_cibrw_apply_swizzle_to_mask(unsigned swz, unsigned mask)
130bf215546Sopenharmony_ci{
131bf215546Sopenharmony_ci   unsigned result = 0;
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci   for (unsigned i = 0; i < 4; i++) {
134bf215546Sopenharmony_ci      if (mask & (1 << BRW_GET_SWZ(swz, i)))
135bf215546Sopenharmony_ci         result |= 1 << i;
136bf215546Sopenharmony_ci   }
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci   return result;
139bf215546Sopenharmony_ci}
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci/**
142bf215546Sopenharmony_ci * Return the result of applying the inverse of swizzle \p swz to shuffle the
143bf215546Sopenharmony_ci * bits of \p mask (AKA preimage).  Useful to find out which components are
144bf215546Sopenharmony_ci * read from a swizzled source given the instruction writemask.
145bf215546Sopenharmony_ci */
146bf215546Sopenharmony_cistatic inline unsigned
147bf215546Sopenharmony_cibrw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask)
148bf215546Sopenharmony_ci{
149bf215546Sopenharmony_ci   unsigned result = 0;
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci   for (unsigned i = 0; i < 4; i++) {
152bf215546Sopenharmony_ci      if (mask & (1 << i))
153bf215546Sopenharmony_ci         result |= 1 << BRW_GET_SWZ(swz, i);
154bf215546Sopenharmony_ci   }
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci   return result;
157bf215546Sopenharmony_ci}
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci/**
160bf215546Sopenharmony_ci * Construct an identity swizzle for the set of enabled channels given by \p
161bf215546Sopenharmony_ci * mask.  The result will only reference channels enabled in the provided \p
162bf215546Sopenharmony_ci * mask, assuming that \p mask is non-zero.  The constructed swizzle will
163bf215546Sopenharmony_ci * satisfy the property that for any instruction OP and any mask:
164bf215546Sopenharmony_ci *
165bf215546Sopenharmony_ci *    brw_OP(p, brw_writemask(dst, mask),
166bf215546Sopenharmony_ci *           brw_swizzle(src, brw_swizzle_for_mask(mask)));
167bf215546Sopenharmony_ci *
168bf215546Sopenharmony_ci * will be equivalent to the same instruction without swizzle:
169bf215546Sopenharmony_ci *
170bf215546Sopenharmony_ci *    brw_OP(p, brw_writemask(dst, mask), src);
171bf215546Sopenharmony_ci */
172bf215546Sopenharmony_cistatic inline unsigned
173bf215546Sopenharmony_cibrw_swizzle_for_mask(unsigned mask)
174bf215546Sopenharmony_ci{
175bf215546Sopenharmony_ci   unsigned last = (mask ? ffs(mask) - 1 : 0);
176bf215546Sopenharmony_ci   unsigned swz[4];
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   for (unsigned i = 0; i < 4; i++)
179bf215546Sopenharmony_ci      last = swz[i] = (mask & (1 << i) ? i : last);
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci   return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
182bf215546Sopenharmony_ci}
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci/**
185bf215546Sopenharmony_ci * Construct an identity swizzle for the first \p n components of a vector.
186bf215546Sopenharmony_ci * When only a subset of channels of a vec4 are used we don't want to
187bf215546Sopenharmony_ci * reference the other channels, as that will tell optimization passes that
188bf215546Sopenharmony_ci * those other channels are used.
189bf215546Sopenharmony_ci */
190bf215546Sopenharmony_cistatic inline unsigned
191bf215546Sopenharmony_cibrw_swizzle_for_size(unsigned n)
192bf215546Sopenharmony_ci{
193bf215546Sopenharmony_ci   return brw_swizzle_for_mask((1 << n) - 1);
194bf215546Sopenharmony_ci}
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci/**
197bf215546Sopenharmony_ci * Converse of brw_swizzle_for_mask().  Returns the mask of components
198bf215546Sopenharmony_ci * accessed by the specified swizzle \p swz.
199bf215546Sopenharmony_ci */
200bf215546Sopenharmony_cistatic inline unsigned
201bf215546Sopenharmony_cibrw_mask_for_swizzle(unsigned swz)
202bf215546Sopenharmony_ci{
203bf215546Sopenharmony_ci   return brw_apply_inv_swizzle_to_mask(swz, ~0);
204bf215546Sopenharmony_ci}
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ciuint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz);
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci#define REG_SIZE (8*4)
209bf215546Sopenharmony_ci
210bf215546Sopenharmony_ci/* These aren't hardware structs, just something useful for us to pass around:
211bf215546Sopenharmony_ci *
212bf215546Sopenharmony_ci * Align1 operation has a lot of control over input ranges.  Used in
213bf215546Sopenharmony_ci * WM programs to implement shaders decomposed into "channel serial"
214bf215546Sopenharmony_ci * or "structure of array" form:
215bf215546Sopenharmony_ci */
216bf215546Sopenharmony_cistruct brw_reg {
217bf215546Sopenharmony_ci   union {
218bf215546Sopenharmony_ci      struct {
219bf215546Sopenharmony_ci         enum brw_reg_type type:4;
220bf215546Sopenharmony_ci         enum brw_reg_file file:3;      /* :2 hardware format */
221bf215546Sopenharmony_ci         unsigned negate:1;             /* source only */
222bf215546Sopenharmony_ci         unsigned abs:1;                /* source only */
223bf215546Sopenharmony_ci         unsigned address_mode:1;       /* relative addressing, hopefully! */
224bf215546Sopenharmony_ci         unsigned pad0:17;
225bf215546Sopenharmony_ci         unsigned subnr:5;              /* :1 in align16 */
226bf215546Sopenharmony_ci      };
227bf215546Sopenharmony_ci      uint32_t bits;
228bf215546Sopenharmony_ci   };
229bf215546Sopenharmony_ci
230bf215546Sopenharmony_ci   union {
231bf215546Sopenharmony_ci      struct {
232bf215546Sopenharmony_ci         unsigned nr;
233bf215546Sopenharmony_ci         unsigned swizzle:8;      /* src only, align16 only */
234bf215546Sopenharmony_ci         unsigned writemask:4;    /* dest only, align16 only */
235bf215546Sopenharmony_ci         int  indirect_offset:10; /* relative addressing offset */
236bf215546Sopenharmony_ci         unsigned vstride:4;      /* source only */
237bf215546Sopenharmony_ci         unsigned width:3;        /* src only, align1 only */
238bf215546Sopenharmony_ci         unsigned hstride:2;      /* align1 only */
239bf215546Sopenharmony_ci         unsigned pad1:1;
240bf215546Sopenharmony_ci      };
241bf215546Sopenharmony_ci
242bf215546Sopenharmony_ci      double df;
243bf215546Sopenharmony_ci      uint64_t u64;
244bf215546Sopenharmony_ci      int64_t d64;
245bf215546Sopenharmony_ci      float f;
246bf215546Sopenharmony_ci      int   d;
247bf215546Sopenharmony_ci      unsigned ud;
248bf215546Sopenharmony_ci   };
249bf215546Sopenharmony_ci};
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_cistatic inline bool
252bf215546Sopenharmony_cibrw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
253bf215546Sopenharmony_ci{
254bf215546Sopenharmony_ci   return a->bits == b->bits && a->u64 == b->u64;
255bf215546Sopenharmony_ci}
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_cistatic inline bool
258bf215546Sopenharmony_cibrw_regs_negative_equal(const struct brw_reg *a, const struct brw_reg *b)
259bf215546Sopenharmony_ci{
260bf215546Sopenharmony_ci   if (a->file == IMM) {
261bf215546Sopenharmony_ci      if (a->bits != b->bits)
262bf215546Sopenharmony_ci         return false;
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci      switch ((enum brw_reg_type) a->type) {
265bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_UQ:
266bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_Q:
267bf215546Sopenharmony_ci         return a->d64 == -b->d64;
268bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_DF:
269bf215546Sopenharmony_ci         return a->df == -b->df;
270bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_UD:
271bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_D:
272bf215546Sopenharmony_ci         return a->d == -b->d;
273bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_F:
274bf215546Sopenharmony_ci         return a->f == -b->f;
275bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_VF:
276bf215546Sopenharmony_ci         /* It is tempting to treat 0 as a negation of 0 (and -0 as a negation
277bf215546Sopenharmony_ci          * of -0).  There are occasions where 0 or -0 is used and the exact
278bf215546Sopenharmony_ci          * bit pattern is desired.  At the very least, changing this to allow
279bf215546Sopenharmony_ci          * 0 as a negation of 0 causes some fp64 tests to fail on IVB.
280bf215546Sopenharmony_ci          */
281bf215546Sopenharmony_ci         return a->ud == (b->ud ^ 0x80808080);
282bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_UW:
283bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_W:
284bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_UV:
285bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_V:
286bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_HF:
287bf215546Sopenharmony_ci         /* FINISHME: Implement support for these types once there is
288bf215546Sopenharmony_ci          * something in the compiler that can generate them.  Until then,
289bf215546Sopenharmony_ci          * they cannot be tested.
290bf215546Sopenharmony_ci          */
291bf215546Sopenharmony_ci         return false;
292bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_UB:
293bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_B:
294bf215546Sopenharmony_ci      case BRW_REGISTER_TYPE_NF:
295bf215546Sopenharmony_ci      default:
296bf215546Sopenharmony_ci         unreachable("not reached");
297bf215546Sopenharmony_ci      }
298bf215546Sopenharmony_ci   } else {
299bf215546Sopenharmony_ci      struct brw_reg tmp = *a;
300bf215546Sopenharmony_ci
301bf215546Sopenharmony_ci      tmp.negate = !tmp.negate;
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_ci      return brw_regs_equal(&tmp, b);
304bf215546Sopenharmony_ci   }
305bf215546Sopenharmony_ci}
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_cistruct brw_indirect {
308bf215546Sopenharmony_ci   unsigned addr_subnr:4;
309bf215546Sopenharmony_ci   int addr_offset:10;
310bf215546Sopenharmony_ci   unsigned pad:18;
311bf215546Sopenharmony_ci};
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_cistatic inline unsigned
315bf215546Sopenharmony_citype_sz(unsigned type)
316bf215546Sopenharmony_ci{
317bf215546Sopenharmony_ci   switch(type) {
318bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_UQ:
319bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_Q:
320bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_DF:
321bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_NF:
322bf215546Sopenharmony_ci      return 8;
323bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_UD:
324bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_D:
325bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_F:
326bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_VF:
327bf215546Sopenharmony_ci      return 4;
328bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_UW:
329bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_W:
330bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_HF:
331bf215546Sopenharmony_ci   /* [U]V components are 4-bit, but HW unpacks them to 16-bit (2 bytes) */
332bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_UV:
333bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_V:
334bf215546Sopenharmony_ci      return 2;
335bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_UB:
336bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_B:
337bf215546Sopenharmony_ci      return 1;
338bf215546Sopenharmony_ci   default:
339bf215546Sopenharmony_ci      unreachable("not reached");
340bf215546Sopenharmony_ci   }
341bf215546Sopenharmony_ci}
342bf215546Sopenharmony_ci
343bf215546Sopenharmony_cistatic inline enum brw_reg_type
344bf215546Sopenharmony_ciget_exec_type(const enum brw_reg_type type)
345bf215546Sopenharmony_ci{
346bf215546Sopenharmony_ci   switch (type) {
347bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_B:
348bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_V:
349bf215546Sopenharmony_ci      return BRW_REGISTER_TYPE_W;
350bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_UB:
351bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_UV:
352bf215546Sopenharmony_ci      return BRW_REGISTER_TYPE_UW;
353bf215546Sopenharmony_ci   case BRW_REGISTER_TYPE_VF:
354bf215546Sopenharmony_ci      return BRW_REGISTER_TYPE_F;
355bf215546Sopenharmony_ci   default:
356bf215546Sopenharmony_ci      return type;
357bf215546Sopenharmony_ci   }
358bf215546Sopenharmony_ci}
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci/**
361bf215546Sopenharmony_ci * Return an integer type of the requested size and signedness.
362bf215546Sopenharmony_ci */
363bf215546Sopenharmony_cistatic inline enum brw_reg_type
364bf215546Sopenharmony_cibrw_int_type(unsigned sz, bool is_signed)
365bf215546Sopenharmony_ci{
366bf215546Sopenharmony_ci   switch (sz) {
367bf215546Sopenharmony_ci   case 1:
368bf215546Sopenharmony_ci      return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
369bf215546Sopenharmony_ci   case 2:
370bf215546Sopenharmony_ci      return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
371bf215546Sopenharmony_ci   case 4:
372bf215546Sopenharmony_ci      return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
373bf215546Sopenharmony_ci   case 8:
374bf215546Sopenharmony_ci      return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
375bf215546Sopenharmony_ci   default:
376bf215546Sopenharmony_ci      unreachable("Not reached.");
377bf215546Sopenharmony_ci   }
378bf215546Sopenharmony_ci}
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci/**
381bf215546Sopenharmony_ci * Construct a brw_reg.
382bf215546Sopenharmony_ci * \param file      one of the BRW_x_REGISTER_FILE values
383bf215546Sopenharmony_ci * \param nr        register number/index
384bf215546Sopenharmony_ci * \param subnr     register sub number
385bf215546Sopenharmony_ci * \param negate    register negate modifier
386bf215546Sopenharmony_ci * \param abs       register abs modifier
387bf215546Sopenharmony_ci * \param type      one of BRW_REGISTER_TYPE_x
388bf215546Sopenharmony_ci * \param vstride   one of BRW_VERTICAL_STRIDE_x
389bf215546Sopenharmony_ci * \param width     one of BRW_WIDTH_x
390bf215546Sopenharmony_ci * \param hstride   one of BRW_HORIZONTAL_STRIDE_x
391bf215546Sopenharmony_ci * \param swizzle   one of BRW_SWIZZLE_x
392bf215546Sopenharmony_ci * \param writemask WRITEMASK_X/Y/Z/W bitfield
393bf215546Sopenharmony_ci */
394bf215546Sopenharmony_cistatic inline struct brw_reg
395bf215546Sopenharmony_cibrw_reg(enum brw_reg_file file,
396bf215546Sopenharmony_ci        unsigned nr,
397bf215546Sopenharmony_ci        unsigned subnr,
398bf215546Sopenharmony_ci        unsigned negate,
399bf215546Sopenharmony_ci        unsigned abs,
400bf215546Sopenharmony_ci        enum brw_reg_type type,
401bf215546Sopenharmony_ci        unsigned vstride,
402bf215546Sopenharmony_ci        unsigned width,
403bf215546Sopenharmony_ci        unsigned hstride,
404bf215546Sopenharmony_ci        unsigned swizzle,
405bf215546Sopenharmony_ci        unsigned writemask)
406bf215546Sopenharmony_ci{
407bf215546Sopenharmony_ci   struct brw_reg reg;
408bf215546Sopenharmony_ci   if (file == BRW_GENERAL_REGISTER_FILE)
409bf215546Sopenharmony_ci      assert(nr < BRW_MAX_GRF);
410bf215546Sopenharmony_ci   else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
411bf215546Sopenharmony_ci      assert(nr <= BRW_ARF_TIMESTAMP);
412bf215546Sopenharmony_ci   /* Asserting on the MRF register number requires to know the hardware gen
413bf215546Sopenharmony_ci    * (gfx6 has 24 MRF registers), which we don't know here, so we assert
414bf215546Sopenharmony_ci    * for that in the generators and in brw_eu_emit.c
415bf215546Sopenharmony_ci    */
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci   reg.type = type;
418bf215546Sopenharmony_ci   reg.file = file;
419bf215546Sopenharmony_ci   reg.negate = negate;
420bf215546Sopenharmony_ci   reg.abs = abs;
421bf215546Sopenharmony_ci   reg.address_mode = BRW_ADDRESS_DIRECT;
422bf215546Sopenharmony_ci   reg.pad0 = 0;
423bf215546Sopenharmony_ci   reg.subnr = subnr * type_sz(type);
424bf215546Sopenharmony_ci   reg.nr = nr;
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_ci   /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
427bf215546Sopenharmony_ci    * set swizzle and writemask to W, as the lower bits of subnr will
428bf215546Sopenharmony_ci    * be lost when converted to align16.  This is probably too much to
429bf215546Sopenharmony_ci    * keep track of as you'd want it adjusted by suboffset(), etc.
430bf215546Sopenharmony_ci    * Perhaps fix up when converting to align16?
431bf215546Sopenharmony_ci    */
432bf215546Sopenharmony_ci   reg.swizzle = swizzle;
433bf215546Sopenharmony_ci   reg.writemask = writemask;
434bf215546Sopenharmony_ci   reg.indirect_offset = 0;
435bf215546Sopenharmony_ci   reg.vstride = vstride;
436bf215546Sopenharmony_ci   reg.width = width;
437bf215546Sopenharmony_ci   reg.hstride = hstride;
438bf215546Sopenharmony_ci   reg.pad1 = 0;
439bf215546Sopenharmony_ci   return reg;
440bf215546Sopenharmony_ci}
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci/** Construct float[16] register */
443bf215546Sopenharmony_cistatic inline struct brw_reg
444bf215546Sopenharmony_cibrw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
445bf215546Sopenharmony_ci{
446bf215546Sopenharmony_ci   return brw_reg(file,
447bf215546Sopenharmony_ci                  nr,
448bf215546Sopenharmony_ci                  subnr,
449bf215546Sopenharmony_ci                  0,
450bf215546Sopenharmony_ci                  0,
451bf215546Sopenharmony_ci                  BRW_REGISTER_TYPE_F,
452bf215546Sopenharmony_ci                  BRW_VERTICAL_STRIDE_16,
453bf215546Sopenharmony_ci                  BRW_WIDTH_16,
454bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_1,
455bf215546Sopenharmony_ci                  BRW_SWIZZLE_XYZW,
456bf215546Sopenharmony_ci                  WRITEMASK_XYZW);
457bf215546Sopenharmony_ci}
458bf215546Sopenharmony_ci
459bf215546Sopenharmony_ci/** Construct float[8] register */
460bf215546Sopenharmony_cistatic inline struct brw_reg
461bf215546Sopenharmony_cibrw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
462bf215546Sopenharmony_ci{
463bf215546Sopenharmony_ci   return brw_reg(file,
464bf215546Sopenharmony_ci                  nr,
465bf215546Sopenharmony_ci                  subnr,
466bf215546Sopenharmony_ci                  0,
467bf215546Sopenharmony_ci                  0,
468bf215546Sopenharmony_ci                  BRW_REGISTER_TYPE_F,
469bf215546Sopenharmony_ci                  BRW_VERTICAL_STRIDE_8,
470bf215546Sopenharmony_ci                  BRW_WIDTH_8,
471bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_1,
472bf215546Sopenharmony_ci                  BRW_SWIZZLE_XYZW,
473bf215546Sopenharmony_ci                  WRITEMASK_XYZW);
474bf215546Sopenharmony_ci}
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ci/** Construct float[4] register */
477bf215546Sopenharmony_cistatic inline struct brw_reg
478bf215546Sopenharmony_cibrw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
479bf215546Sopenharmony_ci{
480bf215546Sopenharmony_ci   return brw_reg(file,
481bf215546Sopenharmony_ci                  nr,
482bf215546Sopenharmony_ci                  subnr,
483bf215546Sopenharmony_ci                  0,
484bf215546Sopenharmony_ci                  0,
485bf215546Sopenharmony_ci                  BRW_REGISTER_TYPE_F,
486bf215546Sopenharmony_ci                  BRW_VERTICAL_STRIDE_4,
487bf215546Sopenharmony_ci                  BRW_WIDTH_4,
488bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_1,
489bf215546Sopenharmony_ci                  BRW_SWIZZLE_XYZW,
490bf215546Sopenharmony_ci                  WRITEMASK_XYZW);
491bf215546Sopenharmony_ci}
492bf215546Sopenharmony_ci
493bf215546Sopenharmony_ci/** Construct float[2] register */
494bf215546Sopenharmony_cistatic inline struct brw_reg
495bf215546Sopenharmony_cibrw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
496bf215546Sopenharmony_ci{
497bf215546Sopenharmony_ci   return brw_reg(file,
498bf215546Sopenharmony_ci                  nr,
499bf215546Sopenharmony_ci                  subnr,
500bf215546Sopenharmony_ci                  0,
501bf215546Sopenharmony_ci                  0,
502bf215546Sopenharmony_ci                  BRW_REGISTER_TYPE_F,
503bf215546Sopenharmony_ci                  BRW_VERTICAL_STRIDE_2,
504bf215546Sopenharmony_ci                  BRW_WIDTH_2,
505bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_1,
506bf215546Sopenharmony_ci                  BRW_SWIZZLE_XYXY,
507bf215546Sopenharmony_ci                  WRITEMASK_XY);
508bf215546Sopenharmony_ci}
509bf215546Sopenharmony_ci
510bf215546Sopenharmony_ci/** Construct float[1] register */
511bf215546Sopenharmony_cistatic inline struct brw_reg
512bf215546Sopenharmony_cibrw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
513bf215546Sopenharmony_ci{
514bf215546Sopenharmony_ci   return brw_reg(file,
515bf215546Sopenharmony_ci                  nr,
516bf215546Sopenharmony_ci                  subnr,
517bf215546Sopenharmony_ci                  0,
518bf215546Sopenharmony_ci                  0,
519bf215546Sopenharmony_ci                  BRW_REGISTER_TYPE_F,
520bf215546Sopenharmony_ci                  BRW_VERTICAL_STRIDE_0,
521bf215546Sopenharmony_ci                  BRW_WIDTH_1,
522bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_0,
523bf215546Sopenharmony_ci                  BRW_SWIZZLE_XXXX,
524bf215546Sopenharmony_ci                  WRITEMASK_X);
525bf215546Sopenharmony_ci}
526bf215546Sopenharmony_ci
527bf215546Sopenharmony_cistatic inline struct brw_reg
528bf215546Sopenharmony_cibrw_vecn_reg(unsigned width, enum brw_reg_file file,
529bf215546Sopenharmony_ci             unsigned nr, unsigned subnr)
530bf215546Sopenharmony_ci{
531bf215546Sopenharmony_ci   switch (width) {
532bf215546Sopenharmony_ci   case 1:
533bf215546Sopenharmony_ci      return brw_vec1_reg(file, nr, subnr);
534bf215546Sopenharmony_ci   case 2:
535bf215546Sopenharmony_ci      return brw_vec2_reg(file, nr, subnr);
536bf215546Sopenharmony_ci   case 4:
537bf215546Sopenharmony_ci      return brw_vec4_reg(file, nr, subnr);
538bf215546Sopenharmony_ci   case 8:
539bf215546Sopenharmony_ci      return brw_vec8_reg(file, nr, subnr);
540bf215546Sopenharmony_ci   case 16:
541bf215546Sopenharmony_ci      return brw_vec16_reg(file, nr, subnr);
542bf215546Sopenharmony_ci   default:
543bf215546Sopenharmony_ci      unreachable("Invalid register width");
544bf215546Sopenharmony_ci   }
545bf215546Sopenharmony_ci}
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_cistatic inline struct brw_reg
548bf215546Sopenharmony_ciretype(struct brw_reg reg, enum brw_reg_type type)
549bf215546Sopenharmony_ci{
550bf215546Sopenharmony_ci   reg.type = type;
551bf215546Sopenharmony_ci   return reg;
552bf215546Sopenharmony_ci}
553bf215546Sopenharmony_ci
554bf215546Sopenharmony_cistatic inline struct brw_reg
555bf215546Sopenharmony_cifirsthalf(struct brw_reg reg)
556bf215546Sopenharmony_ci{
557bf215546Sopenharmony_ci   return reg;
558bf215546Sopenharmony_ci}
559bf215546Sopenharmony_ci
560bf215546Sopenharmony_cistatic inline struct brw_reg
561bf215546Sopenharmony_cisechalf(struct brw_reg reg)
562bf215546Sopenharmony_ci{
563bf215546Sopenharmony_ci   if (reg.vstride)
564bf215546Sopenharmony_ci      reg.nr++;
565bf215546Sopenharmony_ci   return reg;
566bf215546Sopenharmony_ci}
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_cistatic inline struct brw_reg
569bf215546Sopenharmony_cioffset(struct brw_reg reg, unsigned delta)
570bf215546Sopenharmony_ci{
571bf215546Sopenharmony_ci   reg.nr += delta;
572bf215546Sopenharmony_ci   return reg;
573bf215546Sopenharmony_ci}
574bf215546Sopenharmony_ci
575bf215546Sopenharmony_ci
576bf215546Sopenharmony_cistatic inline struct brw_reg
577bf215546Sopenharmony_cibyte_offset(struct brw_reg reg, unsigned bytes)
578bf215546Sopenharmony_ci{
579bf215546Sopenharmony_ci   unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
580bf215546Sopenharmony_ci   reg.nr = newoffset / REG_SIZE;
581bf215546Sopenharmony_ci   reg.subnr = newoffset % REG_SIZE;
582bf215546Sopenharmony_ci   return reg;
583bf215546Sopenharmony_ci}
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_cistatic inline struct brw_reg
586bf215546Sopenharmony_cisuboffset(struct brw_reg reg, unsigned delta)
587bf215546Sopenharmony_ci{
588bf215546Sopenharmony_ci   return byte_offset(reg, delta * type_sz(reg.type));
589bf215546Sopenharmony_ci}
590bf215546Sopenharmony_ci
591bf215546Sopenharmony_ci/** Construct unsigned word[16] register */
592bf215546Sopenharmony_cistatic inline struct brw_reg
593bf215546Sopenharmony_cibrw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
594bf215546Sopenharmony_ci{
595bf215546Sopenharmony_ci   return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
596bf215546Sopenharmony_ci}
597bf215546Sopenharmony_ci
598bf215546Sopenharmony_ci/** Construct unsigned word[8] register */
599bf215546Sopenharmony_cistatic inline struct brw_reg
600bf215546Sopenharmony_cibrw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
601bf215546Sopenharmony_ci{
602bf215546Sopenharmony_ci   return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
603bf215546Sopenharmony_ci}
604bf215546Sopenharmony_ci
605bf215546Sopenharmony_ci/** Construct unsigned word[1] register */
606bf215546Sopenharmony_cistatic inline struct brw_reg
607bf215546Sopenharmony_cibrw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
608bf215546Sopenharmony_ci{
609bf215546Sopenharmony_ci   return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
610bf215546Sopenharmony_ci}
611bf215546Sopenharmony_ci
612bf215546Sopenharmony_cistatic inline struct brw_reg
613bf215546Sopenharmony_cibrw_ud1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
614bf215546Sopenharmony_ci{
615bf215546Sopenharmony_ci   return retype(brw_vec1_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
616bf215546Sopenharmony_ci}
617bf215546Sopenharmony_ci
618bf215546Sopenharmony_cistatic inline struct brw_reg
619bf215546Sopenharmony_cibrw_imm_reg(enum brw_reg_type type)
620bf215546Sopenharmony_ci{
621bf215546Sopenharmony_ci   return brw_reg(BRW_IMMEDIATE_VALUE,
622bf215546Sopenharmony_ci                  0,
623bf215546Sopenharmony_ci                  0,
624bf215546Sopenharmony_ci                  0,
625bf215546Sopenharmony_ci                  0,
626bf215546Sopenharmony_ci                  type,
627bf215546Sopenharmony_ci                  BRW_VERTICAL_STRIDE_0,
628bf215546Sopenharmony_ci                  BRW_WIDTH_1,
629bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_0,
630bf215546Sopenharmony_ci                  0,
631bf215546Sopenharmony_ci                  0);
632bf215546Sopenharmony_ci}
633bf215546Sopenharmony_ci
634bf215546Sopenharmony_ci/** Construct float immediate register */
635bf215546Sopenharmony_cistatic inline struct brw_reg
636bf215546Sopenharmony_cibrw_imm_df(double df)
637bf215546Sopenharmony_ci{
638bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
639bf215546Sopenharmony_ci   imm.df = df;
640bf215546Sopenharmony_ci   return imm;
641bf215546Sopenharmony_ci}
642bf215546Sopenharmony_ci
643bf215546Sopenharmony_cistatic inline struct brw_reg
644bf215546Sopenharmony_cibrw_imm_u64(uint64_t u64)
645bf215546Sopenharmony_ci{
646bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
647bf215546Sopenharmony_ci   imm.u64 = u64;
648bf215546Sopenharmony_ci   return imm;
649bf215546Sopenharmony_ci}
650bf215546Sopenharmony_ci
651bf215546Sopenharmony_cistatic inline struct brw_reg
652bf215546Sopenharmony_cibrw_imm_f(float f)
653bf215546Sopenharmony_ci{
654bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
655bf215546Sopenharmony_ci   imm.f = f;
656bf215546Sopenharmony_ci   return imm;
657bf215546Sopenharmony_ci}
658bf215546Sopenharmony_ci
659bf215546Sopenharmony_ci/** Construct int64_t immediate register */
660bf215546Sopenharmony_cistatic inline struct brw_reg
661bf215546Sopenharmony_cibrw_imm_q(int64_t q)
662bf215546Sopenharmony_ci{
663bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_Q);
664bf215546Sopenharmony_ci   imm.d64 = q;
665bf215546Sopenharmony_ci   return imm;
666bf215546Sopenharmony_ci}
667bf215546Sopenharmony_ci
668bf215546Sopenharmony_ci/** Construct int64_t immediate register */
669bf215546Sopenharmony_cistatic inline struct brw_reg
670bf215546Sopenharmony_cibrw_imm_uq(uint64_t uq)
671bf215546Sopenharmony_ci{
672bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
673bf215546Sopenharmony_ci   imm.u64 = uq;
674bf215546Sopenharmony_ci   return imm;
675bf215546Sopenharmony_ci}
676bf215546Sopenharmony_ci
677bf215546Sopenharmony_ci/** Construct integer immediate register */
678bf215546Sopenharmony_cistatic inline struct brw_reg
679bf215546Sopenharmony_cibrw_imm_d(int d)
680bf215546Sopenharmony_ci{
681bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
682bf215546Sopenharmony_ci   imm.d = d;
683bf215546Sopenharmony_ci   return imm;
684bf215546Sopenharmony_ci}
685bf215546Sopenharmony_ci
686bf215546Sopenharmony_ci/** Construct uint immediate register */
687bf215546Sopenharmony_cistatic inline struct brw_reg
688bf215546Sopenharmony_cibrw_imm_ud(unsigned ud)
689bf215546Sopenharmony_ci{
690bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
691bf215546Sopenharmony_ci   imm.ud = ud;
692bf215546Sopenharmony_ci   return imm;
693bf215546Sopenharmony_ci}
694bf215546Sopenharmony_ci
695bf215546Sopenharmony_ci/** Construct ushort immediate register */
696bf215546Sopenharmony_cistatic inline struct brw_reg
697bf215546Sopenharmony_cibrw_imm_uw(uint16_t uw)
698bf215546Sopenharmony_ci{
699bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
700bf215546Sopenharmony_ci   imm.ud = uw | (uw << 16);
701bf215546Sopenharmony_ci   return imm;
702bf215546Sopenharmony_ci}
703bf215546Sopenharmony_ci
704bf215546Sopenharmony_ci/** Construct short immediate register */
705bf215546Sopenharmony_cistatic inline struct brw_reg
706bf215546Sopenharmony_cibrw_imm_w(int16_t w)
707bf215546Sopenharmony_ci{
708bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
709bf215546Sopenharmony_ci   imm.ud = (uint16_t)w | (uint32_t)(uint16_t)w << 16;
710bf215546Sopenharmony_ci   return imm;
711bf215546Sopenharmony_ci}
712bf215546Sopenharmony_ci
713bf215546Sopenharmony_ci/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
714bf215546Sopenharmony_ci * numbers alias with _V and _VF below:
715bf215546Sopenharmony_ci */
716bf215546Sopenharmony_ci
717bf215546Sopenharmony_ci/** Construct vector of eight signed half-byte values */
718bf215546Sopenharmony_cistatic inline struct brw_reg
719bf215546Sopenharmony_cibrw_imm_v(unsigned v)
720bf215546Sopenharmony_ci{
721bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
722bf215546Sopenharmony_ci   imm.ud = v;
723bf215546Sopenharmony_ci   return imm;
724bf215546Sopenharmony_ci}
725bf215546Sopenharmony_ci
726bf215546Sopenharmony_ci/** Construct vector of eight unsigned half-byte values */
727bf215546Sopenharmony_cistatic inline struct brw_reg
728bf215546Sopenharmony_cibrw_imm_uv(unsigned uv)
729bf215546Sopenharmony_ci{
730bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
731bf215546Sopenharmony_ci   imm.ud = uv;
732bf215546Sopenharmony_ci   return imm;
733bf215546Sopenharmony_ci}
734bf215546Sopenharmony_ci
735bf215546Sopenharmony_ci/** Construct vector of four 8-bit float values */
736bf215546Sopenharmony_cistatic inline struct brw_reg
737bf215546Sopenharmony_cibrw_imm_vf(unsigned v)
738bf215546Sopenharmony_ci{
739bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
740bf215546Sopenharmony_ci   imm.ud = v;
741bf215546Sopenharmony_ci   return imm;
742bf215546Sopenharmony_ci}
743bf215546Sopenharmony_ci
744bf215546Sopenharmony_cistatic inline struct brw_reg
745bf215546Sopenharmony_cibrw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
746bf215546Sopenharmony_ci{
747bf215546Sopenharmony_ci   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
748bf215546Sopenharmony_ci   imm.vstride = BRW_VERTICAL_STRIDE_0;
749bf215546Sopenharmony_ci   imm.width = BRW_WIDTH_4;
750bf215546Sopenharmony_ci   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
751bf215546Sopenharmony_ci   imm.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
752bf215546Sopenharmony_ci   return imm;
753bf215546Sopenharmony_ci}
754bf215546Sopenharmony_ci
755bf215546Sopenharmony_ci
756bf215546Sopenharmony_cistatic inline struct brw_reg
757bf215546Sopenharmony_cibrw_address(struct brw_reg reg)
758bf215546Sopenharmony_ci{
759bf215546Sopenharmony_ci   return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
760bf215546Sopenharmony_ci}
761bf215546Sopenharmony_ci
762bf215546Sopenharmony_ci/** Construct float[1] general-purpose register */
763bf215546Sopenharmony_cistatic inline struct brw_reg
764bf215546Sopenharmony_cibrw_vec1_grf(unsigned nr, unsigned subnr)
765bf215546Sopenharmony_ci{
766bf215546Sopenharmony_ci   return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
767bf215546Sopenharmony_ci}
768bf215546Sopenharmony_ci
769bf215546Sopenharmony_ci/** Construct float[2] general-purpose register */
770bf215546Sopenharmony_cistatic inline struct brw_reg
771bf215546Sopenharmony_cibrw_vec2_grf(unsigned nr, unsigned subnr)
772bf215546Sopenharmony_ci{
773bf215546Sopenharmony_ci   return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
774bf215546Sopenharmony_ci}
775bf215546Sopenharmony_ci
776bf215546Sopenharmony_ci/** Construct float[4] general-purpose register */
777bf215546Sopenharmony_cistatic inline struct brw_reg
778bf215546Sopenharmony_cibrw_vec4_grf(unsigned nr, unsigned subnr)
779bf215546Sopenharmony_ci{
780bf215546Sopenharmony_ci   return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
781bf215546Sopenharmony_ci}
782bf215546Sopenharmony_ci
783bf215546Sopenharmony_ci/** Construct float[8] general-purpose register */
784bf215546Sopenharmony_cistatic inline struct brw_reg
785bf215546Sopenharmony_cibrw_vec8_grf(unsigned nr, unsigned subnr)
786bf215546Sopenharmony_ci{
787bf215546Sopenharmony_ci   return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
788bf215546Sopenharmony_ci}
789bf215546Sopenharmony_ci
790bf215546Sopenharmony_ci/** Construct float[16] general-purpose register */
791bf215546Sopenharmony_cistatic inline struct brw_reg
792bf215546Sopenharmony_cibrw_vec16_grf(unsigned nr, unsigned subnr)
793bf215546Sopenharmony_ci{
794bf215546Sopenharmony_ci   return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
795bf215546Sopenharmony_ci}
796bf215546Sopenharmony_ci
797bf215546Sopenharmony_cistatic inline struct brw_reg
798bf215546Sopenharmony_cibrw_vecn_grf(unsigned width, unsigned nr, unsigned subnr)
799bf215546Sopenharmony_ci{
800bf215546Sopenharmony_ci   return brw_vecn_reg(width, BRW_GENERAL_REGISTER_FILE, nr, subnr);
801bf215546Sopenharmony_ci}
802bf215546Sopenharmony_ci
803bf215546Sopenharmony_ci
804bf215546Sopenharmony_cistatic inline struct brw_reg
805bf215546Sopenharmony_cibrw_uw8_grf(unsigned nr, unsigned subnr)
806bf215546Sopenharmony_ci{
807bf215546Sopenharmony_ci   return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
808bf215546Sopenharmony_ci}
809bf215546Sopenharmony_ci
810bf215546Sopenharmony_cistatic inline struct brw_reg
811bf215546Sopenharmony_cibrw_uw16_grf(unsigned nr, unsigned subnr)
812bf215546Sopenharmony_ci{
813bf215546Sopenharmony_ci   return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
814bf215546Sopenharmony_ci}
815bf215546Sopenharmony_ci
816bf215546Sopenharmony_ci
817bf215546Sopenharmony_ci/** Construct null register (usually used for setting condition codes) */
818bf215546Sopenharmony_cistatic inline struct brw_reg
819bf215546Sopenharmony_cibrw_null_reg(void)
820bf215546Sopenharmony_ci{
821bf215546Sopenharmony_ci   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
822bf215546Sopenharmony_ci}
823bf215546Sopenharmony_ci
824bf215546Sopenharmony_cistatic inline struct brw_reg
825bf215546Sopenharmony_cibrw_null_vec(unsigned width)
826bf215546Sopenharmony_ci{
827bf215546Sopenharmony_ci   return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
828bf215546Sopenharmony_ci}
829bf215546Sopenharmony_ci
830bf215546Sopenharmony_cistatic inline struct brw_reg
831bf215546Sopenharmony_cibrw_address_reg(unsigned subnr)
832bf215546Sopenharmony_ci{
833bf215546Sopenharmony_ci   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
834bf215546Sopenharmony_ci}
835bf215546Sopenharmony_ci
836bf215546Sopenharmony_cistatic inline struct brw_reg
837bf215546Sopenharmony_cibrw_tdr_reg(void)
838bf215546Sopenharmony_ci{
839bf215546Sopenharmony_ci   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_TDR, 0);
840bf215546Sopenharmony_ci}
841bf215546Sopenharmony_ci
842bf215546Sopenharmony_ci/* If/else instructions break in align16 mode if writemask & swizzle
843bf215546Sopenharmony_ci * aren't xyzw.  This goes against the convention for other scalar
844bf215546Sopenharmony_ci * regs:
845bf215546Sopenharmony_ci */
846bf215546Sopenharmony_cistatic inline struct brw_reg
847bf215546Sopenharmony_cibrw_ip_reg(void)
848bf215546Sopenharmony_ci{
849bf215546Sopenharmony_ci   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
850bf215546Sopenharmony_ci                  BRW_ARF_IP,
851bf215546Sopenharmony_ci                  0,
852bf215546Sopenharmony_ci                  0,
853bf215546Sopenharmony_ci                  0,
854bf215546Sopenharmony_ci                  BRW_REGISTER_TYPE_UD,
855bf215546Sopenharmony_ci                  BRW_VERTICAL_STRIDE_4, /* ? */
856bf215546Sopenharmony_ci                  BRW_WIDTH_1,
857bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_0,
858bf215546Sopenharmony_ci                  BRW_SWIZZLE_XYZW, /* NOTE! */
859bf215546Sopenharmony_ci                  WRITEMASK_XYZW); /* NOTE! */
860bf215546Sopenharmony_ci}
861bf215546Sopenharmony_ci
862bf215546Sopenharmony_cistatic inline struct brw_reg
863bf215546Sopenharmony_cibrw_notification_reg(void)
864bf215546Sopenharmony_ci{
865bf215546Sopenharmony_ci   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
866bf215546Sopenharmony_ci                  BRW_ARF_NOTIFICATION_COUNT,
867bf215546Sopenharmony_ci                  0,
868bf215546Sopenharmony_ci                  0,
869bf215546Sopenharmony_ci                  0,
870bf215546Sopenharmony_ci                  BRW_REGISTER_TYPE_UD,
871bf215546Sopenharmony_ci                  BRW_VERTICAL_STRIDE_0,
872bf215546Sopenharmony_ci                  BRW_WIDTH_1,
873bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_0,
874bf215546Sopenharmony_ci                  BRW_SWIZZLE_XXXX,
875bf215546Sopenharmony_ci                  WRITEMASK_X);
876bf215546Sopenharmony_ci}
877bf215546Sopenharmony_ci
878bf215546Sopenharmony_cistatic inline struct brw_reg
879bf215546Sopenharmony_cibrw_cr0_reg(unsigned subnr)
880bf215546Sopenharmony_ci{
881bf215546Sopenharmony_ci   return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_CONTROL, subnr);
882bf215546Sopenharmony_ci}
883bf215546Sopenharmony_ci
884bf215546Sopenharmony_cistatic inline struct brw_reg
885bf215546Sopenharmony_cibrw_sr0_reg(unsigned subnr)
886bf215546Sopenharmony_ci{
887bf215546Sopenharmony_ci   return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_STATE, subnr);
888bf215546Sopenharmony_ci}
889bf215546Sopenharmony_ci
890bf215546Sopenharmony_cistatic inline struct brw_reg
891bf215546Sopenharmony_cibrw_acc_reg(unsigned width)
892bf215546Sopenharmony_ci{
893bf215546Sopenharmony_ci   return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
894bf215546Sopenharmony_ci                       BRW_ARF_ACCUMULATOR, 0);
895bf215546Sopenharmony_ci}
896bf215546Sopenharmony_ci
897bf215546Sopenharmony_cistatic inline struct brw_reg
898bf215546Sopenharmony_cibrw_flag_reg(int reg, int subreg)
899bf215546Sopenharmony_ci{
900bf215546Sopenharmony_ci   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
901bf215546Sopenharmony_ci                      BRW_ARF_FLAG + reg, subreg);
902bf215546Sopenharmony_ci}
903bf215546Sopenharmony_ci
904bf215546Sopenharmony_cistatic inline struct brw_reg
905bf215546Sopenharmony_cibrw_flag_subreg(unsigned subreg)
906bf215546Sopenharmony_ci{
907bf215546Sopenharmony_ci   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
908bf215546Sopenharmony_ci                      BRW_ARF_FLAG + subreg / 2, subreg % 2);
909bf215546Sopenharmony_ci}
910bf215546Sopenharmony_ci
911bf215546Sopenharmony_ci/**
912bf215546Sopenharmony_ci * Return the mask register present in Gfx4-5, or the related register present
913bf215546Sopenharmony_ci * in Gfx7.5 and later hardware referred to as "channel enable" register in
914bf215546Sopenharmony_ci * the documentation.
915bf215546Sopenharmony_ci */
916bf215546Sopenharmony_cistatic inline struct brw_reg
917bf215546Sopenharmony_cibrw_mask_reg(unsigned subnr)
918bf215546Sopenharmony_ci{
919bf215546Sopenharmony_ci   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
920bf215546Sopenharmony_ci}
921bf215546Sopenharmony_ci
922bf215546Sopenharmony_cistatic inline struct brw_reg
923bf215546Sopenharmony_cibrw_vmask_reg()
924bf215546Sopenharmony_ci{
925bf215546Sopenharmony_ci   return brw_sr0_reg(3);
926bf215546Sopenharmony_ci}
927bf215546Sopenharmony_ci
928bf215546Sopenharmony_cistatic inline struct brw_reg
929bf215546Sopenharmony_cibrw_dmask_reg()
930bf215546Sopenharmony_ci{
931bf215546Sopenharmony_ci   return brw_sr0_reg(2);
932bf215546Sopenharmony_ci}
933bf215546Sopenharmony_ci
934bf215546Sopenharmony_cistatic inline struct brw_reg
935bf215546Sopenharmony_cibrw_mask_stack_reg(unsigned subnr)
936bf215546Sopenharmony_ci{
937bf215546Sopenharmony_ci   return suboffset(retype(brw_vec16_reg(BRW_ARCHITECTURE_REGISTER_FILE,
938bf215546Sopenharmony_ci                                         BRW_ARF_MASK_STACK, 0),
939bf215546Sopenharmony_ci                           BRW_REGISTER_TYPE_UB), subnr);
940bf215546Sopenharmony_ci}
941bf215546Sopenharmony_ci
942bf215546Sopenharmony_cistatic inline struct brw_reg
943bf215546Sopenharmony_cibrw_mask_stack_depth_reg(unsigned subnr)
944bf215546Sopenharmony_ci{
945bf215546Sopenharmony_ci   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
946bf215546Sopenharmony_ci                      BRW_ARF_MASK_STACK_DEPTH, subnr);
947bf215546Sopenharmony_ci}
948bf215546Sopenharmony_ci
949bf215546Sopenharmony_cistatic inline struct brw_reg
950bf215546Sopenharmony_cibrw_message_reg(unsigned nr)
951bf215546Sopenharmony_ci{
952bf215546Sopenharmony_ci   return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
953bf215546Sopenharmony_ci}
954bf215546Sopenharmony_ci
955bf215546Sopenharmony_cistatic inline struct brw_reg
956bf215546Sopenharmony_cibrw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
957bf215546Sopenharmony_ci{
958bf215546Sopenharmony_ci   return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
959bf215546Sopenharmony_ci                 BRW_REGISTER_TYPE_UD);
960bf215546Sopenharmony_ci}
961bf215546Sopenharmony_ci
962bf215546Sopenharmony_ci/* This is almost always called with a numeric constant argument, so
963bf215546Sopenharmony_ci * make things easy to evaluate at compile time:
964bf215546Sopenharmony_ci */
965bf215546Sopenharmony_cistatic inline unsigned cvt(unsigned val)
966bf215546Sopenharmony_ci{
967bf215546Sopenharmony_ci   switch (val) {
968bf215546Sopenharmony_ci   case 0: return 0;
969bf215546Sopenharmony_ci   case 1: return 1;
970bf215546Sopenharmony_ci   case 2: return 2;
971bf215546Sopenharmony_ci   case 4: return 3;
972bf215546Sopenharmony_ci   case 8: return 4;
973bf215546Sopenharmony_ci   case 16: return 5;
974bf215546Sopenharmony_ci   case 32: return 6;
975bf215546Sopenharmony_ci   }
976bf215546Sopenharmony_ci   return 0;
977bf215546Sopenharmony_ci}
978bf215546Sopenharmony_ci
979bf215546Sopenharmony_cistatic inline struct brw_reg
980bf215546Sopenharmony_cistride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
981bf215546Sopenharmony_ci{
982bf215546Sopenharmony_ci   reg.vstride = cvt(vstride);
983bf215546Sopenharmony_ci   reg.width = cvt(width) - 1;
984bf215546Sopenharmony_ci   reg.hstride = cvt(hstride);
985bf215546Sopenharmony_ci   return reg;
986bf215546Sopenharmony_ci}
987bf215546Sopenharmony_ci
988bf215546Sopenharmony_ci/**
989bf215546Sopenharmony_ci * Multiply the vertical and horizontal stride of a register by the given
990bf215546Sopenharmony_ci * factor \a s.
991bf215546Sopenharmony_ci */
992bf215546Sopenharmony_cistatic inline struct brw_reg
993bf215546Sopenharmony_cispread(struct brw_reg reg, unsigned s)
994bf215546Sopenharmony_ci{
995bf215546Sopenharmony_ci   if (s) {
996bf215546Sopenharmony_ci      assert(util_is_power_of_two_nonzero(s));
997bf215546Sopenharmony_ci
998bf215546Sopenharmony_ci      if (reg.hstride)
999bf215546Sopenharmony_ci         reg.hstride += cvt(s) - 1;
1000bf215546Sopenharmony_ci
1001bf215546Sopenharmony_ci      if (reg.vstride)
1002bf215546Sopenharmony_ci         reg.vstride += cvt(s) - 1;
1003bf215546Sopenharmony_ci
1004bf215546Sopenharmony_ci      return reg;
1005bf215546Sopenharmony_ci   } else {
1006bf215546Sopenharmony_ci      return stride(reg, 0, 1, 0);
1007bf215546Sopenharmony_ci   }
1008bf215546Sopenharmony_ci}
1009bf215546Sopenharmony_ci
1010bf215546Sopenharmony_ci/**
1011bf215546Sopenharmony_ci * Reinterpret each channel of register \p reg as a vector of values of the
1012bf215546Sopenharmony_ci * given smaller type and take the i-th subcomponent from each.
1013bf215546Sopenharmony_ci */
1014bf215546Sopenharmony_cistatic inline struct brw_reg
1015bf215546Sopenharmony_cisubscript(struct brw_reg reg, enum brw_reg_type type, unsigned i)
1016bf215546Sopenharmony_ci{
1017bf215546Sopenharmony_ci   unsigned scale = type_sz(reg.type) / type_sz(type);
1018bf215546Sopenharmony_ci   assert(scale >= 1 && i < scale);
1019bf215546Sopenharmony_ci
1020bf215546Sopenharmony_ci   if (reg.file == IMM) {
1021bf215546Sopenharmony_ci      unsigned bit_size = type_sz(type) * 8;
1022bf215546Sopenharmony_ci      reg.u64 >>= i * bit_size;
1023bf215546Sopenharmony_ci      reg.u64 &= BITFIELD64_MASK(bit_size);
1024bf215546Sopenharmony_ci      if (bit_size <= 16)
1025bf215546Sopenharmony_ci         reg.u64 |= reg.u64 << 16;
1026bf215546Sopenharmony_ci      return retype(reg, type);
1027bf215546Sopenharmony_ci   }
1028bf215546Sopenharmony_ci
1029bf215546Sopenharmony_ci   return suboffset(retype(spread(reg, scale), type), i);
1030bf215546Sopenharmony_ci}
1031bf215546Sopenharmony_ci
1032bf215546Sopenharmony_cistatic inline struct brw_reg
1033bf215546Sopenharmony_civec16(struct brw_reg reg)
1034bf215546Sopenharmony_ci{
1035bf215546Sopenharmony_ci   return stride(reg, 16,16,1);
1036bf215546Sopenharmony_ci}
1037bf215546Sopenharmony_ci
1038bf215546Sopenharmony_cistatic inline struct brw_reg
1039bf215546Sopenharmony_civec8(struct brw_reg reg)
1040bf215546Sopenharmony_ci{
1041bf215546Sopenharmony_ci   return stride(reg, 8,8,1);
1042bf215546Sopenharmony_ci}
1043bf215546Sopenharmony_ci
1044bf215546Sopenharmony_cistatic inline struct brw_reg
1045bf215546Sopenharmony_civec4(struct brw_reg reg)
1046bf215546Sopenharmony_ci{
1047bf215546Sopenharmony_ci   return stride(reg, 4,4,1);
1048bf215546Sopenharmony_ci}
1049bf215546Sopenharmony_ci
1050bf215546Sopenharmony_cistatic inline struct brw_reg
1051bf215546Sopenharmony_civec2(struct brw_reg reg)
1052bf215546Sopenharmony_ci{
1053bf215546Sopenharmony_ci   return stride(reg, 2,2,1);
1054bf215546Sopenharmony_ci}
1055bf215546Sopenharmony_ci
1056bf215546Sopenharmony_cistatic inline struct brw_reg
1057bf215546Sopenharmony_civec1(struct brw_reg reg)
1058bf215546Sopenharmony_ci{
1059bf215546Sopenharmony_ci   return stride(reg, 0,1,0);
1060bf215546Sopenharmony_ci}
1061bf215546Sopenharmony_ci
1062bf215546Sopenharmony_ci
1063bf215546Sopenharmony_cistatic inline struct brw_reg
1064bf215546Sopenharmony_ciget_element(struct brw_reg reg, unsigned elt)
1065bf215546Sopenharmony_ci{
1066bf215546Sopenharmony_ci   return vec1(suboffset(reg, elt));
1067bf215546Sopenharmony_ci}
1068bf215546Sopenharmony_ci
1069bf215546Sopenharmony_cistatic inline struct brw_reg
1070bf215546Sopenharmony_ciget_element_ud(struct brw_reg reg, unsigned elt)
1071bf215546Sopenharmony_ci{
1072bf215546Sopenharmony_ci   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
1073bf215546Sopenharmony_ci}
1074bf215546Sopenharmony_ci
1075bf215546Sopenharmony_cistatic inline struct brw_reg
1076bf215546Sopenharmony_ciget_element_d(struct brw_reg reg, unsigned elt)
1077bf215546Sopenharmony_ci{
1078bf215546Sopenharmony_ci   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
1079bf215546Sopenharmony_ci}
1080bf215546Sopenharmony_ci
1081bf215546Sopenharmony_cistatic inline struct brw_reg
1082bf215546Sopenharmony_cibrw_swizzle(struct brw_reg reg, unsigned swz)
1083bf215546Sopenharmony_ci{
1084bf215546Sopenharmony_ci   if (reg.file == BRW_IMMEDIATE_VALUE)
1085bf215546Sopenharmony_ci      reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
1086bf215546Sopenharmony_ci   else
1087bf215546Sopenharmony_ci      reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
1088bf215546Sopenharmony_ci
1089bf215546Sopenharmony_ci   return reg;
1090bf215546Sopenharmony_ci}
1091bf215546Sopenharmony_ci
1092bf215546Sopenharmony_cistatic inline struct brw_reg
1093bf215546Sopenharmony_cibrw_writemask(struct brw_reg reg, unsigned mask)
1094bf215546Sopenharmony_ci{
1095bf215546Sopenharmony_ci   assert(reg.file != BRW_IMMEDIATE_VALUE);
1096bf215546Sopenharmony_ci   reg.writemask &= mask;
1097bf215546Sopenharmony_ci   return reg;
1098bf215546Sopenharmony_ci}
1099bf215546Sopenharmony_ci
1100bf215546Sopenharmony_cistatic inline struct brw_reg
1101bf215546Sopenharmony_cibrw_set_writemask(struct brw_reg reg, unsigned mask)
1102bf215546Sopenharmony_ci{
1103bf215546Sopenharmony_ci   assert(reg.file != BRW_IMMEDIATE_VALUE);
1104bf215546Sopenharmony_ci   reg.writemask = mask;
1105bf215546Sopenharmony_ci   return reg;
1106bf215546Sopenharmony_ci}
1107bf215546Sopenharmony_ci
1108bf215546Sopenharmony_cistatic inline unsigned
1109bf215546Sopenharmony_cibrw_writemask_for_size(unsigned n)
1110bf215546Sopenharmony_ci{
1111bf215546Sopenharmony_ci   return (1 << n) - 1;
1112bf215546Sopenharmony_ci}
1113bf215546Sopenharmony_ci
1114bf215546Sopenharmony_cistatic inline unsigned
1115bf215546Sopenharmony_cibrw_writemask_for_component_packing(unsigned n, unsigned first_component)
1116bf215546Sopenharmony_ci{
1117bf215546Sopenharmony_ci   assert(first_component + n <= 4);
1118bf215546Sopenharmony_ci   return (((1 << n) - 1) << first_component);
1119bf215546Sopenharmony_ci}
1120bf215546Sopenharmony_ci
1121bf215546Sopenharmony_cistatic inline struct brw_reg
1122bf215546Sopenharmony_cinegate(struct brw_reg reg)
1123bf215546Sopenharmony_ci{
1124bf215546Sopenharmony_ci   reg.negate ^= 1;
1125bf215546Sopenharmony_ci   return reg;
1126bf215546Sopenharmony_ci}
1127bf215546Sopenharmony_ci
1128bf215546Sopenharmony_cistatic inline struct brw_reg
1129bf215546Sopenharmony_cibrw_abs(struct brw_reg reg)
1130bf215546Sopenharmony_ci{
1131bf215546Sopenharmony_ci   reg.abs = 1;
1132bf215546Sopenharmony_ci   reg.negate = 0;
1133bf215546Sopenharmony_ci   return reg;
1134bf215546Sopenharmony_ci}
1135bf215546Sopenharmony_ci
1136bf215546Sopenharmony_ci/************************************************************************/
1137bf215546Sopenharmony_ci
1138bf215546Sopenharmony_cistatic inline struct brw_reg
1139bf215546Sopenharmony_cibrw_vec4_indirect(unsigned subnr, int offset)
1140bf215546Sopenharmony_ci{
1141bf215546Sopenharmony_ci   struct brw_reg reg =  brw_vec4_grf(0, 0);
1142bf215546Sopenharmony_ci   reg.subnr = subnr;
1143bf215546Sopenharmony_ci   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1144bf215546Sopenharmony_ci   reg.indirect_offset = offset;
1145bf215546Sopenharmony_ci   return reg;
1146bf215546Sopenharmony_ci}
1147bf215546Sopenharmony_ci
1148bf215546Sopenharmony_cistatic inline struct brw_reg
1149bf215546Sopenharmony_cibrw_vec1_indirect(unsigned subnr, int offset)
1150bf215546Sopenharmony_ci{
1151bf215546Sopenharmony_ci   struct brw_reg reg =  brw_vec1_grf(0, 0);
1152bf215546Sopenharmony_ci   reg.subnr = subnr;
1153bf215546Sopenharmony_ci   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1154bf215546Sopenharmony_ci   reg.indirect_offset = offset;
1155bf215546Sopenharmony_ci   return reg;
1156bf215546Sopenharmony_ci}
1157bf215546Sopenharmony_ci
1158bf215546Sopenharmony_cistatic inline struct brw_reg
1159bf215546Sopenharmony_cibrw_VxH_indirect(unsigned subnr, int offset)
1160bf215546Sopenharmony_ci{
1161bf215546Sopenharmony_ci   struct brw_reg reg = brw_vec1_grf(0, 0);
1162bf215546Sopenharmony_ci   reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
1163bf215546Sopenharmony_ci   reg.subnr = subnr;
1164bf215546Sopenharmony_ci   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1165bf215546Sopenharmony_ci   reg.indirect_offset = offset;
1166bf215546Sopenharmony_ci   return reg;
1167bf215546Sopenharmony_ci}
1168bf215546Sopenharmony_ci
1169bf215546Sopenharmony_cistatic inline struct brw_reg
1170bf215546Sopenharmony_cideref_4f(struct brw_indirect ptr, int offset)
1171bf215546Sopenharmony_ci{
1172bf215546Sopenharmony_ci   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1173bf215546Sopenharmony_ci}
1174bf215546Sopenharmony_ci
1175bf215546Sopenharmony_cistatic inline struct brw_reg
1176bf215546Sopenharmony_cideref_1f(struct brw_indirect ptr, int offset)
1177bf215546Sopenharmony_ci{
1178bf215546Sopenharmony_ci   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
1179bf215546Sopenharmony_ci}
1180bf215546Sopenharmony_ci
1181bf215546Sopenharmony_cistatic inline struct brw_reg
1182bf215546Sopenharmony_cideref_4b(struct brw_indirect ptr, int offset)
1183bf215546Sopenharmony_ci{
1184bf215546Sopenharmony_ci   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
1185bf215546Sopenharmony_ci}
1186bf215546Sopenharmony_ci
1187bf215546Sopenharmony_cistatic inline struct brw_reg
1188bf215546Sopenharmony_cideref_1uw(struct brw_indirect ptr, int offset)
1189bf215546Sopenharmony_ci{
1190bf215546Sopenharmony_ci   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
1191bf215546Sopenharmony_ci}
1192bf215546Sopenharmony_ci
1193bf215546Sopenharmony_cistatic inline struct brw_reg
1194bf215546Sopenharmony_cideref_1d(struct brw_indirect ptr, int offset)
1195bf215546Sopenharmony_ci{
1196bf215546Sopenharmony_ci   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
1197bf215546Sopenharmony_ci}
1198bf215546Sopenharmony_ci
1199bf215546Sopenharmony_cistatic inline struct brw_reg
1200bf215546Sopenharmony_cideref_1ud(struct brw_indirect ptr, int offset)
1201bf215546Sopenharmony_ci{
1202bf215546Sopenharmony_ci   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
1203bf215546Sopenharmony_ci}
1204bf215546Sopenharmony_ci
1205bf215546Sopenharmony_cistatic inline struct brw_reg
1206bf215546Sopenharmony_ciget_addr_reg(struct brw_indirect ptr)
1207bf215546Sopenharmony_ci{
1208bf215546Sopenharmony_ci   return brw_address_reg(ptr.addr_subnr);
1209bf215546Sopenharmony_ci}
1210bf215546Sopenharmony_ci
1211bf215546Sopenharmony_cistatic inline struct brw_indirect
1212bf215546Sopenharmony_cibrw_indirect_offset(struct brw_indirect ptr, int offset)
1213bf215546Sopenharmony_ci{
1214bf215546Sopenharmony_ci   ptr.addr_offset += offset;
1215bf215546Sopenharmony_ci   return ptr;
1216bf215546Sopenharmony_ci}
1217bf215546Sopenharmony_ci
1218bf215546Sopenharmony_cistatic inline struct brw_indirect
1219bf215546Sopenharmony_cibrw_indirect(unsigned addr_subnr, int offset)
1220bf215546Sopenharmony_ci{
1221bf215546Sopenharmony_ci   struct brw_indirect ptr;
1222bf215546Sopenharmony_ci   ptr.addr_subnr = addr_subnr;
1223bf215546Sopenharmony_ci   ptr.addr_offset = offset;
1224bf215546Sopenharmony_ci   ptr.pad = 0;
1225bf215546Sopenharmony_ci   return ptr;
1226bf215546Sopenharmony_ci}
1227bf215546Sopenharmony_ci
1228bf215546Sopenharmony_cistatic inline bool
1229bf215546Sopenharmony_ciregion_matches(struct brw_reg reg, enum brw_vertical_stride v,
1230bf215546Sopenharmony_ci               enum brw_width w, enum brw_horizontal_stride h)
1231bf215546Sopenharmony_ci{
1232bf215546Sopenharmony_ci   return reg.vstride == v &&
1233bf215546Sopenharmony_ci          reg.width == w &&
1234bf215546Sopenharmony_ci          reg.hstride == h;
1235bf215546Sopenharmony_ci}
1236bf215546Sopenharmony_ci
1237bf215546Sopenharmony_ci#define has_scalar_region(reg) \
1238bf215546Sopenharmony_ci   region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
1239bf215546Sopenharmony_ci                  BRW_HORIZONTAL_STRIDE_0)
1240bf215546Sopenharmony_ci
1241bf215546Sopenharmony_ci/**
1242bf215546Sopenharmony_ci * Return the size in bytes per data element of register \p reg on the
1243bf215546Sopenharmony_ci * corresponding register file.
1244bf215546Sopenharmony_ci */
1245bf215546Sopenharmony_cistatic inline unsigned
1246bf215546Sopenharmony_cielement_sz(struct brw_reg reg)
1247bf215546Sopenharmony_ci{
1248bf215546Sopenharmony_ci   if (reg.file == BRW_IMMEDIATE_VALUE || has_scalar_region(reg)) {
1249bf215546Sopenharmony_ci      return type_sz(reg.type);
1250bf215546Sopenharmony_ci
1251bf215546Sopenharmony_ci   } else if (reg.width == BRW_WIDTH_1 &&
1252bf215546Sopenharmony_ci              reg.hstride == BRW_HORIZONTAL_STRIDE_0) {
1253bf215546Sopenharmony_ci      assert(reg.vstride != BRW_VERTICAL_STRIDE_0);
1254bf215546Sopenharmony_ci      return type_sz(reg.type) << (reg.vstride - 1);
1255bf215546Sopenharmony_ci
1256bf215546Sopenharmony_ci   } else {
1257bf215546Sopenharmony_ci      assert(reg.hstride != BRW_HORIZONTAL_STRIDE_0);
1258bf215546Sopenharmony_ci      assert(reg.vstride == reg.hstride + reg.width);
1259bf215546Sopenharmony_ci      return type_sz(reg.type) << (reg.hstride - 1);
1260bf215546Sopenharmony_ci   }
1261bf215546Sopenharmony_ci}
1262bf215546Sopenharmony_ci
1263bf215546Sopenharmony_ci/* brw_packed_float.c */
1264bf215546Sopenharmony_ciint brw_float_to_vf(float f);
1265bf215546Sopenharmony_cifloat brw_vf_to_float(unsigned char vf);
1266bf215546Sopenharmony_ci
1267bf215546Sopenharmony_ci#ifdef __cplusplus
1268bf215546Sopenharmony_ci}
1269bf215546Sopenharmony_ci#endif
1270bf215546Sopenharmony_ci
1271bf215546Sopenharmony_ci#endif
1272