#define BRW_REG_H
#include <stdbool.h>
-#include "main/imports.h"
#include "main/compiler.h"
#include "main/macros.h"
#include "program/prog_instruction.h"
#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)
+#define BRW_SWIZZLE_XZXZ BRW_SWIZZLE4(0,2,0,2)
#define BRW_SWIZZLE_YZXW BRW_SWIZZLE4(1,2,0,3)
+#define BRW_SWIZZLE_YWYW BRW_SWIZZLE4(1,3,1,3)
#define BRW_SWIZZLE_ZXYW BRW_SWIZZLE4(2,0,1,3)
#define BRW_SWIZZLE_ZWZW BRW_SWIZZLE4(2,3,2,3)
+#define BRW_SWIZZLE_WZYX BRW_SWIZZLE4(3,2,1,0)
+
+#define BRW_SWZ_COMP_INPUT(comp) (BRW_SWIZZLE_XYZW >> ((comp)*2))
+#define BRW_SWZ_COMP_OUTPUT(comp) (BRW_SWIZZLE_XYZW << ((comp)*2))
static inline bool
brw_is_single_value_swizzle(unsigned swiz)
};
unsigned brw_reg_type_to_hw_type(const struct brw_device_info *devinfo,
- enum brw_reg_type type, unsigned file);
+ enum brw_reg_type type, enum brw_reg_file file);
const char *brw_reg_type_letters(unsigned brw_reg_type);
+uint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz);
#define REG_SIZE (8*4)
* or "structure of array" form:
*/
struct brw_reg {
- enum brw_reg_type 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 {
+ enum brw_reg_type type:4;
+ enum brw_reg_file file:3; /* :2 hardware format */
+ unsigned negate:1; /* source only */
+ unsigned abs:1; /* source only */
+ unsigned address_mode:1; /* relative addressing, hopefully! */
+ unsigned pad0:1;
+ unsigned subnr:5; /* :1 in align16 */
+ unsigned nr:16;
+ };
+ uint32_t bits;
+ };
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 */
+ unsigned vstride:4; /* source only */
+ unsigned width:3; /* src only, align1 only */
+ unsigned hstride:2; /* align1 only */
+ unsigned pad1:1;
};
+ double df;
+ uint64_t u64;
float f;
int d;
unsigned ud;
};
};
+static inline bool
+brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
+{
+ const bool df = a->type == BRW_REGISTER_TYPE_DF && a->file == IMM;
+ return a->bits == b->bits && (df ? a->u64 == b->u64 : a->ud == b->ud);
+}
struct brw_indirect {
unsigned addr_subnr:4;
switch(type) {
case BRW_REGISTER_TYPE_UQ:
case BRW_REGISTER_TYPE_Q:
+ case BRW_REGISTER_TYPE_DF:
return 8;
case BRW_REGISTER_TYPE_UD:
case BRW_REGISTER_TYPE_D:
case BRW_REGISTER_TYPE_F:
+ case BRW_REGISTER_TYPE_VF:
return 4;
case BRW_REGISTER_TYPE_UW:
case BRW_REGISTER_TYPE_W:
+ case BRW_REGISTER_TYPE_UV:
+ case BRW_REGISTER_TYPE_V:
+ case BRW_REGISTER_TYPE_HF:
return 2;
case BRW_REGISTER_TYPE_UB:
case BRW_REGISTER_TYPE_B:
return 1;
default:
- return 0;
+ unreachable("not reached");
}
}
-static inline bool
-type_is_signed(unsigned type)
+/**
+ * Return an integer type of the requested size and signedness.
+ */
+static inline enum brw_reg_type
+brw_int_type(unsigned sz, bool is_signed)
{
- switch(type) {
- case BRW_REGISTER_TYPE_D:
- case BRW_REGISTER_TYPE_W:
- case BRW_REGISTER_TYPE_F:
- case BRW_REGISTER_TYPE_B:
- case BRW_REGISTER_TYPE_V:
- case BRW_REGISTER_TYPE_VF:
- case BRW_REGISTER_TYPE_DF:
- case BRW_REGISTER_TYPE_HF:
- case BRW_REGISTER_TYPE_Q:
- return true;
-
- case BRW_REGISTER_TYPE_UD:
- case BRW_REGISTER_TYPE_UW:
- case BRW_REGISTER_TYPE_UB:
- case BRW_REGISTER_TYPE_UV:
- case BRW_REGISTER_TYPE_UQ:
- return false;
-
+ switch (sz) {
+ case 1:
+ return (is_signed ? BRW_REGISTER_TYPE_B : BRW_REGISTER_TYPE_UB);
+ case 2:
+ return (is_signed ? BRW_REGISTER_TYPE_W : BRW_REGISTER_TYPE_UW);
+ case 4:
+ return (is_signed ? BRW_REGISTER_TYPE_D : BRW_REGISTER_TYPE_UD);
+ case 8:
+ return (is_signed ? BRW_REGISTER_TYPE_Q : BRW_REGISTER_TYPE_UQ);
default:
- unreachable("not reached");
+ unreachable("Not reached.");
}
}
* \param writemask WRITEMASK_X/Y/Z/W bitfield
*/
static inline struct brw_reg
-brw_reg(unsigned file,
+brw_reg(enum brw_reg_file file,
unsigned nr,
unsigned subnr,
unsigned negate,
reg.type = type;
reg.file = file;
- reg.nr = nr;
- reg.subnr = subnr * type_sz(type);
reg.negate = negate;
reg.abs = abs;
- reg.vstride = vstride;
- reg.width = width;
- reg.hstride = hstride;
reg.address_mode = BRW_ADDRESS_DIRECT;
reg.pad0 = 0;
+ reg.subnr = subnr * type_sz(type);
+ reg.nr = nr;
/* 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
reg.swizzle = swizzle;
reg.writemask = writemask;
reg.indirect_offset = 0;
+ reg.vstride = vstride;
+ reg.width = width;
+ reg.hstride = hstride;
reg.pad1 = 0;
return reg;
}
/** Construct float[16] register */
static inline struct brw_reg
-brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr)
+brw_vec16_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
{
return brw_reg(file,
nr,
/** Construct float[8] register */
static inline struct brw_reg
-brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr)
+brw_vec8_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
{
return brw_reg(file,
nr,
/** Construct float[4] register */
static inline struct brw_reg
-brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr)
+brw_vec4_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
{
return brw_reg(file,
nr,
/** Construct float[2] register */
static inline struct brw_reg
-brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr)
+brw_vec2_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
{
return brw_reg(file,
nr,
/** Construct float[1] register */
static inline struct brw_reg
-brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr)
+brw_vec1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
{
return brw_reg(file,
nr,
}
static inline struct brw_reg
-brw_vecn_reg(unsigned width, unsigned file, unsigned nr, unsigned subnr)
+brw_vecn_reg(unsigned width, enum brw_reg_file file,
+ unsigned nr, unsigned subnr)
{
switch (width) {
case 1:
/** Construct unsigned word[16] register */
static inline struct brw_reg
-brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr)
+brw_uw16_reg(enum brw_reg_file 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)
+brw_uw8_reg(enum brw_reg_file 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)
+brw_uw1_reg(enum brw_reg_file file, unsigned nr, unsigned subnr)
{
return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
}
}
/** Construct float immediate register */
+static inline struct brw_reg
+brw_imm_df(double df)
+{
+ struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_DF);
+ imm.df = df;
+ return imm;
+}
+
static inline struct brw_reg
brw_imm_f(float f)
{
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.ud = v;
return imm;
}
+/** Construct vector of eight unsigned half-byte values */
+static inline struct brw_reg
+brw_imm_uv(unsigned uv)
+{
+ struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UV);
+ imm.ud = uv;
+ 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.ud = v;
return imm;
}
-/**
- * Convert an integer into a "restricted" 8-bit float, used in vector
- * immediates. The 8-bit floating point format has a sign bit, an
- * excess-3 3-bit exponent, and a 4-bit mantissa. All integer values
- * from -31 to 31 can be represented exactly.
- */
-static inline uint8_t
-int_to_float8(int x)
-{
- if (x == 0) {
- return 0;
- } else if (x < 0) {
- return 1 << 7 | int_to_float8(-x);
- } else {
- const unsigned exponent = _mesa_logbase2(x);
- const unsigned mantissa = (x - (1 << exponent)) << (4 - exponent);
- assert(exponent <= 4);
- return (exponent + 3) << 4 | mantissa;
- }
-}
-
-/**
- * Construct a floating-point packed vector immediate from its integer
- * values. \sa int_to_float8()
- */
static inline struct brw_reg
-brw_imm_vf4(int v0, int v1, int v2, int v3)
+brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
{
- return brw_imm_vf((int_to_float8(v0) << 0) |
- (int_to_float8(v1) << 8) |
- (int_to_float8(v2) << 16) |
- (int_to_float8(v3) << 24));
+ 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.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24));
+ return imm;
}
WRITEMASK_X);
}
+static inline struct brw_reg
+brw_sr0_reg(void)
+{
+ return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+ BRW_ARF_STATE,
+ 0,
+ 0,
+ 0,
+ BRW_REGISTER_TYPE_UD,
+ BRW_VERTICAL_STRIDE_8,
+ BRW_WIDTH_8,
+ BRW_HORIZONTAL_STRIDE_1,
+ BRW_SWIZZLE_XYZW,
+ WRITEMASK_XYZW);
+}
+
static inline struct brw_reg
brw_acc_reg(unsigned width)
{
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)
+brw_swizzle(struct brw_reg reg, unsigned swz)
{
- assert(reg.file != BRW_IMMEDIATE_VALUE);
+ if (reg.file == BRW_IMMEDIATE_VALUE)
+ reg.ud = brw_swizzle_immediate(reg.type, reg.ud, swz);
+ else
+ reg.swizzle = brw_compose_swizzle(swz, reg.swizzle);
- reg.swizzle = brw_compose_swizzle(BRW_SWIZZLE4(x, y, z, w),
- reg.swizzle);
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)
{
return (1 << n) - 1;
}
+static inline unsigned
+brw_writemask_for_component_packing(unsigned n, unsigned first_component)
+{
+ assert(first_component + n <= 4);
+ return (((1 << n) - 1) << first_component);
+}
+
static inline struct brw_reg
negate(struct brw_reg reg)
{