From 3b2c868848c12ea772ac818c0833850a2940eb7e Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Wed, 14 Jun 2017 14:49:31 -0700 Subject: [PATCH] i965: Add align1 ternary instruction support to conversion functions Reviewed-by: Scott D Phillips --- src/intel/compiler/brw_disasm.c | 16 ++--- src/intel/compiler/brw_inst.h | 4 +- src/intel/compiler/brw_reg_type.c | 99 ++++++++++++++++++++++++++----- src/intel/compiler/brw_reg_type.h | 16 +++-- 4 files changed, 101 insertions(+), 34 deletions(-) diff --git a/src/intel/compiler/brw_disasm.c b/src/intel/compiler/brw_disasm.c index e91961028e7..ef7f623ceb0 100644 --- a/src/intel/compiler/brw_disasm.c +++ b/src/intel/compiler/brw_disasm.c @@ -764,9 +764,7 @@ dest_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *ins { int err = 0; uint32_t reg_file; - enum brw_reg_type type = - brw_hw_3src_type_to_reg_type(devinfo, - brw_inst_3src_a16_dst_hw_type(devinfo, inst)); + enum brw_reg_type type = brw_inst_3src_a16_dst_type(devinfo, inst); unsigned dst_subreg_nr = brw_inst_3src_a16_dst_subreg_nr(devinfo, inst) * 4 / brw_reg_type_to_size(type); @@ -934,9 +932,7 @@ static int src0_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst) { int err = 0; - enum brw_reg_type type = - brw_hw_3src_type_to_reg_type(devinfo, - brw_inst_3src_a16_src_hw_type(devinfo, inst)); + enum brw_reg_type type = brw_inst_3src_a16_src_type(devinfo, inst); unsigned src0_subreg_nr = brw_inst_3src_a16_src0_subreg_nr(devinfo, inst) * 4 / brw_reg_type_to_size(type); @@ -966,9 +962,7 @@ static int src1_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst) { int err = 0; - enum brw_reg_type type = - brw_hw_3src_type_to_reg_type(devinfo, - brw_inst_3src_a16_src_hw_type(devinfo, inst)); + enum brw_reg_type type = brw_inst_3src_a16_src_type(devinfo, inst); unsigned src1_subreg_nr = brw_inst_3src_a16_src1_subreg_nr(devinfo, inst) * 4 / brw_reg_type_to_size(type); @@ -999,9 +993,7 @@ static int src2_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst) { int err = 0; - enum brw_reg_type type = - brw_hw_3src_type_to_reg_type(devinfo, - brw_inst_3src_a16_src_hw_type(devinfo, inst)); + enum brw_reg_type type = brw_inst_3src_a16_src_type(devinfo, inst); unsigned src2_subreg_nr = brw_inst_3src_a16_src2_subreg_nr(devinfo, inst) * 4 / brw_reg_type_to_size(type); diff --git a/src/intel/compiler/brw_inst.h b/src/intel/compiler/brw_inst.h index 0cc1a3e911e..1ddee771640 100644 --- a/src/intel/compiler/brw_inst.h +++ b/src/intel/compiler/brw_inst.h @@ -251,7 +251,7 @@ static inline void \ brw_inst_set_3src_a16_##reg##_type(const struct gen_device_info *devinfo, \ brw_inst *inst, enum brw_reg_type type) \ { \ - unsigned hw_type = brw_reg_type_to_hw_3src_type(devinfo, type); \ + unsigned hw_type = brw_reg_type_to_a16_hw_3src_type(devinfo, type); \ brw_inst_set_3src_a16_##reg##_hw_type(devinfo, inst, hw_type); \ } \ \ @@ -260,7 +260,7 @@ brw_inst_3src_a16_##reg##_type(const struct gen_device_info *devinfo, \ const brw_inst *inst) \ { \ unsigned hw_type = brw_inst_3src_a16_##reg##_hw_type(devinfo, inst); \ - return brw_hw_3src_type_to_reg_type(devinfo, hw_type); \ + return brw_a16_hw_3src_type_to_reg_type(devinfo, hw_type); \ } REG_TYPE(dst) diff --git a/src/intel/compiler/brw_reg_type.c b/src/intel/compiler/brw_reg_type.c index f5aadf88bb7..b7fff0867f4 100644 --- a/src/intel/compiler/brw_reg_type.c +++ b/src/intel/compiler/brw_reg_type.c @@ -84,20 +84,57 @@ static const struct { * 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 { GEN7_3SRC_TYPE_F = 0, GEN7_3SRC_TYPE_D = 1, GEN7_3SRC_TYPE_UD = 2, GEN7_3SRC_TYPE_DF = 3, + + /** When ExecutionDatatype is 1: @{ */ + GEN10_ALIGN1_3SRC_REG_TYPE_HF = 0b000, + GEN10_ALIGN1_3SRC_REG_TYPE_F = 0b001, + GEN10_ALIGN1_3SRC_REG_TYPE_DF = 0b010, + /** @} */ + + /** When ExecutionDatatype is 0: @{ */ + GEN10_ALIGN1_3SRC_REG_TYPE_UD = 0b000, + GEN10_ALIGN1_3SRC_REG_TYPE_D = 0b001, + GEN10_ALIGN1_3SRC_REG_TYPE_UW = 0b010, + GEN10_ALIGN1_3SRC_REG_TYPE_W = 0b011, + GEN10_ALIGN1_3SRC_REG_TYPE_UB = 0b100, + GEN10_ALIGN1_3SRC_REG_TYPE_B = 0b101, + /** @} */ }; -static const enum hw_3src_reg_type gen7_3src_type[] = { - [0 ... BRW_REGISTER_TYPE_LAST] = INVALID, - [BRW_REGISTER_TYPE_F] = GEN7_3SRC_TYPE_F, - [BRW_REGISTER_TYPE_D] = GEN7_3SRC_TYPE_D, - [BRW_REGISTER_TYPE_UD] = GEN7_3SRC_TYPE_UD, - [BRW_REGISTER_TYPE_DF] = GEN7_3SRC_TYPE_DF, +static const struct hw_3src_type { + enum hw_3src_reg_type reg_type; + enum gen10_align1_3src_exec_type exec_type; +} gen7_hw_3src_type[] = { + [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, + + [BRW_REGISTER_TYPE_F] = { GEN7_3SRC_TYPE_F }, + [BRW_REGISTER_TYPE_D] = { GEN7_3SRC_TYPE_D }, + [BRW_REGISTER_TYPE_UD] = { GEN7_3SRC_TYPE_UD }, + [BRW_REGISTER_TYPE_DF] = { GEN7_3SRC_TYPE_DF }, +}, gen10_hw_3src_align1_type[] = { +#define E(x) BRW_ALIGN1_3SRC_EXEC_TYPE_##x + [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, + + [BRW_REGISTER_TYPE_DF] = { GEN10_ALIGN1_3SRC_REG_TYPE_DF, E(FLOAT) }, + [BRW_REGISTER_TYPE_F] = { GEN10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) }, + [BRW_REGISTER_TYPE_HF] = { GEN10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) }, + + [BRW_REGISTER_TYPE_D] = { GEN10_ALIGN1_3SRC_REG_TYPE_D, E(INT) }, + [BRW_REGISTER_TYPE_UD] = { GEN10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) }, + [BRW_REGISTER_TYPE_W] = { GEN10_ALIGN1_3SRC_REG_TYPE_W, E(INT) }, + [BRW_REGISTER_TYPE_UW] = { GEN10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) }, + [BRW_REGISTER_TYPE_B] = { GEN10_ALIGN1_3SRC_REG_TYPE_B, E(INT) }, + [BRW_REGISTER_TYPE_UB] = { GEN10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) }, +#undef E }; /** @@ -148,27 +185,57 @@ brw_hw_type_to_reg_type(const struct gen_device_info *devinfo, /** * Convert a brw_reg_type enumeration value into the hardware representation - * for a 3-src instruction + * for a 3-src align16 instruction + */ +unsigned +brw_reg_type_to_a16_hw_3src_type(const struct gen_device_info *devinfo, + enum brw_reg_type type) +{ + assert(type < ARRAY_SIZE(gen7_hw_3src_type)); + assert(gen7_hw_3src_type[type].reg_type != (enum hw_3src_reg_type)INVALID); + return gen7_hw_3src_type[type].reg_type; +} + +/** + * Convert a brw_reg_type enumeration value into the hardware representation + * for a 3-src align1 instruction */ unsigned -brw_reg_type_to_hw_3src_type(const struct gen_device_info *devinfo, - enum brw_reg_type type) +brw_reg_type_to_a1_hw_3src_type(const struct gen_device_info *devinfo, + enum brw_reg_type type) { - assert(type < ARRAY_SIZE(gen7_3src_type)); - assert(gen7_3src_type[type] != -1); - return gen7_3src_type[type]; + assert(type < ARRAY_SIZE(gen10_hw_3src_align1_type)); + assert(gen10_hw_3src_align1_type[type].reg_type != (enum hw_3src_reg_type)INVALID); + return gen10_hw_3src_align1_type[type].reg_type; +} + +/** + * Convert the hardware representation for a 3-src align16 instruction into a + * brw_reg_type enumeration value. + */ +enum brw_reg_type +brw_a16_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo, + unsigned hw_type) +{ + for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) { + if (gen7_hw_3src_type[i].reg_type == hw_type) { + return i; + } + } + unreachable("not reached"); } /** - * Convert the hardware representation for a 3-src instruction into a + * Convert the hardware representation for a 3-src align1 instruction into a * brw_reg_type enumeration value. */ enum brw_reg_type -brw_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo, - unsigned hw_type) +brw_a1_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo, + unsigned hw_type, unsigned exec_type) { for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) { - if (gen7_3src_type[i] == hw_type) { + if (gen10_hw_3src_align1_type[i].reg_type == hw_type && + gen10_hw_3src_align1_type[i].exec_type == exec_type) { return i; } } diff --git a/src/intel/compiler/brw_reg_type.h b/src/intel/compiler/brw_reg_type.h index ed249d77e60..3bc9a36e7bf 100644 --- a/src/intel/compiler/brw_reg_type.h +++ b/src/intel/compiler/brw_reg_type.h @@ -89,12 +89,20 @@ brw_hw_type_to_reg_type(const struct gen_device_info *devinfo, enum brw_reg_file file, unsigned hw_type); unsigned -brw_reg_type_to_hw_3src_type(const struct gen_device_info *devinfo, - enum brw_reg_type type); +brw_reg_type_to_a16_hw_3src_type(const struct gen_device_info *devinfo, + enum brw_reg_type type); + +unsigned +brw_reg_type_to_a1_hw_3src_type(const struct gen_device_info *devinfo, + enum brw_reg_type type); + +enum brw_reg_type +brw_a16_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo, + unsigned hw_type); enum brw_reg_type -brw_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo, - unsigned hw_type); +brw_a1_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo, + unsigned hw_type, unsigned exec_type); unsigned brw_reg_type_to_size(enum brw_reg_type type); -- 2.30.2