intel/compiler: Add Gen11+ native float type
authorMatt Turner <mattst88@gmail.com>
Wed, 14 Jun 2017 18:03:19 +0000 (11:03 -0700)
committerMatt Turner <mattst88@gmail.com>
Wed, 28 Feb 2018 19:15:47 +0000 (11:15 -0800)
This new type exposes the additional precision offered by the
accumulator register and will be used in the next patch to implement the
functionality of the PLN instruction using a pair of MAD instructions.

One weird thing to note: align1 ternary instructions may only have an
accumulator in the dst or src1 normally, but when src0's type is :NF
the accumulator is read.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/intel/compiler/brw_disasm.c
src/intel/compiler/brw_eu_emit.c
src/intel/compiler/brw_eu_validate.c
src/intel/compiler/brw_reg_type.c
src/intel/compiler/brw_reg_type.h
src/intel/compiler/brw_shader.cpp

index 429ed78140440a8de4d0cbc77d35625f70f8a215..a9a108f8acd1b9df569c4ee33c2f5f78ba0b261a 100644 (file)
@@ -1035,6 +1035,12 @@ src0_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *ins
          reg_nr = brw_inst_3src_src0_reg_nr(devinfo, inst);
          subreg_nr = brw_inst_3src_a1_src0_subreg_nr(devinfo, inst);
          type = brw_inst_3src_a1_src0_type(devinfo, inst);
+      } else if (brw_inst_3src_a1_src0_type(devinfo, inst) ==
+                 BRW_REGISTER_TYPE_NF) {
+         _file = BRW_ARCHITECTURE_REGISTER_FILE;
+         reg_nr = brw_inst_3src_src0_reg_nr(devinfo, inst);
+         subreg_nr = brw_inst_3src_a1_src0_subreg_nr(devinfo, inst);
+         type = brw_inst_3src_a1_src0_type(devinfo, inst);
       } else {
          _file = BRW_IMMEDIATE_VALUE;
          uint16_t imm_val = brw_inst_3src_a1_src0_imm(devinfo, inst);
@@ -1288,6 +1294,7 @@ imm(FILE *file, const struct gen_device_info *devinfo, enum brw_reg_type type,
    case BRW_REGISTER_TYPE_HF:
       string(file, "Half Float IMM");
       break;
+   case BRW_REGISTER_TYPE_NF:
    case BRW_REGISTER_TYPE_UB:
    case BRW_REGISTER_TYPE_B:
       format(file, "*** invalid immediate type %d ", type);
index c25d8d6eda09455eb031bbb3754c17ac12891c1e..ec871e5aa75f80c07db214e43c92e184d031cd57 100644 (file)
@@ -771,7 +771,11 @@ brw_alu3(struct brw_codegen *p, unsigned opcode, struct brw_reg dest,
                                         to_3src_align1_hstride(src2.hstride));
 
       brw_inst_set_3src_a1_src0_subreg_nr(devinfo, inst, src0.subnr);
-      brw_inst_set_3src_src0_reg_nr(devinfo, inst, src0.nr);
+      if (src0.type == BRW_REGISTER_TYPE_NF) {
+         brw_inst_set_3src_src0_reg_nr(devinfo, inst, BRW_ARF_ACCUMULATOR);
+      } else {
+         brw_inst_set_3src_src0_reg_nr(devinfo, inst, src0.nr);
+      }
       brw_inst_set_3src_src0_abs(devinfo, inst, src0.abs);
       brw_inst_set_3src_src0_negate(devinfo, inst, src0.negate);
 
@@ -790,7 +794,9 @@ brw_alu3(struct brw_codegen *p, unsigned opcode, struct brw_reg dest,
       brw_inst_set_3src_src2_negate(devinfo, inst, src2.negate);
 
       assert(src0.file == BRW_GENERAL_REGISTER_FILE ||
-             src0.file == BRW_IMMEDIATE_VALUE);
+             src0.file == BRW_IMMEDIATE_VALUE ||
+             (src0.file == BRW_ARCHITECTURE_REGISTER_FILE &&
+              src0.type == BRW_REGISTER_TYPE_NF));
       assert(src1.file == BRW_GENERAL_REGISTER_FILE ||
              src1.file == BRW_ARCHITECTURE_REGISTER_FILE);
       assert(src2.file == BRW_GENERAL_REGISTER_FILE ||
index 6ee6b4ffbe74f33f10efa5b2ed1f41c47dc319af..d3189d1ef5e390c2a42cb03762439abd7527981a 100644 (file)
@@ -277,6 +277,7 @@ static enum brw_reg_type
 execution_type_for_type(enum brw_reg_type type)
 {
    switch (type) {
+   case BRW_REGISTER_TYPE_NF:
    case BRW_REGISTER_TYPE_DF:
    case BRW_REGISTER_TYPE_F:
    case BRW_REGISTER_TYPE_HF:
index c4f8eedeb4bc4b74dba2108d6ecab42555680709..3c82eb0a76fd0a73b5e70271b15da02d5bdab468 100644 (file)
@@ -52,6 +52,7 @@ enum hw_reg_type {
    GEN11_HW_REG_TYPE_HF = 8,
    GEN11_HW_REG_TYPE_F  = 9,
    GEN11_HW_REG_TYPE_DF = 10,
+   GEN11_HW_REG_TYPE_NF = 11,
 };
 
 enum hw_imm_type {
@@ -87,6 +88,8 @@ static const struct hw_type {
    enum hw_reg_type reg_type;
    enum hw_imm_type imm_type;
 } gen4_hw_type[] = {
+   [0 ... BRW_REGISTER_TYPE_LAST] = {     INVALID, INVALID             },
+
    [BRW_REGISTER_TYPE_DF] = { GEN7_HW_REG_TYPE_DF, GEN8_HW_IMM_TYPE_DF },
    [BRW_REGISTER_TYPE_F]  = { BRW_HW_REG_TYPE_F,   BRW_HW_IMM_TYPE_F   },
    [BRW_REGISTER_TYPE_HF] = { GEN8_HW_REG_TYPE_HF, GEN8_HW_IMM_TYPE_HF },
@@ -103,6 +106,7 @@ static const struct hw_type {
    [BRW_REGISTER_TYPE_V]  = { INVALID,             BRW_HW_IMM_TYPE_V   },
    [BRW_REGISTER_TYPE_UV] = { INVALID,             BRW_HW_IMM_TYPE_UV  },
 }, gen11_hw_type[] = {
+   [BRW_REGISTER_TYPE_NF] = { GEN11_HW_REG_TYPE_NF, INVALID              },
    [BRW_REGISTER_TYPE_DF] = { GEN11_HW_REG_TYPE_DF, GEN11_HW_IMM_TYPE_DF },
    [BRW_REGISTER_TYPE_F]  = { GEN11_HW_REG_TYPE_F,  GEN11_HW_IMM_TYPE_F  },
    [BRW_REGISTER_TYPE_HF] = { GEN11_HW_REG_TYPE_HF, GEN11_HW_IMM_TYPE_HF },
@@ -139,6 +143,7 @@ enum hw_3src_reg_type {
    GEN10_ALIGN1_3SRC_REG_TYPE_HF = 0b000,
    GEN10_ALIGN1_3SRC_REG_TYPE_F  = 0b001,
    GEN10_ALIGN1_3SRC_REG_TYPE_DF = 0b010,
+   GEN11_ALIGN1_3SRC_REG_TYPE_NF = 0b011,
    /** @} */
 
    /** When ExecutionDatatype is 0: @{ */
@@ -165,6 +170,7 @@ static const struct hw_3src_type {
 #define E(x) BRW_ALIGN1_3SRC_EXEC_TYPE_##x
    [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
 
+   [BRW_REGISTER_TYPE_NF] = { GEN11_ALIGN1_3SRC_REG_TYPE_NF, E(FLOAT) },
    [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) },
@@ -306,6 +312,7 @@ unsigned
 brw_reg_type_to_size(enum brw_reg_type type)
 {
    static const unsigned type_size[] = {
+      [BRW_REGISTER_TYPE_NF] = 8,
       [BRW_REGISTER_TYPE_DF] = 8,
       [BRW_REGISTER_TYPE_F]  = 4,
       [BRW_REGISTER_TYPE_HF] = 2,
@@ -335,6 +342,7 @@ const char *
 brw_reg_type_to_letters(enum brw_reg_type type)
 {
    static const char letters[][3] = {
+      [BRW_REGISTER_TYPE_NF] = "NF",
       [BRW_REGISTER_TYPE_DF] = "DF",
       [BRW_REGISTER_TYPE_F]  = "F",
       [BRW_REGISTER_TYPE_HF] = "HF",
index 3bc9a36e7bf32c229cfe6499075b711a722f2992..ffbec90d3fe4ab57d0975a63bd8ec134f6b39405 100644 (file)
@@ -45,6 +45,7 @@ struct gen_device_info;
  */
 enum PACKED brw_reg_type {
    /** Floating-point types: @{ */
+   BRW_REGISTER_TYPE_NF,
    BRW_REGISTER_TYPE_DF,
    BRW_REGISTER_TYPE_F,
    BRW_REGISTER_TYPE_HF,
@@ -71,6 +72,7 @@ static inline bool
 brw_reg_type_is_floating_point(enum brw_reg_type type)
 {
    switch (type) {
+   case BRW_REGISTER_TYPE_NF:
    case BRW_REGISTER_TYPE_DF:
    case BRW_REGISTER_TYPE_F:
    case BRW_REGISTER_TYPE_HF:
index 1df4f35cd8e4d492df0f9af929a425873e8ec8be..0e713819d9497088d5475aff23d1c743b810e2f7 100644 (file)
@@ -541,6 +541,8 @@ brw_saturate_immediate(enum brw_reg_type type, struct brw_reg *reg)
       unreachable("unimplemented: saturate vector immediate");
    case BRW_REGISTER_TYPE_HF:
       unreachable("unimplemented: saturate HF immediate");
+   case BRW_REGISTER_TYPE_NF:
+      unreachable("no NF immediates");
    }
 
    if (size < 8) {
@@ -590,6 +592,8 @@ brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg)
       assert(!"unimplemented: negate UV/V immediate");
    case BRW_REGISTER_TYPE_HF:
       assert(!"unimplemented: negate HF immediate");
+   case BRW_REGISTER_TYPE_NF:
+      unreachable("no NF immediates");
    }
 
    return false;
@@ -632,6 +636,8 @@ brw_abs_immediate(enum brw_reg_type type, struct brw_reg *reg)
       assert(!"unimplemented: abs V immediate");
    case BRW_REGISTER_TYPE_HF:
       assert(!"unimplemented: abs HF immediate");
+   case BRW_REGISTER_TYPE_NF:
+      unreachable("no NF immediates");
    }
 
    return false;