mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-29 23:10:11 +01:00
intel/brw: Rework BRW_REGISTER_TYPE's representation semantics
In ancient days, we directly used the hardware register type encodings throughout the compiler. As more GPU generations came out, encodings shifted, and we moved to an abstract enum that we could encode/decode to a particular GPU's hardware encoding. But there was no particular meaning behind any particular value. One downside to this approach is that we end up with switch statements galore. Want to know a type's size? Switch. Convert a unsigned type to a signed one? Switch. Get a type with the same base type, but different bit size? Switch. This is both inefficient and inconvenient. In contrast, nir_alu_type takes a nicer approach - the type encoding has certain bits representing the base type, and others encoding the size of the type. Switching base types or sizes is a simple matter of masking out the relevant field and substituting a different one. Tigerlake's encoding adopts a similar approach: two bits represent the size as a 2-bit unsigned number n, where the bit size is (8 * 2^n). Two more bits represent the base type. Past encodings were a bit ad hoc as new data types were added over time, but Gfx12 is organized (mostly). This patch converts our brw_reg_type enum over to a new system that's patterned after the Tigerlake style (for easy conversion) while deviating in a few ways that make our vector immediate type size handling simpler. Should we add additional base types, we're likely to continue deviating. Still, converting is much simpler. Type size calculations (which are performed all the time) are now a simple mask and shift, instead of a switch. We also adopt the name BRW_TYPE_* instead of BRW_REGISTER_TYPE_* because it's much shorter and easier to type. Similarly, we create new helper functions named brw_type_* for working with these types, with a cleaner naming convention. Legacy names still exist but will we dropped over the next few patches as pieces get cleaned up. Reviewed-by: Caio Oliveira <caio.oliveira@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28847>
This commit is contained in:
parent
c45e235df5
commit
9d8f2c4421
8 changed files with 358 additions and 471 deletions
|
|
@ -1586,6 +1586,7 @@ imm(FILE *file, const struct brw_isa_info *isa, enum brw_reg_type type,
|
|||
break;
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
case BRW_REGISTER_TYPE_B:
|
||||
default:
|
||||
format(file, "*** invalid immediate type %d ", type);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1512,6 +1512,7 @@ compact_immediate(const struct intel_device_info *devinfo,
|
|||
case BRW_REGISTER_TYPE_UQ:
|
||||
case BRW_REGISTER_TYPE_B:
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1555,6 +1556,8 @@ uncompact_immediate(const struct intel_device_info *devinfo,
|
|||
case BRW_REGISTER_TYPE_B:
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
unreachable("not reached");
|
||||
default:
|
||||
unreachable("invalid type");
|
||||
}
|
||||
} else {
|
||||
/* Replicate the 13th bit into the high 19 bits */
|
||||
|
|
@ -1570,10 +1573,10 @@ has_immediate(const struct intel_device_info *devinfo, const brw_inst *inst,
|
|||
{
|
||||
if (brw_inst_src0_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
|
||||
*type = brw_inst_src0_type(devinfo, inst);
|
||||
return *type != INVALID_REG_TYPE;
|
||||
return *type != BRW_TYPE_INVALID;
|
||||
} else if (brw_inst_src1_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
|
||||
*type = brw_inst_src1_type(devinfo, inst);
|
||||
return *type != INVALID_REG_TYPE;
|
||||
return *type != BRW_TYPE_INVALID;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -125,13 +125,7 @@ inst_is_split_send(const struct brw_isa_info *isa, const brw_inst *inst)
|
|||
static unsigned
|
||||
signed_type(unsigned type)
|
||||
{
|
||||
switch (type) {
|
||||
case BRW_REGISTER_TYPE_UD: return BRW_REGISTER_TYPE_D;
|
||||
case BRW_REGISTER_TYPE_UW: return BRW_REGISTER_TYPE_W;
|
||||
case BRW_REGISTER_TYPE_UB: return BRW_REGISTER_TYPE_B;
|
||||
case BRW_REGISTER_TYPE_UQ: return BRW_REGISTER_TYPE_Q;
|
||||
default: return type;
|
||||
}
|
||||
return brw_type_is_uint(type) ? (type | BRW_TYPE_BASE_SINT) : type;
|
||||
}
|
||||
|
||||
static enum brw_reg_type
|
||||
|
|
@ -266,25 +260,25 @@ invalid_values(const struct brw_isa_info *isa, const brw_inst *inst)
|
|||
if (num_sources == 3) {
|
||||
if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
|
||||
if (devinfo->ver >= 10) {
|
||||
ERROR_IF(brw_inst_3src_a1_dst_type (devinfo, inst) == INVALID_REG_TYPE ||
|
||||
brw_inst_3src_a1_src0_type(devinfo, inst) == INVALID_REG_TYPE ||
|
||||
brw_inst_3src_a1_src1_type(devinfo, inst) == INVALID_REG_TYPE ||
|
||||
brw_inst_3src_a1_src2_type(devinfo, inst) == INVALID_REG_TYPE,
|
||||
ERROR_IF(brw_inst_3src_a1_dst_type (devinfo, inst) == BRW_TYPE_INVALID ||
|
||||
brw_inst_3src_a1_src0_type(devinfo, inst) == BRW_TYPE_INVALID ||
|
||||
brw_inst_3src_a1_src1_type(devinfo, inst) == BRW_TYPE_INVALID ||
|
||||
brw_inst_3src_a1_src2_type(devinfo, inst) == BRW_TYPE_INVALID,
|
||||
"invalid register type encoding");
|
||||
} else {
|
||||
ERROR("Align1 mode not allowed on Gen < 10");
|
||||
}
|
||||
} else {
|
||||
ERROR_IF(brw_inst_3src_a16_dst_type(devinfo, inst) == INVALID_REG_TYPE ||
|
||||
brw_inst_3src_a16_src_type(devinfo, inst) == INVALID_REG_TYPE,
|
||||
ERROR_IF(brw_inst_3src_a16_dst_type(devinfo, inst) == BRW_TYPE_INVALID ||
|
||||
brw_inst_3src_a16_src_type(devinfo, inst) == BRW_TYPE_INVALID,
|
||||
"invalid register type encoding");
|
||||
}
|
||||
} else {
|
||||
ERROR_IF(brw_inst_dst_type (devinfo, inst) == INVALID_REG_TYPE ||
|
||||
ERROR_IF(brw_inst_dst_type (devinfo, inst) == BRW_TYPE_INVALID ||
|
||||
(num_sources > 0 &&
|
||||
brw_inst_src0_type(devinfo, inst) == INVALID_REG_TYPE) ||
|
||||
brw_inst_src0_type(devinfo, inst) == BRW_TYPE_INVALID) ||
|
||||
(num_sources > 1 &&
|
||||
brw_inst_src1_type(devinfo, inst) == INVALID_REG_TYPE),
|
||||
brw_inst_src1_type(devinfo, inst) == BRW_TYPE_INVALID),
|
||||
"invalid register type encoding");
|
||||
}
|
||||
|
||||
|
|
@ -468,8 +462,9 @@ execution_type_for_type(enum brw_reg_type type)
|
|||
case BRW_REGISTER_TYPE_V:
|
||||
case BRW_REGISTER_TYPE_UV:
|
||||
return BRW_REGISTER_TYPE_W;
|
||||
default:
|
||||
unreachable("invalid type");
|
||||
}
|
||||
unreachable("not reached");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -157,12 +157,12 @@ uint32_t brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz)
|
|||
struct brw_reg {
|
||||
union {
|
||||
struct {
|
||||
enum brw_reg_type type:4;
|
||||
enum brw_reg_type type:5;
|
||||
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:17;
|
||||
unsigned pad0:16;
|
||||
unsigned subnr:5; /* :1 in align16 */
|
||||
};
|
||||
uint32_t bits;
|
||||
|
|
@ -287,29 +287,7 @@ struct brw_indirect {
|
|||
static inline unsigned
|
||||
type_sz(unsigned type)
|
||||
{
|
||||
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_HF:
|
||||
/* [U]V components are 4-bit, but HW unpacks them to 16-bit (2 bytes) */
|
||||
case BRW_REGISTER_TYPE_UV:
|
||||
case BRW_REGISTER_TYPE_V:
|
||||
return 2;
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
case BRW_REGISTER_TYPE_B:
|
||||
return 1;
|
||||
default:
|
||||
unreachable("not reached");
|
||||
}
|
||||
return brw_type_size_bytes((enum brw_reg_type) type);
|
||||
}
|
||||
|
||||
static inline enum brw_reg_type
|
||||
|
|
|
|||
|
|
@ -25,225 +25,6 @@
|
|||
#include "brw_eu_defines.h"
|
||||
#include "dev/intel_device_info.h"
|
||||
|
||||
#define INVALID (-1)
|
||||
|
||||
enum hw_reg_type {
|
||||
BRW_HW_REG_TYPE_UD = 0,
|
||||
BRW_HW_REG_TYPE_D = 1,
|
||||
BRW_HW_REG_TYPE_UW = 2,
|
||||
BRW_HW_REG_TYPE_W = 3,
|
||||
BRW_HW_REG_TYPE_F = 7,
|
||||
GFX8_HW_REG_TYPE_UQ = 8,
|
||||
GFX8_HW_REG_TYPE_Q = 9,
|
||||
|
||||
BRW_HW_REG_TYPE_UB = 4,
|
||||
BRW_HW_REG_TYPE_B = 5,
|
||||
GFX7_HW_REG_TYPE_DF = 6,
|
||||
GFX8_HW_REG_TYPE_HF = 10,
|
||||
|
||||
GFX11_HW_REG_TYPE_UD = 0,
|
||||
GFX11_HW_REG_TYPE_D = 1,
|
||||
GFX11_HW_REG_TYPE_UW = 2,
|
||||
GFX11_HW_REG_TYPE_W = 3,
|
||||
GFX11_HW_REG_TYPE_UB = 4,
|
||||
GFX11_HW_REG_TYPE_B = 5,
|
||||
GFX11_HW_REG_TYPE_UQ = 6,
|
||||
GFX11_HW_REG_TYPE_Q = 7,
|
||||
GFX11_HW_REG_TYPE_HF = 8,
|
||||
GFX11_HW_REG_TYPE_F = 9,
|
||||
GFX11_HW_REG_TYPE_DF = 10,
|
||||
};
|
||||
|
||||
enum hw_imm_type {
|
||||
BRW_HW_IMM_TYPE_UD = 0,
|
||||
BRW_HW_IMM_TYPE_D = 1,
|
||||
BRW_HW_IMM_TYPE_UW = 2,
|
||||
BRW_HW_IMM_TYPE_W = 3,
|
||||
BRW_HW_IMM_TYPE_F = 7,
|
||||
GFX8_HW_IMM_TYPE_UQ = 8,
|
||||
GFX8_HW_IMM_TYPE_Q = 9,
|
||||
|
||||
BRW_HW_IMM_TYPE_UV = 4,
|
||||
BRW_HW_IMM_TYPE_VF = 5,
|
||||
BRW_HW_IMM_TYPE_V = 6,
|
||||
GFX8_HW_IMM_TYPE_DF = 10,
|
||||
GFX8_HW_IMM_TYPE_HF = 11,
|
||||
|
||||
GFX11_HW_IMM_TYPE_UD = 0,
|
||||
GFX11_HW_IMM_TYPE_D = 1,
|
||||
GFX11_HW_IMM_TYPE_UW = 2,
|
||||
GFX11_HW_IMM_TYPE_W = 3,
|
||||
GFX11_HW_IMM_TYPE_UV = 4,
|
||||
GFX11_HW_IMM_TYPE_V = 5,
|
||||
GFX11_HW_IMM_TYPE_UQ = 6,
|
||||
GFX11_HW_IMM_TYPE_Q = 7,
|
||||
GFX11_HW_IMM_TYPE_HF = 8,
|
||||
GFX11_HW_IMM_TYPE_F = 9,
|
||||
GFX11_HW_IMM_TYPE_DF = 10,
|
||||
GFX11_HW_IMM_TYPE_VF = 11,
|
||||
};
|
||||
|
||||
#define GFX12_HW_REG_TYPE_UINT(n) (n)
|
||||
#define GFX12_HW_REG_TYPE_SINT(n) (0x4 | (n))
|
||||
#define GFX12_HW_REG_TYPE_FLOAT(n) (0x8 | (n))
|
||||
|
||||
static const struct hw_type {
|
||||
enum hw_reg_type reg_type;
|
||||
enum hw_imm_type imm_type;
|
||||
} gfx8_hw_type[] = {
|
||||
[0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
|
||||
|
||||
[BRW_REGISTER_TYPE_DF] = { GFX7_HW_REG_TYPE_DF, GFX8_HW_IMM_TYPE_DF },
|
||||
[BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
|
||||
[BRW_REGISTER_TYPE_HF] = { GFX8_HW_REG_TYPE_HF, GFX8_HW_IMM_TYPE_HF },
|
||||
[BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
|
||||
|
||||
[BRW_REGISTER_TYPE_Q] = { GFX8_HW_REG_TYPE_Q, GFX8_HW_IMM_TYPE_Q },
|
||||
[BRW_REGISTER_TYPE_UQ] = { GFX8_HW_REG_TYPE_UQ, GFX8_HW_IMM_TYPE_UQ },
|
||||
[BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
|
||||
[BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
|
||||
[BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
|
||||
[BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
|
||||
[BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
|
||||
[BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
|
||||
[BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
|
||||
[BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
|
||||
}, gfx11_hw_type[] = {
|
||||
[0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
|
||||
|
||||
[BRW_REGISTER_TYPE_F] = { GFX11_HW_REG_TYPE_F, GFX11_HW_IMM_TYPE_F },
|
||||
[BRW_REGISTER_TYPE_HF] = { GFX11_HW_REG_TYPE_HF, GFX11_HW_IMM_TYPE_HF },
|
||||
[BRW_REGISTER_TYPE_VF] = { INVALID, GFX11_HW_IMM_TYPE_VF },
|
||||
|
||||
[BRW_REGISTER_TYPE_D] = { GFX11_HW_REG_TYPE_D, GFX11_HW_IMM_TYPE_D },
|
||||
[BRW_REGISTER_TYPE_UD] = { GFX11_HW_REG_TYPE_UD, GFX11_HW_IMM_TYPE_UD },
|
||||
[BRW_REGISTER_TYPE_W] = { GFX11_HW_REG_TYPE_W, GFX11_HW_IMM_TYPE_W },
|
||||
[BRW_REGISTER_TYPE_UW] = { GFX11_HW_REG_TYPE_UW, GFX11_HW_IMM_TYPE_UW },
|
||||
[BRW_REGISTER_TYPE_B] = { GFX11_HW_REG_TYPE_B, INVALID },
|
||||
[BRW_REGISTER_TYPE_UB] = { GFX11_HW_REG_TYPE_UB, INVALID },
|
||||
[BRW_REGISTER_TYPE_V] = { INVALID, GFX11_HW_IMM_TYPE_V },
|
||||
[BRW_REGISTER_TYPE_UV] = { INVALID, GFX11_HW_IMM_TYPE_UV },
|
||||
}, gfx12_hw_type[] = {
|
||||
[0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
|
||||
|
||||
[BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_FLOAT(2), GFX12_HW_REG_TYPE_FLOAT(2) },
|
||||
[BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_FLOAT(1), GFX12_HW_REG_TYPE_FLOAT(1) },
|
||||
[BRW_REGISTER_TYPE_VF] = { INVALID, GFX12_HW_REG_TYPE_FLOAT(0) },
|
||||
|
||||
[BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), GFX12_HW_REG_TYPE_SINT(2) },
|
||||
[BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), GFX12_HW_REG_TYPE_UINT(2) },
|
||||
[BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), GFX12_HW_REG_TYPE_SINT(1) },
|
||||
[BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), GFX12_HW_REG_TYPE_UINT(1) },
|
||||
[BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), INVALID },
|
||||
[BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), INVALID },
|
||||
[BRW_REGISTER_TYPE_V] = { INVALID, GFX12_HW_REG_TYPE_SINT(0) },
|
||||
[BRW_REGISTER_TYPE_UV] = { INVALID, GFX12_HW_REG_TYPE_UINT(0) },
|
||||
}, gfx125_hw_type[] = {
|
||||
[0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
|
||||
|
||||
[BRW_REGISTER_TYPE_DF] = { GFX12_HW_REG_TYPE_FLOAT(3), GFX12_HW_REG_TYPE_FLOAT(3) },
|
||||
[BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_FLOAT(2), GFX12_HW_REG_TYPE_FLOAT(2) },
|
||||
[BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_FLOAT(1), GFX12_HW_REG_TYPE_FLOAT(1) },
|
||||
[BRW_REGISTER_TYPE_VF] = { INVALID, GFX12_HW_REG_TYPE_FLOAT(0) },
|
||||
|
||||
[BRW_REGISTER_TYPE_Q] = { GFX12_HW_REG_TYPE_SINT(3), GFX12_HW_REG_TYPE_SINT(3) },
|
||||
[BRW_REGISTER_TYPE_UQ] = { GFX12_HW_REG_TYPE_UINT(3), GFX12_HW_REG_TYPE_UINT(3) },
|
||||
[BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), GFX12_HW_REG_TYPE_SINT(2) },
|
||||
[BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), GFX12_HW_REG_TYPE_UINT(2) },
|
||||
[BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), GFX12_HW_REG_TYPE_SINT(1) },
|
||||
[BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), GFX12_HW_REG_TYPE_UINT(1) },
|
||||
[BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), INVALID },
|
||||
[BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), INVALID },
|
||||
[BRW_REGISTER_TYPE_V] = { INVALID, GFX12_HW_REG_TYPE_SINT(0) },
|
||||
[BRW_REGISTER_TYPE_UV] = { INVALID, GFX12_HW_REG_TYPE_UINT(0) },
|
||||
};
|
||||
|
||||
/* SNB adds 3-src instructions (MAD and LRP) that only operate on floats, so
|
||||
* the types were implied. IVB adds BFE and BFI2 that operate on doublewords
|
||||
* and unsigned doublewords, so a new field is also available in the da3src
|
||||
* struct (part of struct brw_instruction.bits1 in brw_structs.h) to select
|
||||
* dst and shared-src types.
|
||||
*
|
||||
* CNL adds support for 3-src instructions in align1 mode, and with it support
|
||||
* for most register types.
|
||||
*/
|
||||
enum hw_3src_reg_type {
|
||||
GFX7_3SRC_TYPE_F = 0,
|
||||
GFX7_3SRC_TYPE_D = 1,
|
||||
GFX7_3SRC_TYPE_UD = 2,
|
||||
GFX7_3SRC_TYPE_DF = 3,
|
||||
GFX8_3SRC_TYPE_HF = 4,
|
||||
|
||||
/** When ExecutionDatatype is 1: @{ */
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_HF = 0b000,
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_F = 0b001,
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_DF = 0b010,
|
||||
/** @} */
|
||||
|
||||
/** When ExecutionDatatype is 0: @{ */
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_UD = 0b000,
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_D = 0b001,
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_UW = 0b010,
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_W = 0b011,
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_UB = 0b100,
|
||||
GFX10_ALIGN1_3SRC_REG_TYPE_B = 0b101,
|
||||
/** @} */
|
||||
};
|
||||
|
||||
static const struct hw_3src_type {
|
||||
enum hw_3src_reg_type reg_type;
|
||||
enum gfx10_align1_3src_exec_type exec_type;
|
||||
} gfx8_hw_3src_type[] = {
|
||||
[0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
|
||||
|
||||
[BRW_REGISTER_TYPE_F] = { GFX7_3SRC_TYPE_F },
|
||||
[BRW_REGISTER_TYPE_D] = { GFX7_3SRC_TYPE_D },
|
||||
[BRW_REGISTER_TYPE_UD] = { GFX7_3SRC_TYPE_UD },
|
||||
[BRW_REGISTER_TYPE_DF] = { GFX7_3SRC_TYPE_DF },
|
||||
[BRW_REGISTER_TYPE_HF] = { GFX8_3SRC_TYPE_HF },
|
||||
}, gfx11_hw_3src_type[] = {
|
||||
#define E(x) BRW_ALIGN1_3SRC_EXEC_TYPE_##x
|
||||
[0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
|
||||
|
||||
[BRW_REGISTER_TYPE_F] = { GFX10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) },
|
||||
[BRW_REGISTER_TYPE_HF] = { GFX10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) },
|
||||
|
||||
[BRW_REGISTER_TYPE_D] = { GFX10_ALIGN1_3SRC_REG_TYPE_D, E(INT) },
|
||||
[BRW_REGISTER_TYPE_UD] = { GFX10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) },
|
||||
[BRW_REGISTER_TYPE_W] = { GFX10_ALIGN1_3SRC_REG_TYPE_W, E(INT) },
|
||||
[BRW_REGISTER_TYPE_UW] = { GFX10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) },
|
||||
[BRW_REGISTER_TYPE_B] = { GFX10_ALIGN1_3SRC_REG_TYPE_B, E(INT) },
|
||||
[BRW_REGISTER_TYPE_UB] = { GFX10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) },
|
||||
}, gfx12_hw_3src_type[] = {
|
||||
[0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
|
||||
|
||||
[BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_UINT(2), E(FLOAT), },
|
||||
[BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_UINT(1), E(FLOAT), },
|
||||
|
||||
[BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), E(INT), },
|
||||
[BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), E(INT), },
|
||||
[BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), E(INT), },
|
||||
[BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), E(INT), },
|
||||
[BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), E(INT), },
|
||||
[BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), E(INT), },
|
||||
}, gfx125_hw_3src_type[] = {
|
||||
[0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
|
||||
|
||||
[BRW_REGISTER_TYPE_DF] = { GFX12_HW_REG_TYPE_UINT(3), E(FLOAT), },
|
||||
[BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_UINT(2), E(FLOAT), },
|
||||
[BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_UINT(1), E(FLOAT), },
|
||||
|
||||
[BRW_REGISTER_TYPE_Q] = { GFX12_HW_REG_TYPE_SINT(3), E(INT), },
|
||||
[BRW_REGISTER_TYPE_UQ] = { GFX12_HW_REG_TYPE_UINT(3), E(INT), },
|
||||
[BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), E(INT), },
|
||||
[BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), E(INT), },
|
||||
[BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), E(INT), },
|
||||
[BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), E(INT), },
|
||||
[BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), E(INT), },
|
||||
[BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), E(INT), },
|
||||
#undef E
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a brw_reg_type enumeration value into the hardware representation.
|
||||
*
|
||||
|
|
@ -254,28 +35,70 @@ brw_reg_type_to_hw_type(const struct intel_device_info *devinfo,
|
|||
enum brw_reg_file file,
|
||||
enum brw_reg_type type)
|
||||
{
|
||||
const struct hw_type *table;
|
||||
assert(file != IMM ||
|
||||
brw_type_is_vector_imm(type) ||
|
||||
brw_type_size_bits(type) >= 16);
|
||||
|
||||
if (devinfo->verx10 >= 125) {
|
||||
assert(type < ARRAY_SIZE(gfx125_hw_type));
|
||||
table = gfx125_hw_type;
|
||||
} else if (devinfo->ver >= 12) {
|
||||
assert(type < ARRAY_SIZE(gfx12_hw_type));
|
||||
table = gfx12_hw_type;
|
||||
if (type == BRW_TYPE_INVALID)
|
||||
return INVALID_HW_REG_TYPE;
|
||||
|
||||
if (brw_type_size_bits(type) == 64 &&
|
||||
!(brw_type_is_int(type) ? devinfo->has_64bit_int
|
||||
: devinfo->has_64bit_float))
|
||||
return INVALID_HW_REG_TYPE;
|
||||
|
||||
if (devinfo->ver >= 12) {
|
||||
if (brw_type_is_vector_imm(type))
|
||||
return type & ~(BRW_TYPE_VECTOR | BRW_TYPE_SIZE_MASK);
|
||||
|
||||
return type & (BRW_TYPE_BASE_MASK | BRW_TYPE_SIZE_MASK);
|
||||
} else if (devinfo->ver >= 11) {
|
||||
assert(type < ARRAY_SIZE(gfx11_hw_type));
|
||||
table = gfx11_hw_type;
|
||||
} else {
|
||||
assert(type < ARRAY_SIZE(gfx8_hw_type));
|
||||
table = gfx8_hw_type;
|
||||
}
|
||||
if (brw_type_is_vector_imm(type)) {
|
||||
if (type == BRW_TYPE_VF)
|
||||
return 11;
|
||||
/* UV/V is the same encoding as UB/B */
|
||||
type &= ~(BRW_TYPE_VECTOR | BRW_TYPE_SIZE_MASK);
|
||||
}
|
||||
|
||||
if (file == BRW_IMMEDIATE_VALUE) {
|
||||
assert(table[type].imm_type != (enum hw_imm_type)INVALID);
|
||||
return table[type].imm_type;
|
||||
if (brw_type_is_float(type)) {
|
||||
/* HF: 8, F: 9 */
|
||||
return 8 + (type & BRW_TYPE_SIZE_MASK) - 1;
|
||||
}
|
||||
|
||||
/* UB: 4, UW: 2, UD: 0
|
||||
* B: 5, W: 3, D: 1
|
||||
*/
|
||||
return 4 - 2 * (type & BRW_TYPE_SIZE_MASK) +
|
||||
(brw_type_is_sint(type) ? 1 : 0);
|
||||
} else {
|
||||
assert(table[type].reg_type != (enum hw_reg_type)INVALID);
|
||||
return table[type].reg_type;
|
||||
if (brw_type_is_vector_imm(type)) {
|
||||
return type == BRW_TYPE_UV ? 4 :
|
||||
type == BRW_TYPE_VF ? 5 :
|
||||
/* BRW_TYPE_V */ 6;
|
||||
} else if (brw_type_is_float(type)) {
|
||||
static const unsigned imm_tbl[] = {
|
||||
[0b00] = 5, /* VF */
|
||||
[0b01] = 11, /* HF */
|
||||
[0b10] = 7, /* F */
|
||||
[0b11] = 10, /* DF */
|
||||
};
|
||||
static const unsigned reg_tbl[] = {
|
||||
[0b01] = 10, /* HF */
|
||||
[0b10] = 7, /* F */
|
||||
[0b11] = 6, /* DF */
|
||||
};
|
||||
const unsigned *tbl = file == IMM ? imm_tbl : reg_tbl;
|
||||
return tbl[type & BRW_TYPE_SIZE_MASK];
|
||||
} else {
|
||||
static const unsigned tbl[] = {
|
||||
[0b00] = 4, /* UB/UV */
|
||||
[0b01] = 2, /* UW */
|
||||
[0b10] = 0, /* UD */
|
||||
[0b11] = 8, /* UQ */
|
||||
};
|
||||
return tbl[type & BRW_TYPE_SIZE_MASK] |
|
||||
(brw_type_is_sint(type) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -288,32 +111,78 @@ enum brw_reg_type
|
|||
brw_hw_type_to_reg_type(const struct intel_device_info *devinfo,
|
||||
enum brw_reg_file file, unsigned hw_type)
|
||||
{
|
||||
const struct hw_type *table;
|
||||
if (hw_type >= (1 << 4))
|
||||
return BRW_TYPE_INVALID;
|
||||
|
||||
if (devinfo->verx10 >= 125) {
|
||||
table = gfx125_hw_type;
|
||||
} else if (devinfo->ver >= 12) {
|
||||
table = gfx12_hw_type;
|
||||
if (devinfo->ver >= 12) {
|
||||
enum brw_reg_type t = (enum brw_reg_type) hw_type;
|
||||
if (brw_type_size_bits(t) == 8) {
|
||||
if (brw_type_is_float(t))
|
||||
return file == IMM ? BRW_TYPE_VF : BRW_TYPE_INVALID;
|
||||
else if (file == IMM)
|
||||
return (t & BRW_TYPE_BASE_SINT) ? BRW_TYPE_V : BRW_TYPE_UV;
|
||||
}
|
||||
/* signed-integer floats -> no */
|
||||
if ((t & BRW_TYPE_BASE_MASK) == BRW_TYPE_BASE_MASK)
|
||||
return BRW_TYPE_INVALID;
|
||||
return t;
|
||||
} else if (devinfo->ver >= 11) {
|
||||
table = gfx11_hw_type;
|
||||
static const enum brw_reg_type tbl[] = {
|
||||
[0] = BRW_TYPE_UD,
|
||||
[1] = BRW_TYPE_D,
|
||||
[2] = BRW_TYPE_UW,
|
||||
[3] = BRW_TYPE_W,
|
||||
[4] = BRW_TYPE_UB, /* or UV */
|
||||
[5] = BRW_TYPE_B, /* or V */
|
||||
[6] = BRW_TYPE_UQ,
|
||||
[7] = BRW_TYPE_Q,
|
||||
[8] = BRW_TYPE_HF,
|
||||
[9] = BRW_TYPE_F,
|
||||
[10] = BRW_TYPE_INVALID, /* no DF */
|
||||
[11] = BRW_TYPE_VF,
|
||||
[12 ... 15] = BRW_TYPE_INVALID,
|
||||
};
|
||||
enum brw_reg_type t = tbl[hw_type];
|
||||
if (file == IMM && brw_type_size_bits(t) == 8)
|
||||
return (t & BRW_TYPE_BASE_SINT) ? BRW_TYPE_V : BRW_TYPE_UV;
|
||||
if (file != IMM && brw_type_is_vector_imm(t))
|
||||
return BRW_TYPE_INVALID;
|
||||
return t;
|
||||
} else {
|
||||
table = gfx8_hw_type;
|
||||
static const enum brw_reg_type imm_tbl[] = {
|
||||
[0] = BRW_TYPE_UD,
|
||||
[1] = BRW_TYPE_D,
|
||||
[2] = BRW_TYPE_UW,
|
||||
[3] = BRW_TYPE_W,
|
||||
[4] = BRW_TYPE_UV,
|
||||
[5] = BRW_TYPE_VF,
|
||||
[6] = BRW_TYPE_V,
|
||||
[7] = BRW_TYPE_F,
|
||||
[8] = BRW_TYPE_UQ,
|
||||
[9] = BRW_TYPE_Q,
|
||||
[10] = BRW_TYPE_DF,
|
||||
[11] = BRW_TYPE_HF,
|
||||
[12 ... 15] = BRW_TYPE_INVALID,
|
||||
};
|
||||
static const enum brw_reg_type reg_tbl[] = {
|
||||
[0] = BRW_TYPE_UD,
|
||||
[1] = BRW_TYPE_D,
|
||||
[2] = BRW_TYPE_UW,
|
||||
[3] = BRW_TYPE_W,
|
||||
[4] = BRW_TYPE_UB,
|
||||
[5] = BRW_TYPE_B,
|
||||
[6] = BRW_TYPE_DF,
|
||||
[7] = BRW_TYPE_F,
|
||||
[8] = BRW_TYPE_UQ,
|
||||
[9] = BRW_TYPE_Q,
|
||||
[10] = BRW_TYPE_HF,
|
||||
[11 ... 15] = BRW_TYPE_INVALID,
|
||||
};
|
||||
const enum brw_reg_type *tbl = file == IMM ? imm_tbl : reg_tbl;
|
||||
return tbl[hw_type];
|
||||
}
|
||||
|
||||
if (file == BRW_IMMEDIATE_VALUE) {
|
||||
for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
|
||||
if (table[i].imm_type == (enum hw_imm_type)hw_type) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
|
||||
if (table[i].reg_type == (enum hw_reg_type)hw_type) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return INVALID_REG_TYPE;
|
||||
return BRW_TYPE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -324,11 +193,16 @@ unsigned
|
|||
brw_reg_type_to_a16_hw_3src_type(const struct intel_device_info *devinfo,
|
||||
enum brw_reg_type type)
|
||||
{
|
||||
assert(type < ARRAY_SIZE(gfx8_hw_3src_type));
|
||||
|
||||
const struct hw_3src_type *table = gfx8_hw_3src_type;
|
||||
assert(table[type].reg_type != (enum hw_3src_reg_type)INVALID);
|
||||
return table[type].reg_type;
|
||||
static const unsigned tbl[] = {
|
||||
[0 ... BRW_TYPE_LAST] = BRW_TYPE_INVALID,
|
||||
[BRW_TYPE_F] = 0,
|
||||
[BRW_TYPE_D] = 1,
|
||||
[BRW_TYPE_UD] = 2,
|
||||
[BRW_TYPE_DF] = 3,
|
||||
[BRW_TYPE_HF] = 4,
|
||||
};
|
||||
assert(type < ARRAY_SIZE(tbl));
|
||||
return tbl[type];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -339,16 +213,23 @@ unsigned
|
|||
brw_reg_type_to_a1_hw_3src_type(const struct intel_device_info *devinfo,
|
||||
enum brw_reg_type type)
|
||||
{
|
||||
if (devinfo->verx10 >= 125) {
|
||||
assert(type < ARRAY_SIZE(gfx125_hw_3src_type));
|
||||
return gfx125_hw_3src_type[type].reg_type;
|
||||
} else if (devinfo->ver >= 12) {
|
||||
assert(type < ARRAY_SIZE(gfx12_hw_3src_type));
|
||||
return gfx12_hw_3src_type[type].reg_type;
|
||||
} else {
|
||||
assert(type < ARRAY_SIZE(gfx11_hw_3src_type));
|
||||
return gfx11_hw_3src_type[type].reg_type;
|
||||
if (devinfo->ver >= 12) {
|
||||
/* size mask and SINT type bit match exactly */
|
||||
return type & 0b111;
|
||||
}
|
||||
|
||||
if (brw_type_is_float(type)) {
|
||||
/* HF: 0b000 | F: 0b001 | DF: 0b010; subtract 1 from our size mask */
|
||||
return (type & BRW_TYPE_SIZE_MASK) - 1;
|
||||
}
|
||||
|
||||
/* Bit 0 is the sign bit, bits 1-2 are our size mask reversed.
|
||||
* UD: 0b000 | D: 0b001
|
||||
* UW: 0b010 | W: 0b011
|
||||
* UB: 0b100 | B: 0b101
|
||||
*/
|
||||
return ((2 - (type & BRW_TYPE_SIZE_MASK)) << 1) |
|
||||
(brw_type_is_sint(type) ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -359,14 +240,14 @@ enum brw_reg_type
|
|||
brw_a16_hw_3src_type_to_reg_type(const struct intel_device_info *devinfo,
|
||||
unsigned hw_type)
|
||||
{
|
||||
const struct hw_3src_type *table = gfx8_hw_3src_type;
|
||||
|
||||
for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
|
||||
if (table[i].reg_type == hw_type) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return INVALID_REG_TYPE;
|
||||
static const enum brw_reg_type tbl[] = {
|
||||
[0] = BRW_TYPE_F,
|
||||
[1] = BRW_TYPE_D,
|
||||
[2] = BRW_TYPE_UD,
|
||||
[3] = BRW_TYPE_DF,
|
||||
[4] = BRW_TYPE_HF,
|
||||
};
|
||||
return hw_type < ARRAY_SIZE(tbl) ? tbl[hw_type] : BRW_TYPE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -377,18 +258,29 @@ enum brw_reg_type
|
|||
brw_a1_hw_3src_type_to_reg_type(const struct intel_device_info *devinfo,
|
||||
unsigned hw_type, unsigned exec_type)
|
||||
{
|
||||
const struct hw_3src_type *table =
|
||||
(devinfo->verx10 >= 125 ? gfx125_hw_3src_type :
|
||||
devinfo->ver >= 12 ? gfx12_hw_3src_type :
|
||||
gfx11_hw_3src_type);
|
||||
STATIC_ASSERT(BRW_ALIGN1_3SRC_EXEC_TYPE_INT == 0);
|
||||
STATIC_ASSERT(BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT == 1);
|
||||
assert(exec_type == 0 || exec_type == 1);
|
||||
|
||||
for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
|
||||
if (table[i].reg_type == hw_type &&
|
||||
table[i].exec_type == exec_type) {
|
||||
return i;
|
||||
if (devinfo->ver >= 12) {
|
||||
unsigned size_field = hw_type & BRW_TYPE_SIZE_MASK;
|
||||
unsigned base_field = hw_type & BRW_TYPE_BASE_MASK;
|
||||
if (exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT) {
|
||||
base_field |= BRW_TYPE_BASE_FLOAT;
|
||||
if (base_field & BRW_TYPE_BASE_SINT)
|
||||
return BRW_TYPE_INVALID;
|
||||
}
|
||||
return (enum brw_reg_type) (base_field | size_field);
|
||||
} else {
|
||||
if (exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT) {
|
||||
return hw_type > 1 ? BRW_TYPE_INVALID :
|
||||
hw_type ? BRW_TYPE_F : BRW_TYPE_HF;
|
||||
}
|
||||
|
||||
unsigned size_field = 2 >> (hw_type >> 1);
|
||||
unsigned base_field = (hw_type & 1) << 2;
|
||||
return (enum brw_reg_type) (base_field | size_field);
|
||||
}
|
||||
return INVALID_REG_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -397,27 +289,7 @@ brw_a1_hw_3src_type_to_reg_type(const struct intel_device_info *devinfo,
|
|||
unsigned
|
||||
brw_reg_type_to_size(enum brw_reg_type type)
|
||||
{
|
||||
static const unsigned type_size[] = {
|
||||
[BRW_REGISTER_TYPE_DF] = 8,
|
||||
[BRW_REGISTER_TYPE_F] = 4,
|
||||
[BRW_REGISTER_TYPE_HF] = 2,
|
||||
[BRW_REGISTER_TYPE_VF] = 4,
|
||||
|
||||
[BRW_REGISTER_TYPE_Q] = 8,
|
||||
[BRW_REGISTER_TYPE_UQ] = 8,
|
||||
[BRW_REGISTER_TYPE_D] = 4,
|
||||
[BRW_REGISTER_TYPE_UD] = 4,
|
||||
[BRW_REGISTER_TYPE_W] = 2,
|
||||
[BRW_REGISTER_TYPE_UW] = 2,
|
||||
[BRW_REGISTER_TYPE_B] = 1,
|
||||
[BRW_REGISTER_TYPE_UB] = 1,
|
||||
[BRW_REGISTER_TYPE_V] = 2,
|
||||
[BRW_REGISTER_TYPE_UV] = 2,
|
||||
};
|
||||
if (type >= ARRAY_SIZE(type_size))
|
||||
return -1;
|
||||
|
||||
return type_size[type];
|
||||
return brw_type_size_bytes(type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -430,25 +302,25 @@ const char *
|
|||
brw_reg_type_to_letters(enum brw_reg_type type)
|
||||
{
|
||||
static const char letters[][3] = {
|
||||
[BRW_REGISTER_TYPE_DF] = "DF",
|
||||
[BRW_REGISTER_TYPE_F] = "F",
|
||||
[BRW_REGISTER_TYPE_HF] = "HF",
|
||||
[BRW_REGISTER_TYPE_VF] = "VF",
|
||||
[BRW_TYPE_UB] = "UB",
|
||||
[BRW_TYPE_UW] = "UW",
|
||||
[BRW_TYPE_UD] = "UD",
|
||||
[BRW_TYPE_UQ] = "UQ",
|
||||
|
||||
[BRW_REGISTER_TYPE_Q] = "Q",
|
||||
[BRW_REGISTER_TYPE_UQ] = "UQ",
|
||||
[BRW_REGISTER_TYPE_D] = "D",
|
||||
[BRW_REGISTER_TYPE_UD] = "UD",
|
||||
[BRW_REGISTER_TYPE_W] = "W",
|
||||
[BRW_REGISTER_TYPE_UW] = "UW",
|
||||
[BRW_REGISTER_TYPE_B] = "B",
|
||||
[BRW_REGISTER_TYPE_UB] = "UB",
|
||||
[BRW_REGISTER_TYPE_V] = "V",
|
||||
[BRW_REGISTER_TYPE_UV] = "UV",
|
||||
[BRW_TYPE_B] = "B",
|
||||
[BRW_TYPE_W] = "W",
|
||||
[BRW_TYPE_D] = "D",
|
||||
[BRW_TYPE_Q] = "Q",
|
||||
|
||||
[BRW_TYPE_HF] = "HF",
|
||||
[BRW_TYPE_F] = "F",
|
||||
[BRW_TYPE_DF] = "DF",
|
||||
|
||||
[BRW_TYPE_UV] = "UV",
|
||||
[BRW_TYPE_V] = "V",
|
||||
[BRW_TYPE_VF] = "VF",
|
||||
};
|
||||
if (type >= ARRAY_SIZE(letters))
|
||||
return "INVALID";
|
||||
|
||||
assert(type < ARRAY_SIZE(letters));
|
||||
return letters[type];
|
||||
const char *l = type < ARRAY_SIZE(letters) ? letters[type] : NULL;
|
||||
return l ? l : "INVALID";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,72 +39,154 @@ extern "C" {
|
|||
enum brw_reg_file;
|
||||
struct intel_device_info;
|
||||
|
||||
/*
|
||||
* The ordering has been chosen so that no enum value is the same as a
|
||||
* compatible hardware encoding.
|
||||
/**
|
||||
* Enum for register/value types throughout the compiler.
|
||||
*
|
||||
* Bits 1:0 is the size of the type as a U2 'n' where size = 8 * 2^n.
|
||||
* Bit 3 is set for signed integer types (B/W/D/Q/V/UV).
|
||||
* Bit 4 is set for floating point types. Unsigned types have neither set.
|
||||
* Bit 5 is set for vector immediates.
|
||||
*
|
||||
* While this is inspired by the Tigerlake encodings (and nir_alu_type),
|
||||
* it doesn't match any particular hardware generation's encoding. In
|
||||
* particular, hardware encodings are 4-bit values while this is 5-bit
|
||||
* so that vector immediate types are distinguishable without considering
|
||||
* the register file (immediate or register). We also encode the size
|
||||
* of vector immediates in a way that makes type size calculations simple.
|
||||
*/
|
||||
enum PACKED brw_reg_type {
|
||||
/** Floating-point types: @{ */
|
||||
BRW_REGISTER_TYPE_DF, /* 64-bit float (double float) */
|
||||
BRW_REGISTER_TYPE_F, /* 32-bit float */
|
||||
BRW_REGISTER_TYPE_HF, /* 16-bit float (half float) */
|
||||
BRW_REGISTER_TYPE_VF, /* 32-bit vector of 4 8-bit floats */
|
||||
/* Unsigned integer types: 8, 16, 32, and 64-bit @{ */
|
||||
BRW_TYPE_UB = 0b00000,
|
||||
BRW_TYPE_UW = 0b00001,
|
||||
BRW_TYPE_UD = 0b00010,
|
||||
BRW_TYPE_UQ = 0b00011,
|
||||
/** @} */
|
||||
|
||||
/** Integer types: @{ */
|
||||
BRW_REGISTER_TYPE_Q, /* 64-bit signed integer (quad word) */
|
||||
BRW_REGISTER_TYPE_UQ, /* 64-bit unsigned integer (quad word) */
|
||||
BRW_REGISTER_TYPE_D, /* 32-bit signed integer (double word) */
|
||||
BRW_REGISTER_TYPE_UD, /* 32-bit unsigned integer (double word) */
|
||||
BRW_REGISTER_TYPE_W, /* 16-bit signed integer (word) */
|
||||
BRW_REGISTER_TYPE_UW, /* 16-bit unsigned integer (word) */
|
||||
BRW_REGISTER_TYPE_B, /* 8-bit signed integer (byte) */
|
||||
BRW_REGISTER_TYPE_UB, /* 8-bit unsigned integer (byte) */
|
||||
BRW_REGISTER_TYPE_V, /* vector of 8 signed 4-bit integers (treated as W) */
|
||||
BRW_REGISTER_TYPE_UV, /* vector of 8 unsigned 4-bit integers (treated as UW) */
|
||||
/* Signed integer types: 8, 16, 32, and 64-bit @{ */
|
||||
BRW_TYPE_B = 0b00100,
|
||||
BRW_TYPE_W = 0b00101,
|
||||
BRW_TYPE_D = 0b00110,
|
||||
BRW_TYPE_Q = 0b00111,
|
||||
/** @} */
|
||||
|
||||
BRW_REGISTER_TYPE_LAST = BRW_REGISTER_TYPE_UV
|
||||
/** Floating point types: 16 (half), 32, and 64-bit (double) @{ */
|
||||
BRW_TYPE_HF = 0b01001,
|
||||
BRW_TYPE_F = 0b01010,
|
||||
BRW_TYPE_DF = 0b01011,
|
||||
/** @} */
|
||||
|
||||
/** Vector immediate types */
|
||||
BRW_TYPE_UV = 0b10001,
|
||||
BRW_TYPE_V = 0b10101,
|
||||
BRW_TYPE_VF = 0b11010,
|
||||
/** @} */
|
||||
|
||||
BRW_TYPE_SIZE_MASK = 0b00011, /* type is (8 << x) bits */
|
||||
BRW_TYPE_BASE_MASK = 0b01100, /* base types expressed in these bits */
|
||||
BRW_TYPE_BASE_UINT = 0b00000, /* unsigned types have no base bits set */
|
||||
BRW_TYPE_BASE_SINT = 0b00100, /* type has a signed integer base type */
|
||||
BRW_TYPE_BASE_FLOAT = 0b01000, /* type has a floating point base type */
|
||||
BRW_TYPE_VECTOR = 0b10000, /* type is a vector immediate */
|
||||
|
||||
BRW_TYPE_INVALID = 0b11111,
|
||||
BRW_TYPE_LAST = BRW_TYPE_INVALID,
|
||||
|
||||
/** Backwards compatible long names: @{ */
|
||||
BRW_REGISTER_TYPE_B = BRW_TYPE_B,
|
||||
BRW_REGISTER_TYPE_W = BRW_TYPE_W,
|
||||
BRW_REGISTER_TYPE_D = BRW_TYPE_D,
|
||||
BRW_REGISTER_TYPE_Q = BRW_TYPE_Q,
|
||||
BRW_REGISTER_TYPE_V = BRW_TYPE_V,
|
||||
BRW_REGISTER_TYPE_UB = BRW_TYPE_UB,
|
||||
BRW_REGISTER_TYPE_UW = BRW_TYPE_UW,
|
||||
BRW_REGISTER_TYPE_UD = BRW_TYPE_UD,
|
||||
BRW_REGISTER_TYPE_UQ = BRW_TYPE_UQ,
|
||||
BRW_REGISTER_TYPE_UV = BRW_TYPE_UV,
|
||||
BRW_REGISTER_TYPE_HF = BRW_TYPE_HF,
|
||||
BRW_REGISTER_TYPE_F = BRW_TYPE_F,
|
||||
BRW_REGISTER_TYPE_DF = BRW_TYPE_DF,
|
||||
BRW_REGISTER_TYPE_VF = BRW_TYPE_VF,
|
||||
BRW_REGISTER_TYPE_LAST = BRW_TYPE_INVALID,
|
||||
/** *} */
|
||||
};
|
||||
|
||||
static inline bool
|
||||
brw_type_is_float(enum brw_reg_type t)
|
||||
{
|
||||
return (t & BRW_TYPE_BASE_MASK) == BRW_TYPE_BASE_FLOAT;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
brw_type_is_uint(enum brw_reg_type t)
|
||||
{
|
||||
return (t & BRW_TYPE_BASE_MASK) == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
brw_type_is_sint(enum brw_reg_type t)
|
||||
{
|
||||
return (t & BRW_TYPE_BASE_MASK) == BRW_TYPE_BASE_SINT;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
brw_type_is_int(enum brw_reg_type t)
|
||||
{
|
||||
return !brw_type_is_float(t);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
brw_type_is_vector_imm(enum brw_reg_type t)
|
||||
{
|
||||
return t & BRW_TYPE_VECTOR;
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
brw_type_size_bits(enum brw_reg_type t)
|
||||
{
|
||||
/* [U]V components are 4-bit, but HW unpacks them to 16-bit.
|
||||
* Similarly, VF is expanded to 32-bit.
|
||||
*/
|
||||
return 8 << (t & BRW_TYPE_SIZE_MASK);
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
brw_type_size_bytes(enum brw_reg_type t)
|
||||
{
|
||||
return brw_type_size_bits(t) / 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type based on a base type and a bit size.
|
||||
*/
|
||||
static inline enum brw_reg_type
|
||||
brw_type_with_size(enum brw_reg_type ref_type, unsigned bit_size)
|
||||
{
|
||||
assert(bit_size == 8 || bit_size == 16 ||
|
||||
bit_size == 32 || bit_size == 64);
|
||||
assert(brw_type_is_int(ref_type) || bit_size >= 16);
|
||||
unsigned base_field = ref_type & BRW_TYPE_BASE_MASK;
|
||||
unsigned size_field = ffs(bit_size) - 4;
|
||||
return (enum brw_reg_type)(base_field | size_field);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
|
||||
static inline bool
|
||||
brw_reg_type_is_floating_point(enum brw_reg_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case BRW_REGISTER_TYPE_DF:
|
||||
case BRW_REGISTER_TYPE_F:
|
||||
case BRW_REGISTER_TYPE_HF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return brw_type_is_float(type);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
brw_reg_type_is_integer(enum brw_reg_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case BRW_REGISTER_TYPE_Q:
|
||||
case BRW_REGISTER_TYPE_UQ:
|
||||
case BRW_REGISTER_TYPE_D:
|
||||
case BRW_REGISTER_TYPE_UD:
|
||||
case BRW_REGISTER_TYPE_W:
|
||||
case BRW_REGISTER_TYPE_UW:
|
||||
case BRW_REGISTER_TYPE_B:
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return brw_type_is_int(type);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
brw_reg_type_is_unsigned_integer(enum brw_reg_type tp)
|
||||
{
|
||||
return tp == BRW_REGISTER_TYPE_UB ||
|
||||
tp == BRW_REGISTER_TYPE_UW ||
|
||||
tp == BRW_REGISTER_TYPE_UD ||
|
||||
tp == BRW_REGISTER_TYPE_UQ;
|
||||
return brw_type_is_uint(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -115,61 +197,9 @@ static inline enum brw_reg_type
|
|||
brw_reg_type_from_bit_size(unsigned bit_size,
|
||||
enum brw_reg_type reference_type)
|
||||
{
|
||||
switch(reference_type) {
|
||||
case BRW_REGISTER_TYPE_HF:
|
||||
case BRW_REGISTER_TYPE_F:
|
||||
case BRW_REGISTER_TYPE_DF:
|
||||
switch(bit_size) {
|
||||
case 16:
|
||||
return BRW_REGISTER_TYPE_HF;
|
||||
case 32:
|
||||
return BRW_REGISTER_TYPE_F;
|
||||
case 64:
|
||||
return BRW_REGISTER_TYPE_DF;
|
||||
default:
|
||||
unreachable("Invalid bit size");
|
||||
}
|
||||
case BRW_REGISTER_TYPE_B:
|
||||
case BRW_REGISTER_TYPE_W:
|
||||
case BRW_REGISTER_TYPE_D:
|
||||
case BRW_REGISTER_TYPE_Q:
|
||||
switch(bit_size) {
|
||||
case 8:
|
||||
return BRW_REGISTER_TYPE_B;
|
||||
case 16:
|
||||
return BRW_REGISTER_TYPE_W;
|
||||
case 32:
|
||||
return BRW_REGISTER_TYPE_D;
|
||||
case 64:
|
||||
return BRW_REGISTER_TYPE_Q;
|
||||
default:
|
||||
unreachable("Invalid bit size");
|
||||
}
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
case BRW_REGISTER_TYPE_UW:
|
||||
case BRW_REGISTER_TYPE_UD:
|
||||
case BRW_REGISTER_TYPE_UQ:
|
||||
switch(bit_size) {
|
||||
case 8:
|
||||
return BRW_REGISTER_TYPE_UB;
|
||||
case 16:
|
||||
return BRW_REGISTER_TYPE_UW;
|
||||
case 32:
|
||||
return BRW_REGISTER_TYPE_UD;
|
||||
case 64:
|
||||
return BRW_REGISTER_TYPE_UQ;
|
||||
default:
|
||||
unreachable("Invalid bit size");
|
||||
}
|
||||
default:
|
||||
unreachable("Unknown type");
|
||||
}
|
||||
return brw_type_with_size(reference_type, bit_size);
|
||||
}
|
||||
|
||||
|
||||
#define INVALID_REG_TYPE ((enum brw_reg_type)-1)
|
||||
#define INVALID_HW_REG_TYPE ((unsigned)-1)
|
||||
|
||||
unsigned
|
||||
brw_reg_type_to_hw_type(const struct intel_device_info *devinfo,
|
||||
enum brw_reg_file file, enum brw_reg_type type);
|
||||
|
|
@ -200,6 +230,8 @@ brw_reg_type_to_size(enum brw_reg_type type);
|
|||
const char *
|
||||
brw_reg_type_to_letters(enum brw_reg_type type);
|
||||
|
||||
#define INVALID_HW_REG_TYPE 0b1111
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ fs_reg_saturate_immediate(fs_reg *reg)
|
|||
unreachable("unimplemented: saturate vector immediate");
|
||||
case BRW_REGISTER_TYPE_HF:
|
||||
unreachable("unimplemented: saturate HF immediate");
|
||||
default:
|
||||
unreachable("invalid type");
|
||||
}
|
||||
|
||||
if (size < 8) {
|
||||
|
|
@ -126,6 +128,8 @@ fs_reg_negate_immediate(fs_reg *reg)
|
|||
case BRW_REGISTER_TYPE_HF:
|
||||
reg->ud ^= 0x80008000;
|
||||
return true;
|
||||
default:
|
||||
unreachable("invalid type");
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -171,6 +175,8 @@ fs_reg_abs_immediate(fs_reg *reg)
|
|||
case BRW_REGISTER_TYPE_HF:
|
||||
reg->ud &= ~0x80008000;
|
||||
return true;
|
||||
default:
|
||||
unreachable("invalid type");
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ TEST_P(validation_test, invalid_type_encoding)
|
|||
for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) {
|
||||
if (test_case[i].expected_result) {
|
||||
unsigned hw_type = brw_reg_type_to_hw_type(&devinfo, file, test_case[i].type);
|
||||
if (hw_type != INVALID_REG_TYPE) {
|
||||
if (hw_type != INVALID_HW_REG_TYPE) {
|
||||
/* ... and remove valid encodings from the set */
|
||||
assert(BITSET_TEST(invalid_encodings, hw_type));
|
||||
BITSET_CLEAR(invalid_encodings, hw_type);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue