i965: Split struct brw_reg out from brw_eu.h into its own header.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 9 Nov 2012 22:00:15 +0000 (14:00 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Sat, 15 Dec 2012 21:40:09 +0000 (13:40 -0800)
struct brw_instruction and the related instruction emitting code won't
be useful on Gen8+, as the instruction encoding changed.  However, the
struct brw_reg code is still extremely valuable.

While we're at it, fix up some style points:
- s/GLuint/unsigned/g
- s/GLint/int/g
- s/GLshort/int16_t/g
- s/GLushort/uint16_t/g
- s/INLINE/inline/g
- Replace tabs with spaces
- Put return types on a separate line from the function name/parameters
- Remove trailing whitespace
- Remove extraneous whitespace around function parameters

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_reg.h [new file with mode: 0644]

index b2fa44864db4035d2f24c55707ebf05879e6d855..7b874c7b439b374496d7c2a94947f3310d2b9176 100644 (file)
 #include <stdbool.h>
 #include "brw_structs.h"
 #include "brw_defines.h"
+#include "brw_reg.h"
 #include "program/prog_instruction.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
-#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
-
-#define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
-#define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
-#define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
-#define BRW_SWIZZLE_YYYY      BRW_SWIZZLE4(1,1,1,1)
-#define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
-#define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
-#define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
-
-static inline bool brw_is_single_value_swizzle(int swiz)
-{
-   return (swiz == BRW_SWIZZLE_XXXX ||
-          swiz == BRW_SWIZZLE_YYYY ||
-          swiz == BRW_SWIZZLE_ZZZZ ||
-          swiz == BRW_SWIZZLE_WWWW);
-}
-
-#define REG_SIZE (8*4)
-
-
-/* These aren't hardware structs, just something useful for us to pass around:
- *
- * Align1 operation has a lot of control over input ranges.  Used in
- * WM programs to implement shaders decomposed into "channel serial"
- * or "structure of array" form:
- */
-struct brw_reg
-{
-   GLuint type:4;
-   GLuint file:2;
-   GLuint nr:8;
-   GLuint subnr:5;             /* :1 in align16 */
-   GLuint negate:1;            /* source only */
-   GLuint abs:1;               /* source only */
-   GLuint vstride:4;           /* source only */
-   GLuint width:3;             /* src only, align1 only */
-   GLuint hstride:2;                   /* align1 only */
-   GLuint address_mode:1;      /* relative addressing, hopefully! */
-   GLuint pad0:1;
-
-   union {      
-      struct {
-        GLuint swizzle:8;              /* src only, align16 only */
-        GLuint writemask:4;            /* dest only, align16 only */
-        GLint  indirect_offset:10;     /* relative addressing offset */
-        GLuint pad1:10;                /* two dwords total */
-      } bits;
-
-      GLfloat f;
-      GLint   d;
-      GLuint ud;
-   } dw1;      
-};
-
-
-struct brw_indirect {
-   GLuint addr_subnr:4;
-   GLint addr_offset:10;
-   GLuint pad:18;
-};
-
-
 #define BRW_EU_MAX_INSN_STACK 5
 
 struct brw_compile {
@@ -153,648 +90,6 @@ struct brw_compile {
    int loop_stack_array_size;
 };
 
-static INLINE int type_sz( GLuint type )
-{
-   switch( type ) {
-   case BRW_REGISTER_TYPE_UD:
-   case BRW_REGISTER_TYPE_D:
-   case BRW_REGISTER_TYPE_F:
-      return 4;
-   case BRW_REGISTER_TYPE_HF:
-   case BRW_REGISTER_TYPE_UW:
-   case BRW_REGISTER_TYPE_W:
-      return 2;
-   case BRW_REGISTER_TYPE_UB:
-   case BRW_REGISTER_TYPE_B:
-      return 1;
-   default:
-      return 0;
-   }
-}
-
-/**
- * Construct a brw_reg.
- * \param file  one of the BRW_x_REGISTER_FILE values
- * \param nr  register number/index
- * \param subnr  register sub number
- * \param type  one of BRW_REGISTER_TYPE_x
- * \param vstride  one of BRW_VERTICAL_STRIDE_x
- * \param width  one of BRW_WIDTH_x
- * \param hstride  one of BRW_HORIZONTAL_STRIDE_x
- * \param swizzle  one of BRW_SWIZZLE_x
- * \param writemask  WRITEMASK_X/Y/Z/W bitfield
- */
-static INLINE struct brw_reg brw_reg( GLuint file,
-                                      GLuint nr,
-                                      GLuint subnr,
-                                      GLuint type,
-                                      GLuint vstride,
-                                      GLuint width,
-                                      GLuint hstride,
-                                      GLuint swizzle,
-                                      GLuint writemask )
-{
-   struct brw_reg reg;
-   if (file == BRW_GENERAL_REGISTER_FILE)
-      assert(nr < BRW_MAX_GRF);
-   else if (file == BRW_MESSAGE_REGISTER_FILE)
-      assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
-   else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
-      assert(nr <= BRW_ARF_TIMESTAMP);
-
-   reg.type = type;
-   reg.file = file;
-   reg.nr = nr;
-   reg.subnr = subnr * type_sz(type);
-   reg.negate = 0;
-   reg.abs = 0;
-   reg.vstride = vstride;
-   reg.width = width;
-   reg.hstride = hstride;
-   reg.address_mode = BRW_ADDRESS_DIRECT;
-   reg.pad0 = 0;
-
-   /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
-    * set swizzle and writemask to W, as the lower bits of subnr will
-    * be lost when converted to align16.  This is probably too much to
-    * keep track of as you'd want it adjusted by suboffset(), etc.
-    * Perhaps fix up when converting to align16?
-    */
-   reg.dw1.bits.swizzle = swizzle;
-   reg.dw1.bits.writemask = writemask;
-   reg.dw1.bits.indirect_offset = 0;
-   reg.dw1.bits.pad1 = 0;
-   return reg;
-}
-
-/** Construct float[16] register */
-static INLINE struct brw_reg brw_vec16_reg( GLuint file,
-                                             GLuint nr,
-                                             GLuint subnr )
-{
-   return brw_reg(file,
-                 nr,
-                 subnr,
-                 BRW_REGISTER_TYPE_F,
-                 BRW_VERTICAL_STRIDE_16,
-                 BRW_WIDTH_16,
-                 BRW_HORIZONTAL_STRIDE_1,
-                 BRW_SWIZZLE_XYZW,
-                 WRITEMASK_XYZW);
-}
-
-/** Construct float[8] register */
-static INLINE struct brw_reg brw_vec8_reg( GLuint file,
-                                            GLuint nr,
-                                            GLuint subnr )
-{
-   return brw_reg(file,
-                 nr,
-                 subnr,
-                 BRW_REGISTER_TYPE_F,
-                 BRW_VERTICAL_STRIDE_8,
-                 BRW_WIDTH_8,
-                 BRW_HORIZONTAL_STRIDE_1,
-                 BRW_SWIZZLE_XYZW,
-                 WRITEMASK_XYZW);
-}
-
-/** Construct float[4] register */
-static INLINE struct brw_reg brw_vec4_reg( GLuint file,
-                                             GLuint nr,
-                                             GLuint subnr )
-{
-   return brw_reg(file,
-                 nr,
-                 subnr,
-                 BRW_REGISTER_TYPE_F,
-                 BRW_VERTICAL_STRIDE_4,
-                 BRW_WIDTH_4,
-                 BRW_HORIZONTAL_STRIDE_1,
-                 BRW_SWIZZLE_XYZW,
-                 WRITEMASK_XYZW);
-}
-
-/** Construct float[2] register */
-static INLINE struct brw_reg brw_vec2_reg( GLuint file,
-                                             GLuint nr,
-                                             GLuint subnr )
-{
-   return brw_reg(file,
-                 nr,
-                 subnr,
-                 BRW_REGISTER_TYPE_F,
-                 BRW_VERTICAL_STRIDE_2,
-                 BRW_WIDTH_2,
-                 BRW_HORIZONTAL_STRIDE_1,
-                 BRW_SWIZZLE_XYXY,
-                 WRITEMASK_XY);
-}
-
-/** Construct float[1] register */
-static INLINE struct brw_reg brw_vec1_reg( GLuint file,
-                                            GLuint nr,
-                                            GLuint subnr )
-{
-   return brw_reg(file,
-                 nr,
-                 subnr,
-                 BRW_REGISTER_TYPE_F,
-                 BRW_VERTICAL_STRIDE_0,
-                 BRW_WIDTH_1,
-                 BRW_HORIZONTAL_STRIDE_0,
-                 BRW_SWIZZLE_XXXX,
-                 WRITEMASK_X);
-}
-
-
-static INLINE struct brw_reg retype( struct brw_reg reg,
-                                      GLuint type )
-{
-   reg.type = type;
-   return reg;
-}
-
-static inline struct brw_reg
-sechalf(struct brw_reg reg)
-{
-   if (reg.vstride)
-      reg.nr++;
-   return reg;
-}
-
-static INLINE struct brw_reg suboffset( struct brw_reg reg,
-                                         GLuint delta )
-{   
-   reg.subnr += delta * type_sz(reg.type);
-   return reg;
-}
-
-
-static INLINE struct brw_reg offset( struct brw_reg reg,
-                                      GLuint delta )
-{
-   reg.nr += delta;
-   return reg;
-}
-
-
-static INLINE struct brw_reg byte_offset( struct brw_reg reg,
-                                           GLuint bytes )
-{
-   GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
-   reg.nr = newoffset / REG_SIZE;
-   reg.subnr = newoffset % REG_SIZE;
-   return reg;
-}
-   
-
-/** Construct unsigned word[16] register */
-static INLINE struct brw_reg brw_uw16_reg( GLuint file,
-                                            GLuint nr,
-                                            GLuint subnr )
-{
-   return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
-}
-
-/** Construct unsigned word[8] register */
-static INLINE struct brw_reg brw_uw8_reg( GLuint file,
-                                           GLuint nr,
-                                           GLuint subnr )
-{
-   return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
-}
-
-/** Construct unsigned word[1] register */
-static INLINE struct brw_reg brw_uw1_reg( GLuint file,
-                                           GLuint nr,
-                                           GLuint subnr )
-{
-   return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
-}
-
-static INLINE struct brw_reg brw_imm_reg( GLuint type )
-{
-   return brw_reg( BRW_IMMEDIATE_VALUE,
-                  0,
-                  0,
-                  type,
-                  BRW_VERTICAL_STRIDE_0,
-                  BRW_WIDTH_1,
-                  BRW_HORIZONTAL_STRIDE_0,
-                  0,
-                  0);      
-}
-
-/** Construct float immediate register */
-static INLINE struct brw_reg brw_imm_f( GLfloat f )
-{
-   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
-   imm.dw1.f = f;
-   return imm;
-}
-
-/** Construct integer immediate register */
-static INLINE struct brw_reg brw_imm_d( GLint d )
-{
-   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
-   imm.dw1.d = d;
-   return imm;
-}
-
-/** Construct uint immediate register */
-static INLINE struct brw_reg brw_imm_ud( GLuint ud )
-{
-   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
-   imm.dw1.ud = ud;
-   return imm;
-}
-
-/** Construct ushort immediate register */
-static INLINE struct brw_reg brw_imm_uw( GLushort uw )
-{
-   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
-   imm.dw1.ud = uw | (uw << 16);
-   return imm;
-}
-
-/** Construct short immediate register */
-static INLINE struct brw_reg brw_imm_w( GLshort w )
-{
-   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
-   imm.dw1.d = w | (w << 16);
-   return imm;
-}
-
-/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
- * numbers alias with _V and _VF below:
- */
-
-/** Construct vector of eight signed half-byte values */
-static INLINE struct brw_reg brw_imm_v( GLuint v )
-{
-   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
-   imm.vstride = BRW_VERTICAL_STRIDE_0;
-   imm.width = BRW_WIDTH_8;
-   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
-   imm.dw1.ud = v;
-   return imm;
-}
-
-/** Construct vector of four 8-bit float values */
-static INLINE struct brw_reg brw_imm_vf( GLuint v )
-{
-   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
-   imm.vstride = BRW_VERTICAL_STRIDE_0;
-   imm.width = BRW_WIDTH_4;
-   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
-   imm.dw1.ud = v;
-   return imm;
-}
-
-#define VF_ZERO 0x0
-#define VF_ONE  0x30
-#define VF_NEG  (1<<7)
-
-static INLINE struct brw_reg brw_imm_vf4( GLuint v0, 
-                                           GLuint v1, 
-                                           GLuint v2,
-                                           GLuint v3)
-{
-   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
-   imm.vstride = BRW_VERTICAL_STRIDE_0;
-   imm.width = BRW_WIDTH_4;
-   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
-   imm.dw1.ud = ((v0 << 0) |
-                (v1 << 8) |
-                (v2 << 16) |
-                (v3 << 24));
-   return imm;
-}
-
-
-static INLINE struct brw_reg brw_address( struct brw_reg reg )
-{
-   return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
-}
-
-/** Construct float[1] general-purpose register */
-static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
-{
-   return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
-}
-
-/** Construct float[2] general-purpose register */
-static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
-{
-   return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
-}
-
-/** Construct float[4] general-purpose register */
-static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
-{
-   return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
-}
-
-/** Construct float[8] general-purpose register */
-static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
-{
-   return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
-}
-
-
-static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
-{
-   return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
-}
-
-static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
-{
-   return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
-}
-
-
-/** Construct null register (usually used for setting condition codes) */
-static INLINE struct brw_reg brw_null_reg( void )
-{
-   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
-                      BRW_ARF_NULL, 
-                      0);
-}
-
-static INLINE struct brw_reg brw_address_reg( GLuint subnr )
-{
-   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
-                     BRW_ARF_ADDRESS, 
-                     subnr);
-}
-
-/* If/else instructions break in align16 mode if writemask & swizzle
- * aren't xyzw.  This goes against the convention for other scalar
- * regs:
- */
-static INLINE struct brw_reg brw_ip_reg( void )
-{
-   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
-                 BRW_ARF_IP, 
-                 0,
-                 BRW_REGISTER_TYPE_UD,
-                 BRW_VERTICAL_STRIDE_4, /* ? */
-                 BRW_WIDTH_1,
-                 BRW_HORIZONTAL_STRIDE_0,
-                 BRW_SWIZZLE_XYZW, /* NOTE! */
-                 WRITEMASK_XYZW); /* NOTE! */
-}
-
-static INLINE struct brw_reg brw_acc_reg( void )
-{
-   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
-                      BRW_ARF_ACCUMULATOR, 
-                      0);
-}
-
-static INLINE struct brw_reg brw_notification_1_reg(void)
-{
-
-   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
-                 BRW_ARF_NOTIFICATION_COUNT,
-                 1,
-                 BRW_REGISTER_TYPE_UD,
-                 BRW_VERTICAL_STRIDE_0,
-                 BRW_WIDTH_1,
-                 BRW_HORIZONTAL_STRIDE_0,
-                 BRW_SWIZZLE_XXXX,
-                 WRITEMASK_X);
-}
-
-
-static INLINE struct brw_reg brw_flag_reg(int reg, int subreg)
-{
-   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
-                     BRW_ARF_FLAG + reg,
-                     subreg);
-}
-
-
-static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
-{
-   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
-                     BRW_ARF_MASK,
-                     subnr);
-}
-
-static INLINE struct brw_reg brw_message_reg( GLuint nr )
-{
-   assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
-   return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
-                      nr,
-                      0);
-}
-
-
-
-
-/* This is almost always called with a numeric constant argument, so
- * make things easy to evaluate at compile time:
- */
-static INLINE GLuint cvt( GLuint val )
-{
-   switch (val) {
-   case 0: return 0;
-   case 1: return 1;
-   case 2: return 2;
-   case 4: return 3;
-   case 8: return 4;
-   case 16: return 5;
-   case 32: return 6;
-   }
-   return 0;
-}
-
-static INLINE struct brw_reg stride( struct brw_reg reg,
-                                      GLuint vstride,
-                                      GLuint width,
-                                      GLuint hstride )
-{
-   reg.vstride = cvt(vstride);
-   reg.width = cvt(width) - 1;
-   reg.hstride = cvt(hstride);
-   return reg;
-}
-
-
-static INLINE struct brw_reg vec16( struct brw_reg reg )
-{
-   return stride(reg, 16,16,1);
-}
-
-static INLINE struct brw_reg vec8( struct brw_reg reg )
-{
-   return stride(reg, 8,8,1);
-}
-
-static INLINE struct brw_reg vec4( struct brw_reg reg )
-{
-   return stride(reg, 4,4,1);
-}
-
-static INLINE struct brw_reg vec2( struct brw_reg reg )
-{
-   return stride(reg, 2,2,1);
-}
-
-static INLINE struct brw_reg vec1( struct brw_reg reg )
-{
-   return stride(reg, 0,1,0);
-}
-
-
-static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
-{
-   return vec1(suboffset(reg, elt));
-}
-
-static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
-{
-   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
-}
-
-static INLINE struct brw_reg get_element_d( struct brw_reg reg, GLuint elt )
-{
-   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
-}
-
-
-static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
-                                           GLuint x,
-                                           GLuint y, 
-                                           GLuint z,
-                                           GLuint w)
-{
-   assert(reg.file != BRW_IMMEDIATE_VALUE);
-
-   reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
-                                      BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
-                                      BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
-                                      BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
-   return reg;
-}
-
-
-static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
-                                            GLuint x )
-{
-   return brw_swizzle(reg, x, x, x, x);
-}
-
-static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
-                                             GLuint mask )
-{
-   assert(reg.file != BRW_IMMEDIATE_VALUE);
-   reg.dw1.bits.writemask &= mask;
-   return reg;
-}
-
-static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
-                                                 GLuint mask )
-{
-   assert(reg.file != BRW_IMMEDIATE_VALUE);
-   reg.dw1.bits.writemask = mask;
-   return reg;
-}
-
-static INLINE struct brw_reg negate( struct brw_reg reg )
-{
-   reg.negate ^= 1;
-   return reg;
-}
-
-static INLINE struct brw_reg brw_abs( struct brw_reg reg )
-{
-   reg.abs = 1;
-   reg.negate = 0;
-   return reg;
-}
-
-/***********************************************************************
- */
-static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
-                                                 GLint offset )
-{
-   struct brw_reg reg =  brw_vec4_grf(0, 0);
-   reg.subnr = subnr;
-   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
-   reg.dw1.bits.indirect_offset = offset;
-   return reg;
-}
-
-static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
-                                                 GLint offset )
-{
-   struct brw_reg reg =  brw_vec1_grf(0, 0);
-   reg.subnr = subnr;
-   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
-   reg.dw1.bits.indirect_offset = offset;
-   return reg;
-}
-
-static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
-{
-   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
-}
-
-static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
-{
-   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
-}
-
-static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
-{
-   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
-}
-
-static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
-{
-   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
-}
-
-static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
-{
-   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
-}
-
-static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
-{
-   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
-}
-
-static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
-{
-   return brw_address_reg(ptr.addr_subnr);
-}
-
-static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
-{
-   ptr.addr_offset += offset;
-   return ptr;
-}
-
-static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
-{
-   struct brw_indirect ptr;
-   ptr.addr_subnr = addr_subnr;
-   ptr.addr_offset = offset;
-   ptr.pad = 0;
-   return ptr;
-}
-
-/** Do two brw_regs refer to the same register? */
-static INLINE bool
-brw_same_reg(struct brw_reg r1, struct brw_reg r2)
-{
-   return r1.file == r2.file && r1.nr == r2.nr;
-}
-
 static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
 {
    return &p->store[p->nr_insn];
@@ -1052,9 +347,6 @@ void brw_CMP(struct brw_compile *p,
             struct brw_reg src0,
             struct brw_reg src1);
 
-void brw_print_reg( struct brw_reg reg );
-
-
 /*********************************************************************** 
  * brw_eu_util.c:
  */
diff --git a/src/mesa/drivers/dri/i965/brw_reg.h b/src/mesa/drivers/dri/i965/brw_reg.h
new file mode 100644 (file)
index 0000000..c66ccc2
--- /dev/null
@@ -0,0 +1,777 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+/** @file brw_reg.h
+ *
+ * This file defines struct brw_reg, which is our representation for EU
+ * registers.  They're not a hardware specific format, just an abstraction
+ * that intends to capture the full flexibility of the hardware registers.
+ *
+ * The brw_eu_emit.c layer's brw_set_dest/brw_set_src[01] functions encode
+ * the abstract brw_reg type into the actual hardware instruction encoding.
+ */
+
+#ifndef BRW_REG_H
+#define BRW_REG_H
+
+#include <stdbool.h>
+#include "program/prog_instruction.h"
+#include "brw_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
+#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
+
+#define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
+#define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
+#define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
+#define BRW_SWIZZLE_YYYY      BRW_SWIZZLE4(1,1,1,1)
+#define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
+#define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
+#define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
+
+static inline bool
+brw_is_single_value_swizzle(int swiz)
+{
+   return (swiz == BRW_SWIZZLE_XXXX ||
+           swiz == BRW_SWIZZLE_YYYY ||
+           swiz == BRW_SWIZZLE_ZZZZ ||
+           swiz == BRW_SWIZZLE_WWWW);
+}
+
+#define REG_SIZE (8*4)
+
+/* These aren't hardware structs, just something useful for us to pass around:
+ *
+ * Align1 operation has a lot of control over input ranges.  Used in
+ * WM programs to implement shaders decomposed into "channel serial"
+ * or "structure of array" form:
+ */
+struct brw_reg {
+   unsigned type:4;
+   unsigned file:2;
+   unsigned nr:8;
+   unsigned subnr:5;              /* :1 in align16 */
+   unsigned negate:1;             /* source only */
+   unsigned abs:1;                /* source only */
+   unsigned vstride:4;            /* source only */
+   unsigned width:3;              /* src only, align1 only */
+   unsigned hstride:2;            /* align1 only */
+   unsigned address_mode:1;       /* relative addressing, hopefully! */
+   unsigned pad0:1;
+
+   union {
+      struct {
+         unsigned swizzle:8;      /* src only, align16 only */
+         unsigned writemask:4;    /* dest only, align16 only */
+         int  indirect_offset:10; /* relative addressing offset */
+         unsigned pad1:10;        /* two dwords total */
+      } bits;
+
+      float f;
+      int   d;
+      unsigned ud;
+   } dw1;
+};
+
+
+struct brw_indirect {
+   unsigned addr_subnr:4;
+   int addr_offset:10;
+   unsigned pad:18;
+};
+
+
+static inline int
+type_sz(unsigned type)
+{
+   switch(type) {
+   case BRW_REGISTER_TYPE_UD:
+   case BRW_REGISTER_TYPE_D:
+   case BRW_REGISTER_TYPE_F:
+      return 4;
+   case BRW_REGISTER_TYPE_HF:
+   case BRW_REGISTER_TYPE_UW:
+   case BRW_REGISTER_TYPE_W:
+      return 2;
+   case BRW_REGISTER_TYPE_UB:
+   case BRW_REGISTER_TYPE_B:
+      return 1;
+   default:
+      return 0;
+   }
+}
+
+/**
+ * Construct a brw_reg.
+ * \param file      one of the BRW_x_REGISTER_FILE values
+ * \param nr        register number/index
+ * \param subnr     register sub number
+ * \param type      one of BRW_REGISTER_TYPE_x
+ * \param vstride   one of BRW_VERTICAL_STRIDE_x
+ * \param width     one of BRW_WIDTH_x
+ * \param hstride   one of BRW_HORIZONTAL_STRIDE_x
+ * \param swizzle   one of BRW_SWIZZLE_x
+ * \param writemask WRITEMASK_X/Y/Z/W bitfield
+ */
+static inline struct brw_reg
+brw_reg(unsigned file,
+        unsigned nr,
+        unsigned subnr,
+        unsigned type,
+        unsigned vstride,
+        unsigned width,
+        unsigned hstride,
+        unsigned swizzle,
+        unsigned writemask)
+{
+   struct brw_reg reg;
+   if (file == BRW_GENERAL_REGISTER_FILE)
+      assert(nr < BRW_MAX_GRF);
+   else if (file == BRW_MESSAGE_REGISTER_FILE)
+      assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
+   else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
+      assert(nr <= BRW_ARF_TIMESTAMP);
+
+   reg.type = type;
+   reg.file = file;
+   reg.nr = nr;
+   reg.subnr = subnr * type_sz(type);
+   reg.negate = 0;
+   reg.abs = 0;
+   reg.vstride = vstride;
+   reg.width = width;
+   reg.hstride = hstride;
+   reg.address_mode = BRW_ADDRESS_DIRECT;
+   reg.pad0 = 0;
+
+   /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
+    * set swizzle and writemask to W, as the lower bits of subnr will
+    * be lost when converted to align16.  This is probably too much to
+    * keep track of as you'd want it adjusted by suboffset(), etc.
+    * Perhaps fix up when converting to align16?
+    */
+   reg.dw1.bits.swizzle = swizzle;
+   reg.dw1.bits.writemask = writemask;
+   reg.dw1.bits.indirect_offset = 0;
+   reg.dw1.bits.pad1 = 0;
+   return reg;
+}
+
+/** Construct float[16] register */
+static inline struct brw_reg
+brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
+{
+   return brw_reg(file,
+                  nr,
+                  subnr,
+                  BRW_REGISTER_TYPE_F,
+                  BRW_VERTICAL_STRIDE_16,
+                  BRW_WIDTH_16,
+                  BRW_HORIZONTAL_STRIDE_1,
+                  BRW_SWIZZLE_XYZW,
+                  WRITEMASK_XYZW);
+}
+
+/** Construct float[8] register */
+static inline struct brw_reg
+brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
+{
+   return brw_reg(file,
+                  nr,
+                  subnr,
+                  BRW_REGISTER_TYPE_F,
+                  BRW_VERTICAL_STRIDE_8,
+                  BRW_WIDTH_8,
+                  BRW_HORIZONTAL_STRIDE_1,
+                  BRW_SWIZZLE_XYZW,
+                  WRITEMASK_XYZW);
+}
+
+/** Construct float[4] register */
+static inline struct brw_reg
+brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
+{
+   return brw_reg(file,
+                  nr,
+                  subnr,
+                  BRW_REGISTER_TYPE_F,
+                  BRW_VERTICAL_STRIDE_4,
+                  BRW_WIDTH_4,
+                  BRW_HORIZONTAL_STRIDE_1,
+                  BRW_SWIZZLE_XYZW,
+                  WRITEMASK_XYZW);
+}
+
+/** Construct float[2] register */
+static inline struct brw_reg
+brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr)
+{
+   return brw_reg(file,
+                  nr,
+                  subnr,
+                  BRW_REGISTER_TYPE_F,
+                  BRW_VERTICAL_STRIDE_2,
+                  BRW_WIDTH_2,
+                  BRW_HORIZONTAL_STRIDE_1,
+                  BRW_SWIZZLE_XYXY,
+                  WRITEMASK_XY);
+}
+
+/** Construct float[1] register */
+static inline struct brw_reg
+brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
+{
+   return brw_reg(file,
+                  nr,
+                  subnr,
+                  BRW_REGISTER_TYPE_F,
+                  BRW_VERTICAL_STRIDE_0,
+                  BRW_WIDTH_1,
+                  BRW_HORIZONTAL_STRIDE_0,
+                  BRW_SWIZZLE_XXXX,
+                  WRITEMASK_X);
+}
+
+
+static inline struct brw_reg
+retype(struct brw_reg reg, unsigned type)
+{
+   reg.type = type;
+   return reg;
+}
+
+static inline struct brw_reg
+sechalf(struct brw_reg reg)
+{
+   if (reg.vstride)
+      reg.nr++;
+   return reg;
+}
+
+static inline struct brw_reg
+suboffset(struct brw_reg reg, unsigned delta)
+{
+   reg.subnr += delta * type_sz(reg.type);
+   return reg;
+}
+
+
+static inline struct brw_reg
+offset(struct brw_reg reg, unsigned delta)
+{
+   reg.nr += delta;
+   return reg;
+}
+
+
+static inline struct brw_reg
+byte_offset(struct brw_reg reg, unsigned bytes)
+{
+   unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
+   reg.nr = newoffset / REG_SIZE;
+   reg.subnr = newoffset % REG_SIZE;
+   return reg;
+}
+
+
+/** Construct unsigned word[16] register */
+static inline struct brw_reg
+brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
+{
+   return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
+}
+
+/** Construct unsigned word[8] register */
+static inline struct brw_reg
+brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr)
+{
+   return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
+}
+
+/** Construct unsigned word[1] register */
+static inline struct brw_reg
+brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr)
+{
+   return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
+}
+
+static inline struct brw_reg
+brw_imm_reg(unsigned type)
+{
+   return brw_reg(BRW_IMMEDIATE_VALUE,
+                  0,
+                  0,
+                  type,
+                  BRW_VERTICAL_STRIDE_0,
+                  BRW_WIDTH_1,
+                  BRW_HORIZONTAL_STRIDE_0,
+                  0,
+                  0);
+}
+
+/** Construct float immediate register */
+static inline struct brw_reg
+brw_imm_f(float f)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
+   imm.dw1.f = f;
+   return imm;
+}
+
+/** Construct integer immediate register */
+static inline struct brw_reg
+brw_imm_d(int d)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
+   imm.dw1.d = d;
+   return imm;
+}
+
+/** Construct uint immediate register */
+static inline struct brw_reg
+brw_imm_ud(unsigned ud)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
+   imm.dw1.ud = ud;
+   return imm;
+}
+
+/** Construct ushort immediate register */
+static inline struct brw_reg
+brw_imm_uw(uint16_t uw)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
+   imm.dw1.ud = uw | (uw << 16);
+   return imm;
+}
+
+/** Construct short immediate register */
+static inline struct brw_reg
+brw_imm_w(int16_t w)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
+   imm.dw1.d = w | (w << 16);
+   return imm;
+}
+
+/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
+ * numbers alias with _V and _VF below:
+ */
+
+/** Construct vector of eight signed half-byte values */
+static inline struct brw_reg
+brw_imm_v(unsigned v)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
+   imm.vstride = BRW_VERTICAL_STRIDE_0;
+   imm.width = BRW_WIDTH_8;
+   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
+   imm.dw1.ud = v;
+   return imm;
+}
+
+/** Construct vector of four 8-bit float values */
+static inline struct brw_reg
+brw_imm_vf(unsigned v)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
+   imm.vstride = BRW_VERTICAL_STRIDE_0;
+   imm.width = BRW_WIDTH_4;
+   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
+   imm.dw1.ud = v;
+   return imm;
+}
+
+#define VF_ZERO 0x0
+#define VF_ONE  0x30
+#define VF_NEG  (1<<7)
+
+static inline struct brw_reg
+brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
+   imm.vstride = BRW_VERTICAL_STRIDE_0;
+   imm.width = BRW_WIDTH_4;
+   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
+   imm.dw1.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
+   return imm;
+}
+
+
+static inline struct brw_reg
+brw_address(struct brw_reg reg)
+{
+   return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
+}
+
+/** Construct float[1] general-purpose register */
+static inline struct brw_reg
+brw_vec1_grf(unsigned nr, unsigned subnr)
+{
+   return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+/** Construct float[2] general-purpose register */
+static inline struct brw_reg
+brw_vec2_grf(unsigned nr, unsigned subnr)
+{
+   return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+/** Construct float[4] general-purpose register */
+static inline struct brw_reg
+brw_vec4_grf(unsigned nr, unsigned subnr)
+{
+   return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+/** Construct float[8] general-purpose register */
+static inline struct brw_reg
+brw_vec8_grf(unsigned nr, unsigned subnr)
+{
+   return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+
+static inline struct brw_reg
+brw_uw8_grf(unsigned nr, unsigned subnr)
+{
+   return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+static inline struct brw_reg
+brw_uw16_grf(unsigned nr, unsigned subnr)
+{
+   return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+
+/** Construct null register (usually used for setting condition codes) */
+static inline struct brw_reg
+brw_null_reg(void)
+{
+   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0);
+}
+
+static inline struct brw_reg
+brw_address_reg(unsigned subnr)
+{
+   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr);
+}
+
+/* If/else instructions break in align16 mode if writemask & swizzle
+ * aren't xyzw.  This goes against the convention for other scalar
+ * regs:
+ */
+static inline struct brw_reg
+brw_ip_reg(void)
+{
+   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+                  BRW_ARF_IP,
+                  0,
+                  BRW_REGISTER_TYPE_UD,
+                  BRW_VERTICAL_STRIDE_4, /* ? */
+                  BRW_WIDTH_1,
+                  BRW_HORIZONTAL_STRIDE_0,
+                  BRW_SWIZZLE_XYZW, /* NOTE! */
+                  WRITEMASK_XYZW); /* NOTE! */
+}
+
+static inline struct brw_reg
+brw_acc_reg(void)
+{
+   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0);
+}
+
+static inline struct brw_reg
+brw_notification_1_reg(void)
+{
+
+   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+                  BRW_ARF_NOTIFICATION_COUNT,
+                  1,
+                  BRW_REGISTER_TYPE_UD,
+                  BRW_VERTICAL_STRIDE_0,
+                  BRW_WIDTH_1,
+                  BRW_HORIZONTAL_STRIDE_0,
+                  BRW_SWIZZLE_XXXX,
+                  WRITEMASK_X);
+}
+
+
+static inline struct brw_reg
+brw_flag_reg(int reg, int subreg)
+{
+   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+                      BRW_ARF_FLAG + reg, subreg);
+}
+
+
+static inline struct brw_reg
+brw_mask_reg(unsigned subnr)
+{
+   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr);
+}
+
+static inline struct brw_reg
+brw_message_reg(unsigned nr)
+{
+   assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
+   return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0);
+}
+
+
+/* This is almost always called with a numeric constant argument, so
+ * make things easy to evaluate at compile time:
+ */
+static inline unsigned cvt(unsigned val)
+{
+   switch (val) {
+   case 0: return 0;
+   case 1: return 1;
+   case 2: return 2;
+   case 4: return 3;
+   case 8: return 4;
+   case 16: return 5;
+   case 32: return 6;
+   }
+   return 0;
+}
+
+static inline struct brw_reg
+stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride)
+{
+   reg.vstride = cvt(vstride);
+   reg.width = cvt(width) - 1;
+   reg.hstride = cvt(hstride);
+   return reg;
+}
+
+
+static inline struct brw_reg
+vec16(struct brw_reg reg)
+{
+   return stride(reg, 16,16,1);
+}
+
+static inline struct brw_reg
+vec8(struct brw_reg reg)
+{
+   return stride(reg, 8,8,1);
+}
+
+static inline struct brw_reg
+vec4(struct brw_reg reg)
+{
+   return stride(reg, 4,4,1);
+}
+
+static inline struct brw_reg
+vec2(struct brw_reg reg)
+{
+   return stride(reg, 2,2,1);
+}
+
+static inline struct brw_reg
+vec1(struct brw_reg reg)
+{
+   return stride(reg, 0,1,0);
+}
+
+
+static inline struct brw_reg
+get_element(struct brw_reg reg, unsigned elt)
+{
+   return vec1(suboffset(reg, elt));
+}
+
+static inline struct brw_reg
+get_element_ud(struct brw_reg reg, unsigned elt)
+{
+   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
+}
+
+static inline struct brw_reg
+get_element_d(struct brw_reg reg, unsigned elt)
+{
+   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
+}
+
+
+static inline struct brw_reg
+brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w)
+{
+   assert(reg.file != BRW_IMMEDIATE_VALUE);
+
+   reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
+                                       BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
+                                       BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
+                                       BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
+   return reg;
+}
+
+
+static inline struct brw_reg
+brw_swizzle1(struct brw_reg reg, unsigned x)
+{
+   return brw_swizzle(reg, x, x, x, x);
+}
+
+static inline struct brw_reg
+brw_writemask(struct brw_reg reg, unsigned mask)
+{
+   assert(reg.file != BRW_IMMEDIATE_VALUE);
+   reg.dw1.bits.writemask &= mask;
+   return reg;
+}
+
+static inline struct brw_reg
+brw_set_writemask(struct brw_reg reg, unsigned mask)
+{
+   assert(reg.file != BRW_IMMEDIATE_VALUE);
+   reg.dw1.bits.writemask = mask;
+   return reg;
+}
+
+static inline struct brw_reg
+negate(struct brw_reg reg)
+{
+   reg.negate ^= 1;
+   return reg;
+}
+
+static inline struct brw_reg
+brw_abs(struct brw_reg reg)
+{
+   reg.abs = 1;
+   reg.negate = 0;
+   return reg;
+}
+
+/************************************************************************/
+
+static inline struct brw_reg
+brw_vec4_indirect(unsigned subnr, int offset)
+{
+   struct brw_reg reg =  brw_vec4_grf(0, 0);
+   reg.subnr = subnr;
+   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
+   reg.dw1.bits.indirect_offset = offset;
+   return reg;
+}
+
+static inline struct brw_reg
+brw_vec1_indirect(unsigned subnr, int offset)
+{
+   struct brw_reg reg =  brw_vec1_grf(0, 0);
+   reg.subnr = subnr;
+   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
+   reg.dw1.bits.indirect_offset = offset;
+   return reg;
+}
+
+static inline struct brw_reg
+deref_4f(struct brw_indirect ptr, int offset)
+{
+   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
+}
+
+static inline struct brw_reg
+deref_1f(struct brw_indirect ptr, int offset)
+{
+   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
+}
+
+static inline struct brw_reg
+deref_4b(struct brw_indirect ptr, int offset)
+{
+   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
+}
+
+static inline struct brw_reg
+deref_1uw(struct brw_indirect ptr, int offset)
+{
+   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
+}
+
+static inline struct brw_reg
+deref_1d(struct brw_indirect ptr, int offset)
+{
+   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
+}
+
+static inline struct brw_reg
+deref_1ud(struct brw_indirect ptr, int offset)
+{
+   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
+}
+
+static inline struct brw_reg
+get_addr_reg(struct brw_indirect ptr)
+{
+   return brw_address_reg(ptr.addr_subnr);
+}
+
+static inline struct brw_indirect
+brw_indirect_offset(struct brw_indirect ptr, int offset)
+{
+   ptr.addr_offset += offset;
+   return ptr;
+}
+
+static inline struct brw_indirect
+brw_indirect(unsigned addr_subnr, int offset)
+{
+   struct brw_indirect ptr;
+   ptr.addr_subnr = addr_subnr;
+   ptr.addr_offset = offset;
+   ptr.pad = 0;
+   return ptr;
+}
+
+/** Do two brw_regs refer to the same register? */
+static inline bool
+brw_same_reg(struct brw_reg r1, struct brw_reg r2)
+{
+   return r1.file == r2.file && r1.nr == r2.nr;
+}
+
+void brw_print_reg(struct brw_reg reg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif