i965: Add align1 ternary instruction support to conversion functions
authorMatt Turner <mattst88@gmail.com>
Wed, 14 Jun 2017 21:49:31 +0000 (14:49 -0700)
committerMatt Turner <mattst88@gmail.com>
Fri, 20 Oct 2017 22:00:17 +0000 (15:00 -0700)
Reviewed-by: Scott D Phillips <scott.d.phillips@intel.com>
src/intel/compiler/brw_disasm.c
src/intel/compiler/brw_inst.h
src/intel/compiler/brw_reg_type.c
src/intel/compiler/brw_reg_type.h

index e91961028e7edd4d7c641b2c8fc6c095f601e008..ef7f623ceb0f9d02c4d05876b2807f9cea17d1fe 100644 (file)
@@ -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);
index 0cc1a3e911e081096e2870035b25f184915a6f89..1ddee77164022d8f73d78ec44fbf50768d21bd67 100644 (file)
@@ -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)
index f5aadf88bb77de32eda84ca0cf0153c7f1caa568..b7fff0867f49fffc39219154fc7c11a7e7d95a1c 100644 (file)
@@ -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;
       }
    }
index ed249d77e602855aa70ca4f4d59b265db7df5383..3bc9a36e7bf32c229cfe6499075b711a722f2992 100644 (file)
@@ -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);