101e04c3fSmrg/*
201e04c3fSmrg Copyright (C) Intel Corp.  2006.  All Rights Reserved.
301e04c3fSmrg Intel funded Tungsten Graphics to
401e04c3fSmrg develop this 3D driver.
501e04c3fSmrg
601e04c3fSmrg Permission is hereby granted, free of charge, to any person obtaining
701e04c3fSmrg a copy of this software and associated documentation files (the
801e04c3fSmrg "Software"), to deal in the Software without restriction, including
901e04c3fSmrg without limitation the rights to use, copy, modify, merge, publish,
1001e04c3fSmrg distribute, sublicense, and/or sell copies of the Software, and to
1101e04c3fSmrg permit persons to whom the Software is furnished to do so, subject to
1201e04c3fSmrg the following conditions:
1301e04c3fSmrg
1401e04c3fSmrg The above copyright notice and this permission notice (including the
1501e04c3fSmrg next paragraph) shall be included in all copies or substantial
1601e04c3fSmrg portions of the Software.
1701e04c3fSmrg
1801e04c3fSmrg THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1901e04c3fSmrg EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2001e04c3fSmrg MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2101e04c3fSmrg IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
2201e04c3fSmrg LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
2301e04c3fSmrg OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2401e04c3fSmrg WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2501e04c3fSmrg
2601e04c3fSmrg **********************************************************************/
2701e04c3fSmrg /*
2801e04c3fSmrg  * Authors:
2901e04c3fSmrg  *   Keith Whitwell <keithw@vmware.com>
3001e04c3fSmrg  */
3101e04c3fSmrg
3201e04c3fSmrg/** @file brw_reg.h
3301e04c3fSmrg *
3401e04c3fSmrg * This file defines struct brw_reg, which is our representation for EU
3501e04c3fSmrg * registers.  They're not a hardware specific format, just an abstraction
3601e04c3fSmrg * that intends to capture the full flexibility of the hardware registers.
3701e04c3fSmrg *
3801e04c3fSmrg * The brw_eu_emit.c layer's brw_set_dest/brw_set_src[01] functions encode
3901e04c3fSmrg * the abstract brw_reg type into the actual hardware instruction encoding.
4001e04c3fSmrg */
4101e04c3fSmrg
4201e04c3fSmrg#ifndef BRW_REG_H
4301e04c3fSmrg#define BRW_REG_H
4401e04c3fSmrg
4501e04c3fSmrg#include <stdbool.h>
467ec681f3Smrg#include "util/compiler.h"
4701e04c3fSmrg#include "main/macros.h"
4801e04c3fSmrg#include "program/prog_instruction.h"
4901e04c3fSmrg#include "brw_eu_defines.h"
5001e04c3fSmrg#include "brw_reg_type.h"
5101e04c3fSmrg
5201e04c3fSmrg#ifdef __cplusplus
5301e04c3fSmrgextern "C" {
5401e04c3fSmrg#endif
5501e04c3fSmrg
567ec681f3Smrgstruct intel_device_info;
5701e04c3fSmrg
5801e04c3fSmrg/** Number of general purpose registers (VS, WM, etc) */
5901e04c3fSmrg#define BRW_MAX_GRF 128
6001e04c3fSmrg
6101e04c3fSmrg/**
6201e04c3fSmrg * First GRF used for the MRF hack.
6301e04c3fSmrg *
647ec681f3Smrg * On gfx7, MRFs are no longer used, and contiguous GRFs are used instead.  We
6501e04c3fSmrg * haven't converted our compiler to be aware of this, so it asks for MRFs and
6601e04c3fSmrg * brw_eu_emit.c quietly converts them to be accesses of the top GRFs.  The
6701e04c3fSmrg * register allocators have to be careful of this to avoid corrupting the "MRF"s
6801e04c3fSmrg * with actual GRF allocations.
6901e04c3fSmrg */
707ec681f3Smrg#define GFX7_MRF_HACK_START 112
7101e04c3fSmrg
7201e04c3fSmrg/** Number of message register file registers */
7301e04c3fSmrg#define BRW_MAX_MRF(gen) (gen == 6 ? 24 : 16)
7401e04c3fSmrg
7501e04c3fSmrg#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
7601e04c3fSmrg#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
7701e04c3fSmrg
7801e04c3fSmrg#define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
7901e04c3fSmrg#define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
8001e04c3fSmrg#define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
8101e04c3fSmrg#define BRW_SWIZZLE_YYYY      BRW_SWIZZLE4(1,1,1,1)
8201e04c3fSmrg#define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
8301e04c3fSmrg#define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
8401e04c3fSmrg#define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
8501e04c3fSmrg#define BRW_SWIZZLE_YXYX      BRW_SWIZZLE4(1,0,1,0)
8601e04c3fSmrg#define BRW_SWIZZLE_XZXZ      BRW_SWIZZLE4(0,2,0,2)
8701e04c3fSmrg#define BRW_SWIZZLE_YZXW      BRW_SWIZZLE4(1,2,0,3)
8801e04c3fSmrg#define BRW_SWIZZLE_YWYW      BRW_SWIZZLE4(1,3,1,3)
8901e04c3fSmrg#define BRW_SWIZZLE_ZXYW      BRW_SWIZZLE4(2,0,1,3)
9001e04c3fSmrg#define BRW_SWIZZLE_ZWZW      BRW_SWIZZLE4(2,3,2,3)
9101e04c3fSmrg#define BRW_SWIZZLE_WZWZ      BRW_SWIZZLE4(3,2,3,2)
9201e04c3fSmrg#define BRW_SWIZZLE_WZYX      BRW_SWIZZLE4(3,2,1,0)
9301e04c3fSmrg#define BRW_SWIZZLE_XXZZ      BRW_SWIZZLE4(0,0,2,2)
9401e04c3fSmrg#define BRW_SWIZZLE_YYWW      BRW_SWIZZLE4(1,1,3,3)
9501e04c3fSmrg#define BRW_SWIZZLE_YXWZ      BRW_SWIZZLE4(1,0,3,2)
9601e04c3fSmrg
9701e04c3fSmrg#define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
9801e04c3fSmrg#define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
9901e04c3fSmrg
10001e04c3fSmrgstatic inline bool
10101e04c3fSmrgbrw_is_single_value_swizzle(unsigned swiz)
10201e04c3fSmrg{
10301e04c3fSmrg   return (swiz == BRW_SWIZZLE_XXXX ||
10401e04c3fSmrg           swiz == BRW_SWIZZLE_YYYY ||
10501e04c3fSmrg           swiz == BRW_SWIZZLE_ZZZZ ||
10601e04c3fSmrg           swiz == BRW_SWIZZLE_WWWW);
10701e04c3fSmrg}
10801e04c3fSmrg
10901e04c3fSmrg/**
11001e04c3fSmrg * Compute the swizzle obtained from the application of \p swz0 on the result
11101e04c3fSmrg * of \p swz1.  The argument ordering is expected to match function
11201e04c3fSmrg * composition.
11301e04c3fSmrg */
11401e04c3fSmrgstatic inline unsigned
11501e04c3fSmrgbrw_compose_swizzle(unsigned swz0, unsigned swz1)
11601e04c3fSmrg{
11701e04c3fSmrg   return BRW_SWIZZLE4(
11801e04c3fSmrg      BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 0)),
11901e04c3fSmrg      BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 1)),
12001e04c3fSmrg      BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 2)),
12101e04c3fSmrg      BRW_GET_SWZ(swz1, BRW_GET_SWZ(swz0, 3)));
12201e04c3fSmrg}
12301e04c3fSmrg
12401e04c3fSmrg/**
12501e04c3fSmrg * Return the result of applying swizzle \p swz to shuffle the bits of \p mask
12601e04c3fSmrg * (AKA image).
12701e04c3fSmrg */
12801e04c3fSmrgstatic inline unsigned
12901e04c3fSmrgbrw_apply_swizzle_to_mask(unsigned swz, unsigned mask)
13001e04c3fSmrg{
13101e04c3fSmrg   unsigned result = 0;
13201e04c3fSmrg
13301e04c3fSmrg   for (unsigned i = 0; i < 4; i++) {
13401e04c3fSmrg      if (mask & (1 << BRW_GET_SWZ(swz, i)))
13501e04c3fSmrg         result |= 1 << i;
13601e04c3fSmrg   }
13701e04c3fSmrg
13801e04c3fSmrg   return result;
13901e04c3fSmrg}
14001e04c3fSmrg
14101e04c3fSmrg/**
14201e04c3fSmrg * Return the result of applying the inverse of swizzle \p swz to shuffle the
14301e04c3fSmrg * bits of \p mask (AKA preimage).  Useful to find out which components are
14401e04c3fSmrg * read from a swizzled source given the instruction writemask.
14501e04c3fSmrg */
14601e04c3fSmrgstatic inline unsigned
14701e04c3fSmrgbrw_apply_inv_swizzle_to_mask(unsigned swz, unsigned mask)
14801e04c3fSmrg{
14901e04c3fSmrg   unsigned result = 0;
15001e04c3fSmrg
15101e04c3fSmrg   for (unsigned i = 0; i < 4; i++) {
15201e04c3fSmrg      if (mask & (1 << i))
15301e04c3fSmrg         result |= 1 << BRW_GET_SWZ(swz, i);
15401e04c3fSmrg   }
15501e04c3fSmrg
15601e04c3fSmrg   return result;
15701e04c3fSmrg}
15801e04c3fSmrg
15901e04c3fSmrg/**
16001e04c3fSmrg * Construct an identity swizzle for the set of enabled channels given by \p
16101e04c3fSmrg * mask.  The result will only reference channels enabled in the provided \p
16201e04c3fSmrg * mask, assuming that \p mask is non-zero.  The constructed swizzle will
16301e04c3fSmrg * satisfy the property that for any instruction OP and any mask:
16401e04c3fSmrg *
16501e04c3fSmrg *    brw_OP(p, brw_writemask(dst, mask),
16601e04c3fSmrg *           brw_swizzle(src, brw_swizzle_for_mask(mask)));
16701e04c3fSmrg *
16801e04c3fSmrg * will be equivalent to the same instruction without swizzle:
16901e04c3fSmrg *
17001e04c3fSmrg *    brw_OP(p, brw_writemask(dst, mask), src);
17101e04c3fSmrg */
17201e04c3fSmrgstatic inline unsigned
17301e04c3fSmrgbrw_swizzle_for_mask(unsigned mask)
17401e04c3fSmrg{
17501e04c3fSmrg   unsigned last = (mask ? ffs(mask) - 1 : 0);
17601e04c3fSmrg   unsigned swz[4];
17701e04c3fSmrg
17801e04c3fSmrg   for (unsigned i = 0; i < 4; i++)
17901e04c3fSmrg      last = swz[i] = (mask & (1 << i) ? i : last);
18001e04c3fSmrg
18101e04c3fSmrg   return BRW_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
18201e04c3fSmrg}
18301e04c3fSmrg
18401e04c3fSmrg/**
18501e04c3fSmrg * Construct an identity swizzle for the first \p n components of a vector.
18601e04c3fSmrg * When only a subset of channels of a vec4 are used we don't want to
18701e04c3fSmrg * reference the other channels, as that will tell optimization passes that
18801e04c3fSmrg * those other channels are used.
18901e04c3fSmrg */
19001e04c3fSmrgstatic inline unsigned
19101e04c3fSmrgbrw_swizzle_for_size(unsigned n)
19201e04c3fSmrg{
19301e04c3fSmrg   return brw_swizzle_for_mask((1 << n) - 1);
19401e04c3fSmrg}
19501e04c3fSmrg
19601e04c3fSmrg/**
19701e04c3fSmrg * Converse of brw_swizzle_for_mask().  Returns the mask of components
19801e04c3fSmrg * accessed by the specified swizzle \p swz.
19901e04c3fSmrg */
20001e04c3fSmrgstatic inline unsigned
20101e04c3fSmrgbrw_mask_for_swizzle(unsigned swz)
20201e04c3fSmrg{
20301e04c3fSmrg   return brw_apply_inv_swizzle_to_mask(swz, ~0);
20401e04c3fSmrg}
20501e04c3fSmrg
20601e04c3fSmrguint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz);
20701e04c3fSmrg
20801e04c3fSmrg#define REG_SIZE (8*4)
20901e04c3fSmrg
21001e04c3fSmrg/* These aren't hardware structs, just something useful for us to pass around:
21101e04c3fSmrg *
21201e04c3fSmrg * Align1 operation has a lot of control over input ranges.  Used in
21301e04c3fSmrg * WM programs to implement shaders decomposed into "channel serial"
21401e04c3fSmrg * or "structure of array" form:
21501e04c3fSmrg */
21601e04c3fSmrgstruct brw_reg {
21701e04c3fSmrg   union {
21801e04c3fSmrg      struct {
21901e04c3fSmrg         enum brw_reg_type type:4;
22001e04c3fSmrg         enum brw_reg_file file:3;      /* :2 hardware format */
22101e04c3fSmrg         unsigned negate:1;             /* source only */
22201e04c3fSmrg         unsigned abs:1;                /* source only */
22301e04c3fSmrg         unsigned address_mode:1;       /* relative addressing, hopefully! */
2249f464c52Smaya         unsigned pad0:17;
22501e04c3fSmrg         unsigned subnr:5;              /* :1 in align16 */
22601e04c3fSmrg      };
22701e04c3fSmrg      uint32_t bits;
22801e04c3fSmrg   };
22901e04c3fSmrg
23001e04c3fSmrg   union {
23101e04c3fSmrg      struct {
2329f464c52Smaya         unsigned nr;
23301e04c3fSmrg         unsigned swizzle:8;      /* src only, align16 only */
23401e04c3fSmrg         unsigned writemask:4;    /* dest only, align16 only */
23501e04c3fSmrg         int  indirect_offset:10; /* relative addressing offset */
23601e04c3fSmrg         unsigned vstride:4;      /* source only */
23701e04c3fSmrg         unsigned width:3;        /* src only, align1 only */
23801e04c3fSmrg         unsigned hstride:2;      /* align1 only */
23901e04c3fSmrg         unsigned pad1:1;
24001e04c3fSmrg      };
24101e04c3fSmrg
24201e04c3fSmrg      double df;
24301e04c3fSmrg      uint64_t u64;
24401e04c3fSmrg      int64_t d64;
24501e04c3fSmrg      float f;
24601e04c3fSmrg      int   d;
24701e04c3fSmrg      unsigned ud;
24801e04c3fSmrg   };
24901e04c3fSmrg};
25001e04c3fSmrg
25101e04c3fSmrgstatic inline bool
25201e04c3fSmrgbrw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
25301e04c3fSmrg{
2549f464c52Smaya   return a->bits == b->bits && a->u64 == b->u64;
25501e04c3fSmrg}
25601e04c3fSmrg
25701e04c3fSmrgstatic inline bool
25801e04c3fSmrgbrw_regs_negative_equal(const struct brw_reg *a, const struct brw_reg *b)
25901e04c3fSmrg{
26001e04c3fSmrg   if (a->file == IMM) {
26101e04c3fSmrg      if (a->bits != b->bits)
26201e04c3fSmrg         return false;
26301e04c3fSmrg
26401e04c3fSmrg      switch ((enum brw_reg_type) a->type) {
26501e04c3fSmrg      case BRW_REGISTER_TYPE_UQ:
26601e04c3fSmrg      case BRW_REGISTER_TYPE_Q:
26701e04c3fSmrg         return a->d64 == -b->d64;
26801e04c3fSmrg      case BRW_REGISTER_TYPE_DF:
26901e04c3fSmrg         return a->df == -b->df;
27001e04c3fSmrg      case BRW_REGISTER_TYPE_UD:
27101e04c3fSmrg      case BRW_REGISTER_TYPE_D:
27201e04c3fSmrg         return a->d == -b->d;
27301e04c3fSmrg      case BRW_REGISTER_TYPE_F:
27401e04c3fSmrg         return a->f == -b->f;
27501e04c3fSmrg      case BRW_REGISTER_TYPE_VF:
27601e04c3fSmrg         /* It is tempting to treat 0 as a negation of 0 (and -0 as a negation
27701e04c3fSmrg          * of -0).  There are occasions where 0 or -0 is used and the exact
27801e04c3fSmrg          * bit pattern is desired.  At the very least, changing this to allow
27901e04c3fSmrg          * 0 as a negation of 0 causes some fp64 tests to fail on IVB.
28001e04c3fSmrg          */
28101e04c3fSmrg         return a->ud == (b->ud ^ 0x80808080);
28201e04c3fSmrg      case BRW_REGISTER_TYPE_UW:
28301e04c3fSmrg      case BRW_REGISTER_TYPE_W:
28401e04c3fSmrg      case BRW_REGISTER_TYPE_UV:
28501e04c3fSmrg      case BRW_REGISTER_TYPE_V:
28601e04c3fSmrg      case BRW_REGISTER_TYPE_HF:
28701e04c3fSmrg         /* FINISHME: Implement support for these types once there is
28801e04c3fSmrg          * something in the compiler that can generate them.  Until then,
28901e04c3fSmrg          * they cannot be tested.
29001e04c3fSmrg          */
29101e04c3fSmrg         return false;
29201e04c3fSmrg      case BRW_REGISTER_TYPE_UB:
29301e04c3fSmrg      case BRW_REGISTER_TYPE_B:
29401e04c3fSmrg      case BRW_REGISTER_TYPE_NF:
29501e04c3fSmrg      default:
29601e04c3fSmrg         unreachable("not reached");
29701e04c3fSmrg      }
29801e04c3fSmrg   } else {
29901e04c3fSmrg      struct brw_reg tmp = *a;
30001e04c3fSmrg
30101e04c3fSmrg      tmp.negate = !tmp.negate;
30201e04c3fSmrg
30301e04c3fSmrg      return brw_regs_equal(&tmp, b);
30401e04c3fSmrg   }
30501e04c3fSmrg}
30601e04c3fSmrg
30701e04c3fSmrgstruct brw_indirect {
30801e04c3fSmrg   unsigned addr_subnr:4;
30901e04c3fSmrg   int addr_offset:10;
31001e04c3fSmrg   unsigned pad:18;
31101e04c3fSmrg};
31201e04c3fSmrg
31301e04c3fSmrg
31401e04c3fSmrgstatic inline unsigned
31501e04c3fSmrgtype_sz(unsigned type)
31601e04c3fSmrg{
31701e04c3fSmrg   switch(type) {
31801e04c3fSmrg   case BRW_REGISTER_TYPE_UQ:
31901e04c3fSmrg   case BRW_REGISTER_TYPE_Q:
32001e04c3fSmrg   case BRW_REGISTER_TYPE_DF:
3217ec681f3Smrg   case BRW_REGISTER_TYPE_NF:
32201e04c3fSmrg      return 8;
32301e04c3fSmrg   case BRW_REGISTER_TYPE_UD:
32401e04c3fSmrg   case BRW_REGISTER_TYPE_D:
32501e04c3fSmrg   case BRW_REGISTER_TYPE_F:
32601e04c3fSmrg   case BRW_REGISTER_TYPE_VF:
32701e04c3fSmrg      return 4;
32801e04c3fSmrg   case BRW_REGISTER_TYPE_UW:
32901e04c3fSmrg   case BRW_REGISTER_TYPE_W:
3307ec681f3Smrg   case BRW_REGISTER_TYPE_HF:
3317ec681f3Smrg   /* [U]V components are 4-bit, but HW unpacks them to 16-bit (2 bytes) */
33201e04c3fSmrg   case BRW_REGISTER_TYPE_UV:
33301e04c3fSmrg   case BRW_REGISTER_TYPE_V:
33401e04c3fSmrg      return 2;
33501e04c3fSmrg   case BRW_REGISTER_TYPE_UB:
33601e04c3fSmrg   case BRW_REGISTER_TYPE_B:
33701e04c3fSmrg      return 1;
33801e04c3fSmrg   default:
33901e04c3fSmrg      unreachable("not reached");
34001e04c3fSmrg   }
34101e04c3fSmrg}
34201e04c3fSmrg
34301e04c3fSmrgstatic inline enum brw_reg_type
34401e04c3fSmrgget_exec_type(const enum brw_reg_type type)
34501e04c3fSmrg{
34601e04c3fSmrg   switch (type) {
34701e04c3fSmrg   case BRW_REGISTER_TYPE_B:
34801e04c3fSmrg   case BRW_REGISTER_TYPE_V:
34901e04c3fSmrg      return BRW_REGISTER_TYPE_W;
35001e04c3fSmrg   case BRW_REGISTER_TYPE_UB:
35101e04c3fSmrg   case BRW_REGISTER_TYPE_UV:
35201e04c3fSmrg      return BRW_REGISTER_TYPE_UW;
35301e04c3fSmrg   case BRW_REGISTER_TYPE_VF:
35401e04c3fSmrg      return BRW_REGISTER_TYPE_F;
35501e04c3fSmrg   default:
35601e04c3fSmrg      return type;
35701e04c3fSmrg   }
35801e04c3fSmrg}
35901e04c3fSmrg
36001e04c3fSmrg/**
36101e04c3fSmrg * Return an integer type of the requested size and signedness.
36201e04c3fSmrg */
36301e04c3fSmrgstatic inline enum brw_reg_type
36401e04c3fSmrgbrw_int_type(unsigned sz, bool is_signed)
36501e04c3fSmrg{
36601e04c3fSmrg   switch (sz) {
36701e04c3fSmrg   case 1:
36801e04c3fSmrg      return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
36901e04c3fSmrg   case 2:
37001e04c3fSmrg      return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
37101e04c3fSmrg   case 4:
37201e04c3fSmrg      return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
37301e04c3fSmrg   case 8:
37401e04c3fSmrg      return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
37501e04c3fSmrg   default:
37601e04c3fSmrg      unreachable("Not reached.");
37701e04c3fSmrg   }
37801e04c3fSmrg}
37901e04c3fSmrg
38001e04c3fSmrg/**
38101e04c3fSmrg * Construct a brw_reg.
38201e04c3fSmrg * \param file      one of the BRW_x_REGISTER_FILE values
38301e04c3fSmrg * \param nr        register number/index
38401e04c3fSmrg * \param subnr     register sub number
38501e04c3fSmrg * \param negate    register negate modifier
38601e04c3fSmrg * \param abs       register abs modifier
38701e04c3fSmrg * \param type      one of BRW_REGISTER_TYPE_x
38801e04c3fSmrg * \param vstride   one of BRW_VERTICAL_STRIDE_x
38901e04c3fSmrg * \param width     one of BRW_WIDTH_x
39001e04c3fSmrg * \param hstride   one of BRW_HORIZONTAL_STRIDE_x
39101e04c3fSmrg * \param swizzle   one of BRW_SWIZZLE_x
39201e04c3fSmrg * \param writemask WRITEMASK_X/Y/Z/W bitfield
39301e04c3fSmrg */
39401e04c3fSmrgstatic inline struct brw_reg
39501e04c3fSmrgbrw_reg(enum brw_reg_file file,
39601e04c3fSmrg        unsigned nr,
39701e04c3fSmrg        unsigned subnr,
39801e04c3fSmrg        unsigned negate,
39901e04c3fSmrg        unsigned abs,
40001e04c3fSmrg        enum brw_reg_type type,
40101e04c3fSmrg        unsigned vstride,
40201e04c3fSmrg        unsigned width,
40301e04c3fSmrg        unsigned hstride,
40401e04c3fSmrg        unsigned swizzle,
40501e04c3fSmrg        unsigned writemask)
40601e04c3fSmrg{
40701e04c3fSmrg   struct brw_reg reg;
40801e04c3fSmrg   if (file == BRW_GENERAL_REGISTER_FILE)
40901e04c3fSmrg      assert(nr < BRW_MAX_GRF);
41001e04c3fSmrg   else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
41101e04c3fSmrg      assert(nr <= BRW_ARF_TIMESTAMP);
41201e04c3fSmrg   /* Asserting on the MRF register number requires to know the hardware gen
4137ec681f3Smrg    * (gfx6 has 24 MRF registers), which we don't know here, so we assert
41401e04c3fSmrg    * for that in the generators and in brw_eu_emit.c
41501e04c3fSmrg    */
41601e04c3fSmrg
41701e04c3fSmrg   reg.type = type;
41801e04c3fSmrg   reg.file = file;
41901e04c3fSmrg   reg.negate = negate;
42001e04c3fSmrg   reg.abs = abs;
42101e04c3fSmrg   reg.address_mode = BRW_ADDRESS_DIRECT;
42201e04c3fSmrg   reg.pad0 = 0;
42301e04c3fSmrg   reg.subnr = subnr * type_sz(type);
42401e04c3fSmrg   reg.nr = nr;
42501e04c3fSmrg
42601e04c3fSmrg   /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
42701e04c3fSmrg    * set swizzle and writemask to W, as the lower bits of subnr will
42801e04c3fSmrg    * be lost when converted to align16.  This is probably too much to
42901e04c3fSmrg    * keep track of as you'd want it adjusted by suboffset(), etc.
43001e04c3fSmrg    * Perhaps fix up when converting to align16?
43101e04c3fSmrg    */
43201e04c3fSmrg   reg.swizzle = swizzle;
43301e04c3fSmrg   reg.writemask = writemask;
43401e04c3fSmrg   reg.indirect_offset = 0;
43501e04c3fSmrg   reg.vstride = vstride;
43601e04c3fSmrg   reg.width = width;
43701e04c3fSmrg   reg.hstride = hstride;
43801e04c3fSmrg   reg.pad1 = 0;
43901e04c3fSmrg   return reg;
44001e04c3fSmrg}
44101e04c3fSmrg
44201e04c3fSmrg/** Construct float[16] register */
44301e04c3fSmrgstatic inline struct brw_reg
44401e04c3fSmrgbrw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
44501e04c3fSmrg{
44601e04c3fSmrg   return brw_reg(file,
44701e04c3fSmrg                  nr,
44801e04c3fSmrg                  subnr,
44901e04c3fSmrg                  0,
45001e04c3fSmrg                  0,
45101e04c3fSmrg                  BRW_REGISTER_TYPE_F,
45201e04c3fSmrg                  BRW_VERTICAL_STRIDE_16,
45301e04c3fSmrg                  BRW_WIDTH_16,
45401e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_1,
45501e04c3fSmrg                  BRW_SWIZZLE_XYZW,
45601e04c3fSmrg                  WRITEMASK_XYZW);
45701e04c3fSmrg}
45801e04c3fSmrg
45901e04c3fSmrg/** Construct float[8] register */
46001e04c3fSmrgstatic inline struct brw_reg
46101e04c3fSmrgbrw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
46201e04c3fSmrg{
46301e04c3fSmrg   return brw_reg(file,
46401e04c3fSmrg                  nr,
46501e04c3fSmrg                  subnr,
46601e04c3fSmrg                  0,
46701e04c3fSmrg                  0,
46801e04c3fSmrg                  BRW_REGISTER_TYPE_F,
46901e04c3fSmrg                  BRW_VERTICAL_STRIDE_8,
47001e04c3fSmrg                  BRW_WIDTH_8,
47101e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_1,
47201e04c3fSmrg                  BRW_SWIZZLE_XYZW,
47301e04c3fSmrg                  WRITEMASK_XYZW);
47401e04c3fSmrg}
47501e04c3fSmrg
47601e04c3fSmrg/** Construct float[4] register */
47701e04c3fSmrgstatic inline struct brw_reg
47801e04c3fSmrgbrw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
47901e04c3fSmrg{
48001e04c3fSmrg   return brw_reg(file,
48101e04c3fSmrg                  nr,
48201e04c3fSmrg                  subnr,
48301e04c3fSmrg                  0,
48401e04c3fSmrg                  0,
48501e04c3fSmrg                  BRW_REGISTER_TYPE_F,
48601e04c3fSmrg                  BRW_VERTICAL_STRIDE_4,
48701e04c3fSmrg                  BRW_WIDTH_4,
48801e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_1,
48901e04c3fSmrg                  BRW_SWIZZLE_XYZW,
49001e04c3fSmrg                  WRITEMASK_XYZW);
49101e04c3fSmrg}
49201e04c3fSmrg
49301e04c3fSmrg/** Construct float[2] register */
49401e04c3fSmrgstatic inline struct brw_reg
49501e04c3fSmrgbrw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
49601e04c3fSmrg{
49701e04c3fSmrg   return brw_reg(file,
49801e04c3fSmrg                  nr,
49901e04c3fSmrg                  subnr,
50001e04c3fSmrg                  0,
50101e04c3fSmrg                  0,
50201e04c3fSmrg                  BRW_REGISTER_TYPE_F,
50301e04c3fSmrg                  BRW_VERTICAL_STRIDE_2,
50401e04c3fSmrg                  BRW_WIDTH_2,
50501e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_1,
50601e04c3fSmrg                  BRW_SWIZZLE_XYXY,
50701e04c3fSmrg                  WRITEMASK_XY);
50801e04c3fSmrg}
50901e04c3fSmrg
51001e04c3fSmrg/** Construct float[1] register */
51101e04c3fSmrgstatic inline struct brw_reg
51201e04c3fSmrgbrw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
51301e04c3fSmrg{
51401e04c3fSmrg   return brw_reg(file,
51501e04c3fSmrg                  nr,
51601e04c3fSmrg                  subnr,
51701e04c3fSmrg                  0,
51801e04c3fSmrg                  0,
51901e04c3fSmrg                  BRW_REGISTER_TYPE_F,
52001e04c3fSmrg                  BRW_VERTICAL_STRIDE_0,
52101e04c3fSmrg                  BRW_WIDTH_1,
52201e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_0,
52301e04c3fSmrg                  BRW_SWIZZLE_XXXX,
52401e04c3fSmrg                  WRITEMASK_X);
52501e04c3fSmrg}
52601e04c3fSmrg
52701e04c3fSmrgstatic inline struct brw_reg
52801e04c3fSmrgbrw_vecn_reg(unsigned width, enum brw_reg_file file,
52901e04c3fSmrg             unsigned nr, unsigned subnr)
53001e04c3fSmrg{
53101e04c3fSmrg   switch (width) {
53201e04c3fSmrg   case 1:
53301e04c3fSmrg      return brw_vec1_reg(file, nr, subnr);
53401e04c3fSmrg   case 2:
53501e04c3fSmrg      return brw_vec2_reg(file, nr, subnr);
53601e04c3fSmrg   case 4:
53701e04c3fSmrg      return brw_vec4_reg(file, nr, subnr);
53801e04c3fSmrg   case 8:
53901e04c3fSmrg      return brw_vec8_reg(file, nr, subnr);
54001e04c3fSmrg   case 16:
54101e04c3fSmrg      return brw_vec16_reg(file, nr, subnr);
54201e04c3fSmrg   default:
54301e04c3fSmrg      unreachable("Invalid register width");
54401e04c3fSmrg   }
54501e04c3fSmrg}
54601e04c3fSmrg
54701e04c3fSmrgstatic inline struct brw_reg
54801e04c3fSmrgretype(struct brw_reg reg, enum brw_reg_type type)
54901e04c3fSmrg{
55001e04c3fSmrg   reg.type = type;
55101e04c3fSmrg   return reg;
55201e04c3fSmrg}
55301e04c3fSmrg
55401e04c3fSmrgstatic inline struct brw_reg
55501e04c3fSmrgfirsthalf(struct brw_reg reg)
55601e04c3fSmrg{
55701e04c3fSmrg   return reg;
55801e04c3fSmrg}
55901e04c3fSmrg
56001e04c3fSmrgstatic inline struct brw_reg
56101e04c3fSmrgsechalf(struct brw_reg reg)
56201e04c3fSmrg{
56301e04c3fSmrg   if (reg.vstride)
56401e04c3fSmrg      reg.nr++;
56501e04c3fSmrg   return reg;
56601e04c3fSmrg}
56701e04c3fSmrg
56801e04c3fSmrgstatic inline struct brw_reg
56901e04c3fSmrgoffset(struct brw_reg reg, unsigned delta)
57001e04c3fSmrg{
57101e04c3fSmrg   reg.nr += delta;
57201e04c3fSmrg   return reg;
57301e04c3fSmrg}
57401e04c3fSmrg
57501e04c3fSmrg
57601e04c3fSmrgstatic inline struct brw_reg
57701e04c3fSmrgbyte_offset(struct brw_reg reg, unsigned bytes)
57801e04c3fSmrg{
57901e04c3fSmrg   unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
58001e04c3fSmrg   reg.nr = newoffset / REG_SIZE;
58101e04c3fSmrg   reg.subnr = newoffset % REG_SIZE;
58201e04c3fSmrg   return reg;
58301e04c3fSmrg}
58401e04c3fSmrg
58501e04c3fSmrgstatic inline struct brw_reg
58601e04c3fSmrgsuboffset(struct brw_reg reg, unsigned delta)
58701e04c3fSmrg{
58801e04c3fSmrg   return byte_offset(reg, delta * type_sz(reg.type));
58901e04c3fSmrg}
59001e04c3fSmrg
59101e04c3fSmrg/** Construct unsigned word[16] register */
59201e04c3fSmrgstatic inline struct brw_reg
59301e04c3fSmrgbrw_uw16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
59401e04c3fSmrg{
59501e04c3fSmrg   return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
59601e04c3fSmrg}
59701e04c3fSmrg
59801e04c3fSmrg/** Construct unsigned word[8] register */
59901e04c3fSmrgstatic inline struct brw_reg
60001e04c3fSmrgbrw_uw8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
60101e04c3fSmrg{
60201e04c3fSmrg   return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
60301e04c3fSmrg}
60401e04c3fSmrg
60501e04c3fSmrg/** Construct unsigned word[1] register */
60601e04c3fSmrgstatic inline struct brw_reg
60701e04c3fSmrgbrw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
60801e04c3fSmrg{
60901e04c3fSmrg   return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
61001e04c3fSmrg}
61101e04c3fSmrg
61201e04c3fSmrgstatic inline struct brw_reg
61301e04c3fSmrgbrw_ud1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
61401e04c3fSmrg{
61501e04c3fSmrg   return retype(brw_vec1_reg(file, nr, subnr), BRW_REGISTER_TYPE_UD);
61601e04c3fSmrg}
61701e04c3fSmrg
61801e04c3fSmrgstatic inline struct brw_reg
61901e04c3fSmrgbrw_imm_reg(enum brw_reg_type type)
62001e04c3fSmrg{
62101e04c3fSmrg   return brw_reg(BRW_IMMEDIATE_VALUE,
62201e04c3fSmrg                  0,
62301e04c3fSmrg                  0,
62401e04c3fSmrg                  0,
62501e04c3fSmrg                  0,
62601e04c3fSmrg                  type,
62701e04c3fSmrg                  BRW_VERTICAL_STRIDE_0,
62801e04c3fSmrg                  BRW_WIDTH_1,
62901e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_0,
63001e04c3fSmrg                  0,
63101e04c3fSmrg                  0);
63201e04c3fSmrg}
63301e04c3fSmrg
63401e04c3fSmrg/** Construct float immediate register */
63501e04c3fSmrgstatic inline struct brw_reg
63601e04c3fSmrgbrw_imm_df(double df)
63701e04c3fSmrg{
63801e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
63901e04c3fSmrg   imm.df = df;
64001e04c3fSmrg   return imm;
64101e04c3fSmrg}
64201e04c3fSmrg
64301e04c3fSmrgstatic inline struct brw_reg
64401e04c3fSmrgbrw_imm_u64(uint64_t u64)
64501e04c3fSmrg{
64601e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
64701e04c3fSmrg   imm.u64 = u64;
64801e04c3fSmrg   return imm;
64901e04c3fSmrg}
65001e04c3fSmrg
65101e04c3fSmrgstatic inline struct brw_reg
65201e04c3fSmrgbrw_imm_f(float f)
65301e04c3fSmrg{
65401e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
65501e04c3fSmrg   imm.f = f;
65601e04c3fSmrg   return imm;
65701e04c3fSmrg}
65801e04c3fSmrg
65901e04c3fSmrg/** Construct int64_t immediate register */
66001e04c3fSmrgstatic inline struct brw_reg
66101e04c3fSmrgbrw_imm_q(int64_t q)
66201e04c3fSmrg{
66301e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_Q);
66401e04c3fSmrg   imm.d64 = q;
66501e04c3fSmrg   return imm;
66601e04c3fSmrg}
66701e04c3fSmrg
66801e04c3fSmrg/** Construct int64_t immediate register */
66901e04c3fSmrgstatic inline struct brw_reg
67001e04c3fSmrgbrw_imm_uq(uint64_t uq)
67101e04c3fSmrg{
67201e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UQ);
67301e04c3fSmrg   imm.u64 = uq;
67401e04c3fSmrg   return imm;
67501e04c3fSmrg}
67601e04c3fSmrg
67701e04c3fSmrg/** Construct integer immediate register */
67801e04c3fSmrgstatic inline struct brw_reg
67901e04c3fSmrgbrw_imm_d(int d)
68001e04c3fSmrg{
68101e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
68201e04c3fSmrg   imm.d = d;
68301e04c3fSmrg   return imm;
68401e04c3fSmrg}
68501e04c3fSmrg
68601e04c3fSmrg/** Construct uint immediate register */
68701e04c3fSmrgstatic inline struct brw_reg
68801e04c3fSmrgbrw_imm_ud(unsigned ud)
68901e04c3fSmrg{
69001e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
69101e04c3fSmrg   imm.ud = ud;
69201e04c3fSmrg   return imm;
69301e04c3fSmrg}
69401e04c3fSmrg
69501e04c3fSmrg/** Construct ushort immediate register */
69601e04c3fSmrgstatic inline struct brw_reg
69701e04c3fSmrgbrw_imm_uw(uint16_t uw)
69801e04c3fSmrg{
69901e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
70001e04c3fSmrg   imm.ud = uw | (uw << 16);
70101e04c3fSmrg   return imm;
70201e04c3fSmrg}
70301e04c3fSmrg
70401e04c3fSmrg/** Construct short immediate register */
70501e04c3fSmrgstatic inline struct brw_reg
70601e04c3fSmrgbrw_imm_w(int16_t w)
70701e04c3fSmrg{
70801e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
70901e04c3fSmrg   imm.ud = (uint16_t)w | (uint32_t)(uint16_t)w << 16;
71001e04c3fSmrg   return imm;
71101e04c3fSmrg}
71201e04c3fSmrg
71301e04c3fSmrg/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
71401e04c3fSmrg * numbers alias with _V and _VF below:
71501e04c3fSmrg */
71601e04c3fSmrg
71701e04c3fSmrg/** Construct vector of eight signed half-byte values */
71801e04c3fSmrgstatic inline struct brw_reg
71901e04c3fSmrgbrw_imm_v(unsigned v)
72001e04c3fSmrg{
72101e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
72201e04c3fSmrg   imm.ud = v;
72301e04c3fSmrg   return imm;
72401e04c3fSmrg}
72501e04c3fSmrg
72601e04c3fSmrg/** Construct vector of eight unsigned half-byte values */
72701e04c3fSmrgstatic inline struct brw_reg
72801e04c3fSmrgbrw_imm_uv(unsigned uv)
72901e04c3fSmrg{
73001e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
73101e04c3fSmrg   imm.ud = uv;
73201e04c3fSmrg   return imm;
73301e04c3fSmrg}
73401e04c3fSmrg
73501e04c3fSmrg/** Construct vector of four 8-bit float values */
73601e04c3fSmrgstatic inline struct brw_reg
73701e04c3fSmrgbrw_imm_vf(unsigned v)
73801e04c3fSmrg{
73901e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
74001e04c3fSmrg   imm.ud = v;
74101e04c3fSmrg   return imm;
74201e04c3fSmrg}
74301e04c3fSmrg
74401e04c3fSmrgstatic inline struct brw_reg
74501e04c3fSmrgbrw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
74601e04c3fSmrg{
74701e04c3fSmrg   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
74801e04c3fSmrg   imm.vstride = BRW_VERTICAL_STRIDE_0;
74901e04c3fSmrg   imm.width = BRW_WIDTH_4;
75001e04c3fSmrg   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
75101e04c3fSmrg   imm.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
75201e04c3fSmrg   return imm;
75301e04c3fSmrg}
75401e04c3fSmrg
75501e04c3fSmrg
75601e04c3fSmrgstatic inline struct brw_reg
75701e04c3fSmrgbrw_address(struct brw_reg reg)
75801e04c3fSmrg{
75901e04c3fSmrg   return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
76001e04c3fSmrg}
76101e04c3fSmrg
76201e04c3fSmrg/** Construct float[1] general-purpose register */
76301e04c3fSmrgstatic inline struct brw_reg
76401e04c3fSmrgbrw_vec1_grf(unsigned nr, unsigned subnr)
76501e04c3fSmrg{
76601e04c3fSmrg   return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
76701e04c3fSmrg}
76801e04c3fSmrg
76901e04c3fSmrg/** Construct float[2] general-purpose register */
77001e04c3fSmrgstatic inline struct brw_reg
77101e04c3fSmrgbrw_vec2_grf(unsigned nr, unsigned subnr)
77201e04c3fSmrg{
77301e04c3fSmrg   return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
77401e04c3fSmrg}
77501e04c3fSmrg
77601e04c3fSmrg/** Construct float[4] general-purpose register */
77701e04c3fSmrgstatic inline struct brw_reg
77801e04c3fSmrgbrw_vec4_grf(unsigned nr, unsigned subnr)
77901e04c3fSmrg{
78001e04c3fSmrg   return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
78101e04c3fSmrg}
78201e04c3fSmrg
78301e04c3fSmrg/** Construct float[8] general-purpose register */
78401e04c3fSmrgstatic inline struct brw_reg
78501e04c3fSmrgbrw_vec8_grf(unsigned nr, unsigned subnr)
78601e04c3fSmrg{
78701e04c3fSmrg   return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
78801e04c3fSmrg}
78901e04c3fSmrg
79001e04c3fSmrg/** Construct float[16] general-purpose register */
79101e04c3fSmrgstatic inline struct brw_reg
79201e04c3fSmrgbrw_vec16_grf(unsigned nr, unsigned subnr)
79301e04c3fSmrg{
79401e04c3fSmrg   return brw_vec16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
79501e04c3fSmrg}
79601e04c3fSmrg
79701e04c3fSmrgstatic inline struct brw_reg
79801e04c3fSmrgbrw_vecn_grf(unsigned width, unsigned nr, unsigned subnr)
79901e04c3fSmrg{
80001e04c3fSmrg   return brw_vecn_reg(width, BRW_GENERAL_REGISTER_FILE, nr, subnr);
80101e04c3fSmrg}
80201e04c3fSmrg
80301e04c3fSmrg
80401e04c3fSmrgstatic inline struct brw_reg
80501e04c3fSmrgbrw_uw8_grf(unsigned nr, unsigned subnr)
80601e04c3fSmrg{
80701e04c3fSmrg   return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
80801e04c3fSmrg}
80901e04c3fSmrg
81001e04c3fSmrgstatic inline struct brw_reg
81101e04c3fSmrgbrw_uw16_grf(unsigned nr, unsigned subnr)
81201e04c3fSmrg{
81301e04c3fSmrg   return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
81401e04c3fSmrg}
81501e04c3fSmrg
81601e04c3fSmrg
81701e04c3fSmrg/** Construct null register (usually used for setting condition codes) */
81801e04c3fSmrgstatic inline struct brw_reg
81901e04c3fSmrgbrw_null_reg(void)
82001e04c3fSmrg{
82101e04c3fSmrg   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
82201e04c3fSmrg}
82301e04c3fSmrg
82401e04c3fSmrgstatic inline struct brw_reg
82501e04c3fSmrgbrw_null_vec(unsigned width)
82601e04c3fSmrg{
82701e04c3fSmrg   return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
82801e04c3fSmrg}
82901e04c3fSmrg
83001e04c3fSmrgstatic inline struct brw_reg
83101e04c3fSmrgbrw_address_reg(unsigned subnr)
83201e04c3fSmrg{
83301e04c3fSmrg   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
83401e04c3fSmrg}
83501e04c3fSmrg
83601e04c3fSmrgstatic inline struct brw_reg
83701e04c3fSmrgbrw_tdr_reg(void)
83801e04c3fSmrg{
83901e04c3fSmrg   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_TDR, 0);
84001e04c3fSmrg}
84101e04c3fSmrg
84201e04c3fSmrg/* If/else instructions break in align16 mode if writemask & swizzle
84301e04c3fSmrg * aren't xyzw.  This goes against the convention for other scalar
84401e04c3fSmrg * regs:
84501e04c3fSmrg */
84601e04c3fSmrgstatic inline struct brw_reg
84701e04c3fSmrgbrw_ip_reg(void)
84801e04c3fSmrg{
84901e04c3fSmrg   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
85001e04c3fSmrg                  BRW_ARF_IP,
85101e04c3fSmrg                  0,
85201e04c3fSmrg                  0,
85301e04c3fSmrg                  0,
85401e04c3fSmrg                  BRW_REGISTER_TYPE_UD,
85501e04c3fSmrg                  BRW_VERTICAL_STRIDE_4, /* ? */
85601e04c3fSmrg                  BRW_WIDTH_1,
85701e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_0,
85801e04c3fSmrg                  BRW_SWIZZLE_XYZW, /* NOTE! */
85901e04c3fSmrg                  WRITEMASK_XYZW); /* NOTE! */
86001e04c3fSmrg}
86101e04c3fSmrg
86201e04c3fSmrgstatic inline struct brw_reg
86301e04c3fSmrgbrw_notification_reg(void)
86401e04c3fSmrg{
86501e04c3fSmrg   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
86601e04c3fSmrg                  BRW_ARF_NOTIFICATION_COUNT,
86701e04c3fSmrg                  0,
86801e04c3fSmrg                  0,
86901e04c3fSmrg                  0,
87001e04c3fSmrg                  BRW_REGISTER_TYPE_UD,
87101e04c3fSmrg                  BRW_VERTICAL_STRIDE_0,
87201e04c3fSmrg                  BRW_WIDTH_1,
87301e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_0,
87401e04c3fSmrg                  BRW_SWIZZLE_XXXX,
87501e04c3fSmrg                  WRITEMASK_X);
87601e04c3fSmrg}
87701e04c3fSmrg
87801e04c3fSmrgstatic inline struct brw_reg
87901e04c3fSmrgbrw_cr0_reg(unsigned subnr)
88001e04c3fSmrg{
88101e04c3fSmrg   return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_CONTROL, subnr);
88201e04c3fSmrg}
88301e04c3fSmrg
88401e04c3fSmrgstatic inline struct brw_reg
88501e04c3fSmrgbrw_sr0_reg(unsigned subnr)
88601e04c3fSmrg{
88701e04c3fSmrg   return brw_ud1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_STATE, subnr);
88801e04c3fSmrg}
88901e04c3fSmrg
89001e04c3fSmrgstatic inline struct brw_reg
89101e04c3fSmrgbrw_acc_reg(unsigned width)
89201e04c3fSmrg{
89301e04c3fSmrg   return brw_vecn_reg(width, BRW_ARCHITECTURE_REGISTER_FILE,
89401e04c3fSmrg                       BRW_ARF_ACCUMULATOR, 0);
89501e04c3fSmrg}
89601e04c3fSmrg
89701e04c3fSmrgstatic inline struct brw_reg
89801e04c3fSmrgbrw_flag_reg(int reg, int subreg)
89901e04c3fSmrg{
90001e04c3fSmrg   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
90101e04c3fSmrg                      BRW_ARF_FLAG + reg, subreg);
90201e04c3fSmrg}
90301e04c3fSmrg
90401e04c3fSmrgstatic inline struct brw_reg
90501e04c3fSmrgbrw_flag_subreg(unsigned subreg)
90601e04c3fSmrg{
90701e04c3fSmrg   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
90801e04c3fSmrg                      BRW_ARF_FLAG + subreg / 2, subreg % 2);
90901e04c3fSmrg}
91001e04c3fSmrg
91101e04c3fSmrg/**
9127ec681f3Smrg * Return the mask register present in Gfx4-5, or the related register present
9137ec681f3Smrg * in Gfx7.5 and later hardware referred to as "channel enable" register in
91401e04c3fSmrg * the documentation.
91501e04c3fSmrg */
91601e04c3fSmrgstatic inline struct brw_reg
91701e04c3fSmrgbrw_mask_reg(unsigned subnr)
91801e04c3fSmrg{
91901e04c3fSmrg   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
92001e04c3fSmrg}
92101e04c3fSmrg
92201e04c3fSmrgstatic inline struct brw_reg
92301e04c3fSmrgbrw_vmask_reg()
92401e04c3fSmrg{
92501e04c3fSmrg   return brw_sr0_reg(3);
92601e04c3fSmrg}
92701e04c3fSmrg
92801e04c3fSmrgstatic inline struct brw_reg
92901e04c3fSmrgbrw_dmask_reg()
93001e04c3fSmrg{
93101e04c3fSmrg   return brw_sr0_reg(2);
93201e04c3fSmrg}
93301e04c3fSmrg
9347ec681f3Smrgstatic inline struct brw_reg
9357ec681f3Smrgbrw_mask_stack_reg(unsigned subnr)
9367ec681f3Smrg{
9377ec681f3Smrg   return suboffset(retype(brw_vec16_reg(BRW_ARCHITECTURE_REGISTER_FILE,
9387ec681f3Smrg                                         BRW_ARF_MASK_STACK, 0),
9397ec681f3Smrg                           BRW_REGISTER_TYPE_UB), subnr);
9407ec681f3Smrg}
9417ec681f3Smrg
9427ec681f3Smrgstatic inline struct brw_reg
9437ec681f3Smrgbrw_mask_stack_depth_reg(unsigned subnr)
9447ec681f3Smrg{
9457ec681f3Smrg   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
9467ec681f3Smrg                      BRW_ARF_MASK_STACK_DEPTH, subnr);
9477ec681f3Smrg}
9487ec681f3Smrg
94901e04c3fSmrgstatic inline struct brw_reg
95001e04c3fSmrgbrw_message_reg(unsigned nr)
95101e04c3fSmrg{
95201e04c3fSmrg   return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
95301e04c3fSmrg}
95401e04c3fSmrg
95501e04c3fSmrgstatic inline struct brw_reg
95601e04c3fSmrgbrw_uvec_mrf(unsigned width, unsigned nr, unsigned subnr)
95701e04c3fSmrg{
95801e04c3fSmrg   return retype(brw_vecn_reg(width, BRW_MESSAGE_REGISTER_FILE, nr, subnr),
95901e04c3fSmrg                 BRW_REGISTER_TYPE_UD);
96001e04c3fSmrg}
96101e04c3fSmrg
96201e04c3fSmrg/* This is almost always called with a numeric constant argument, so
96301e04c3fSmrg * make things easy to evaluate at compile time:
96401e04c3fSmrg */
96501e04c3fSmrgstatic inline unsigned cvt(unsigned val)
96601e04c3fSmrg{
96701e04c3fSmrg   switch (val) {
96801e04c3fSmrg   case 0: return 0;
96901e04c3fSmrg   case 1: return 1;
97001e04c3fSmrg   case 2: return 2;
97101e04c3fSmrg   case 4: return 3;
97201e04c3fSmrg   case 8: return 4;
97301e04c3fSmrg   case 16: return 5;
97401e04c3fSmrg   case 32: return 6;
97501e04c3fSmrg   }
97601e04c3fSmrg   return 0;
97701e04c3fSmrg}
97801e04c3fSmrg
97901e04c3fSmrgstatic inline struct brw_reg
98001e04c3fSmrgstride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
98101e04c3fSmrg{
98201e04c3fSmrg   reg.vstride = cvt(vstride);
98301e04c3fSmrg   reg.width = cvt(width) - 1;
98401e04c3fSmrg   reg.hstride = cvt(hstride);
98501e04c3fSmrg   return reg;
98601e04c3fSmrg}
98701e04c3fSmrg
98801e04c3fSmrg/**
98901e04c3fSmrg * Multiply the vertical and horizontal stride of a register by the given
99001e04c3fSmrg * factor \a s.
99101e04c3fSmrg */
99201e04c3fSmrgstatic inline struct brw_reg
99301e04c3fSmrgspread(struct brw_reg reg, unsigned s)
99401e04c3fSmrg{
99501e04c3fSmrg   if (s) {
9967ec681f3Smrg      assert(util_is_power_of_two_nonzero(s));
99701e04c3fSmrg
99801e04c3fSmrg      if (reg.hstride)
99901e04c3fSmrg         reg.hstride += cvt(s) - 1;
100001e04c3fSmrg
100101e04c3fSmrg      if (reg.vstride)
100201e04c3fSmrg         reg.vstride += cvt(s) - 1;
100301e04c3fSmrg
100401e04c3fSmrg      return reg;
100501e04c3fSmrg   } else {
100601e04c3fSmrg      return stride(reg, 0, 1, 0);
100701e04c3fSmrg   }
100801e04c3fSmrg}
100901e04c3fSmrg
101001e04c3fSmrg/**
101101e04c3fSmrg * Reinterpret each channel of register \p reg as a vector of values of the
101201e04c3fSmrg * given smaller type and take the i-th subcomponent from each.
101301e04c3fSmrg */
101401e04c3fSmrgstatic inline struct brw_reg
101501e04c3fSmrgsubscript(struct brw_reg reg, enum brw_reg_type type, unsigned i)
101601e04c3fSmrg{
101701e04c3fSmrg   unsigned scale = type_sz(reg.type) / type_sz(type);
101801e04c3fSmrg   assert(scale >= 1 && i < scale);
101901e04c3fSmrg
10207ec681f3Smrg   if (reg.file == IMM) {
10217ec681f3Smrg      unsigned bit_size = type_sz(type) * 8;
10227ec681f3Smrg      reg.u64 >>= i * bit_size;
10237ec681f3Smrg      reg.u64 &= BITFIELD64_MASK(bit_size);
10247ec681f3Smrg      if (bit_size <= 16)
10257ec681f3Smrg         reg.u64 |= reg.u64 << 16;
10267ec681f3Smrg      return retype(reg, type);
10277ec681f3Smrg   }
10287ec681f3Smrg
102901e04c3fSmrg   return suboffset(retype(spread(reg, scale), type), i);
103001e04c3fSmrg}
103101e04c3fSmrg
103201e04c3fSmrgstatic inline struct brw_reg
103301e04c3fSmrgvec16(struct brw_reg reg)
103401e04c3fSmrg{
103501e04c3fSmrg   return stride(reg, 16,16,1);
103601e04c3fSmrg}
103701e04c3fSmrg
103801e04c3fSmrgstatic inline struct brw_reg
103901e04c3fSmrgvec8(struct brw_reg reg)
104001e04c3fSmrg{
104101e04c3fSmrg   return stride(reg, 8,8,1);
104201e04c3fSmrg}
104301e04c3fSmrg
104401e04c3fSmrgstatic inline struct brw_reg
104501e04c3fSmrgvec4(struct brw_reg reg)
104601e04c3fSmrg{
104701e04c3fSmrg   return stride(reg, 4,4,1);
104801e04c3fSmrg}
104901e04c3fSmrg
105001e04c3fSmrgstatic inline struct brw_reg
105101e04c3fSmrgvec2(struct brw_reg reg)
105201e04c3fSmrg{
105301e04c3fSmrg   return stride(reg, 2,2,1);
105401e04c3fSmrg}
105501e04c3fSmrg
105601e04c3fSmrgstatic inline struct brw_reg
105701e04c3fSmrgvec1(struct brw_reg reg)
105801e04c3fSmrg{
105901e04c3fSmrg   return stride(reg, 0,1,0);
106001e04c3fSmrg}
106101e04c3fSmrg
106201e04c3fSmrg
106301e04c3fSmrgstatic inline struct brw_reg
106401e04c3fSmrgget_element(struct brw_reg reg, unsigned elt)
106501e04c3fSmrg{
106601e04c3fSmrg   return vec1(suboffset(reg, elt));
106701e04c3fSmrg}
106801e04c3fSmrg
106901e04c3fSmrgstatic inline struct brw_reg
107001e04c3fSmrgget_element_ud(struct brw_reg reg, unsigned elt)
107101e04c3fSmrg{
107201e04c3fSmrg   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
107301e04c3fSmrg}
107401e04c3fSmrg
107501e04c3fSmrgstatic inline struct brw_reg
107601e04c3fSmrgget_element_d(struct brw_reg reg, unsigned elt)
107701e04c3fSmrg{
107801e04c3fSmrg   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
107901e04c3fSmrg}
108001e04c3fSmrg
108101e04c3fSmrgstatic inline struct brw_reg
108201e04c3fSmrgbrw_swizzle(struct brw_reg reg, unsigned swz)
108301e04c3fSmrg{
108401e04c3fSmrg   if (reg.file == BRW_IMMEDIATE_VALUE)
108501e04c3fSmrg      reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
108601e04c3fSmrg   else
108701e04c3fSmrg      reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
108801e04c3fSmrg
108901e04c3fSmrg   return reg;
109001e04c3fSmrg}
109101e04c3fSmrg
109201e04c3fSmrgstatic inline struct brw_reg
109301e04c3fSmrgbrw_writemask(struct brw_reg reg, unsigned mask)
109401e04c3fSmrg{
109501e04c3fSmrg   assert(reg.file != BRW_IMMEDIATE_VALUE);
109601e04c3fSmrg   reg.writemask &= mask;
109701e04c3fSmrg   return reg;
109801e04c3fSmrg}
109901e04c3fSmrg
110001e04c3fSmrgstatic inline struct brw_reg
110101e04c3fSmrgbrw_set_writemask(struct brw_reg reg, unsigned mask)
110201e04c3fSmrg{
110301e04c3fSmrg   assert(reg.file != BRW_IMMEDIATE_VALUE);
110401e04c3fSmrg   reg.writemask = mask;
110501e04c3fSmrg   return reg;
110601e04c3fSmrg}
110701e04c3fSmrg
110801e04c3fSmrgstatic inline unsigned
110901e04c3fSmrgbrw_writemask_for_size(unsigned n)
111001e04c3fSmrg{
111101e04c3fSmrg   return (1 << n) - 1;
111201e04c3fSmrg}
111301e04c3fSmrg
111401e04c3fSmrgstatic inline unsigned
111501e04c3fSmrgbrw_writemask_for_component_packing(unsigned n, unsigned first_component)
111601e04c3fSmrg{
111701e04c3fSmrg   assert(first_component + n <= 4);
111801e04c3fSmrg   return (((1 << n) - 1) << first_component);
111901e04c3fSmrg}
112001e04c3fSmrg
112101e04c3fSmrgstatic inline struct brw_reg
112201e04c3fSmrgnegate(struct brw_reg reg)
112301e04c3fSmrg{
112401e04c3fSmrg   reg.negate ^= 1;
112501e04c3fSmrg   return reg;
112601e04c3fSmrg}
112701e04c3fSmrg
112801e04c3fSmrgstatic inline struct brw_reg
112901e04c3fSmrgbrw_abs(struct brw_reg reg)
113001e04c3fSmrg{
113101e04c3fSmrg   reg.abs = 1;
113201e04c3fSmrg   reg.negate = 0;
113301e04c3fSmrg   return reg;
113401e04c3fSmrg}
113501e04c3fSmrg
113601e04c3fSmrg/************************************************************************/
113701e04c3fSmrg
113801e04c3fSmrgstatic inline struct brw_reg
113901e04c3fSmrgbrw_vec4_indirect(unsigned subnr, int offset)
114001e04c3fSmrg{
114101e04c3fSmrg   struct brw_reg reg =  brw_vec4_grf(0, 0);
114201e04c3fSmrg   reg.subnr = subnr;
114301e04c3fSmrg   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
114401e04c3fSmrg   reg.indirect_offset = offset;
114501e04c3fSmrg   return reg;
114601e04c3fSmrg}
114701e04c3fSmrg
114801e04c3fSmrgstatic inline struct brw_reg
114901e04c3fSmrgbrw_vec1_indirect(unsigned subnr, int offset)
115001e04c3fSmrg{
115101e04c3fSmrg   struct brw_reg reg =  brw_vec1_grf(0, 0);
115201e04c3fSmrg   reg.subnr = subnr;
115301e04c3fSmrg   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
115401e04c3fSmrg   reg.indirect_offset = offset;
115501e04c3fSmrg   return reg;
115601e04c3fSmrg}
115701e04c3fSmrg
115801e04c3fSmrgstatic inline struct brw_reg
115901e04c3fSmrgbrw_VxH_indirect(unsigned subnr, int offset)
116001e04c3fSmrg{
116101e04c3fSmrg   struct brw_reg reg = brw_vec1_grf(0, 0);
116201e04c3fSmrg   reg.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
116301e04c3fSmrg   reg.subnr = subnr;
116401e04c3fSmrg   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
116501e04c3fSmrg   reg.indirect_offset = offset;
116601e04c3fSmrg   return reg;
116701e04c3fSmrg}
116801e04c3fSmrg
116901e04c3fSmrgstatic inline struct brw_reg
117001e04c3fSmrgderef_4f(struct brw_indirect ptr, int offset)
117101e04c3fSmrg{
117201e04c3fSmrg   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
117301e04c3fSmrg}
117401e04c3fSmrg
117501e04c3fSmrgstatic inline struct brw_reg
117601e04c3fSmrgderef_1f(struct brw_indirect ptr, int offset)
117701e04c3fSmrg{
117801e04c3fSmrg   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
117901e04c3fSmrg}
118001e04c3fSmrg
118101e04c3fSmrgstatic inline struct brw_reg
118201e04c3fSmrgderef_4b(struct brw_indirect ptr, int offset)
118301e04c3fSmrg{
118401e04c3fSmrg   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
118501e04c3fSmrg}
118601e04c3fSmrg
118701e04c3fSmrgstatic inline struct brw_reg
118801e04c3fSmrgderef_1uw(struct brw_indirect ptr, int offset)
118901e04c3fSmrg{
119001e04c3fSmrg   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
119101e04c3fSmrg}
119201e04c3fSmrg
119301e04c3fSmrgstatic inline struct brw_reg
119401e04c3fSmrgderef_1d(struct brw_indirect ptr, int offset)
119501e04c3fSmrg{
119601e04c3fSmrg   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
119701e04c3fSmrg}
119801e04c3fSmrg
119901e04c3fSmrgstatic inline struct brw_reg
120001e04c3fSmrgderef_1ud(struct brw_indirect ptr, int offset)
120101e04c3fSmrg{
120201e04c3fSmrg   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
120301e04c3fSmrg}
120401e04c3fSmrg
120501e04c3fSmrgstatic inline struct brw_reg
120601e04c3fSmrgget_addr_reg(struct brw_indirect ptr)
120701e04c3fSmrg{
120801e04c3fSmrg   return brw_address_reg(ptr.addr_subnr);
120901e04c3fSmrg}
121001e04c3fSmrg
121101e04c3fSmrgstatic inline struct brw_indirect
121201e04c3fSmrgbrw_indirect_offset(struct brw_indirect ptr, int offset)
121301e04c3fSmrg{
121401e04c3fSmrg   ptr.addr_offset += offset;
121501e04c3fSmrg   return ptr;
121601e04c3fSmrg}
121701e04c3fSmrg
121801e04c3fSmrgstatic inline struct brw_indirect
121901e04c3fSmrgbrw_indirect(unsigned addr_subnr, int offset)
122001e04c3fSmrg{
122101e04c3fSmrg   struct brw_indirect ptr;
122201e04c3fSmrg   ptr.addr_subnr = addr_subnr;
122301e04c3fSmrg   ptr.addr_offset = offset;
122401e04c3fSmrg   ptr.pad = 0;
122501e04c3fSmrg   return ptr;
122601e04c3fSmrg}
122701e04c3fSmrg
122801e04c3fSmrgstatic inline bool
122901e04c3fSmrgregion_matches(struct brw_reg reg, enum brw_vertical_stride v,
123001e04c3fSmrg               enum brw_width w, enum brw_horizontal_stride h)
123101e04c3fSmrg{
123201e04c3fSmrg   return reg.vstride == v &&
123301e04c3fSmrg          reg.width == w &&
123401e04c3fSmrg          reg.hstride == h;
123501e04c3fSmrg}
123601e04c3fSmrg
123701e04c3fSmrg#define has_scalar_region(reg) \
123801e04c3fSmrg   region_matches(reg, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, \
123901e04c3fSmrg                  BRW_HORIZONTAL_STRIDE_0)
124001e04c3fSmrg
12417ec681f3Smrg/**
12427ec681f3Smrg * Return the size in bytes per data element of register \p reg on the
12437ec681f3Smrg * corresponding register file.
12447ec681f3Smrg */
12457ec681f3Smrgstatic inline unsigned
12467ec681f3Smrgelement_sz(struct brw_reg reg)
12477ec681f3Smrg{
12487ec681f3Smrg   if (reg.file == BRW_IMMEDIATE_VALUE || has_scalar_region(reg)) {
12497ec681f3Smrg      return type_sz(reg.type);
12507ec681f3Smrg
12517ec681f3Smrg   } else if (reg.width == BRW_WIDTH_1 &&
12527ec681f3Smrg              reg.hstride == BRW_HORIZONTAL_STRIDE_0) {
12537ec681f3Smrg      assert(reg.vstride != BRW_VERTICAL_STRIDE_0);
12547ec681f3Smrg      return type_sz(reg.type) << (reg.vstride - 1);
12557ec681f3Smrg
12567ec681f3Smrg   } else {
12577ec681f3Smrg      assert(reg.hstride != BRW_HORIZONTAL_STRIDE_0);
12587ec681f3Smrg      assert(reg.vstride == reg.hstride + reg.width);
12597ec681f3Smrg      return type_sz(reg.type) << (reg.hstride - 1);
12607ec681f3Smrg   }
12617ec681f3Smrg}
12627ec681f3Smrg
126301e04c3fSmrg/* brw_packed_float.c */
126401e04c3fSmrgint brw_float_to_vf(float f);
126501e04c3fSmrgfloat brw_vf_to_float(unsigned char vf);
126601e04c3fSmrg
126701e04c3fSmrg#ifdef __cplusplus
126801e04c3fSmrg}
126901e04c3fSmrg#endif
127001e04c3fSmrg
127101e04c3fSmrg#endif
1272