i965/fs: Expose arbitrary pull constant load sizes to the IR.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_eu.c
index 102e4ca608859129201b1226342c40210a42af5b..6a422bb798b77409a86e18ae01c523e0a82d2131 100644 (file)
@@ -187,8 +187,6 @@ void
 brw_set_default_compression_control(struct brw_codegen *p,
                            enum brw_compression compression_control)
 {
-   p->compressed = (compression_control == BRW_COMPRESSION_COMPRESSED);
-
    if (p->devinfo->gen >= 6) {
       /* Since we don't use the SIMD32 support in gen6, we translate
        * the pre-gen6 compression control here.
@@ -218,6 +216,75 @@ brw_set_default_compression_control(struct brw_codegen *p,
    }
 }
 
+/**
+ * Enable or disable instruction compression on the given instruction leaving
+ * the currently selected channel enable group untouched.
+ */
+void
+brw_inst_set_compression(const struct gen_device_info *devinfo,
+                         brw_inst *inst, bool on)
+{
+   if (devinfo->gen >= 6) {
+      /* No-op, the EU will figure out for us whether the instruction needs to
+       * be compressed.
+       */
+   } else {
+      /* The channel group and compression controls are non-orthogonal, there
+       * are two possible representations for uncompressed instructions and we
+       * may need to preserve the current one to avoid changing the selected
+       * channel group inadvertently.
+       */
+      if (on)
+         brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_COMPRESSED);
+      else if (brw_inst_qtr_control(devinfo, inst)
+               == BRW_COMPRESSION_COMPRESSED)
+         brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_NONE);
+   }
+}
+
+void
+brw_set_default_compression(struct brw_codegen *p, bool on)
+{
+   brw_inst_set_compression(p->devinfo, p->current, on);
+}
+
+/**
+ * Apply the range of channel enable signals given by
+ * [group, group + exec_size) to the instruction passed as argument.
+ */
+void
+brw_inst_set_group(const struct gen_device_info *devinfo,
+                   brw_inst *inst, unsigned group)
+{
+   if (devinfo->gen >= 7) {
+      assert(group % 4 == 0 && group < 32);
+      brw_inst_set_qtr_control(devinfo, inst, group / 8);
+      brw_inst_set_nib_control(devinfo, inst, (group / 4) % 2);
+
+   } else if (devinfo->gen == 6) {
+      assert(group % 8 == 0 && group < 32);
+      brw_inst_set_qtr_control(devinfo, inst, group / 8);
+
+   } else {
+      assert(group % 8 == 0 && group < 16);
+      /* The channel group and compression controls are non-orthogonal, there
+       * are two possible representations for group zero and we may need to
+       * preserve the current one to avoid changing the selected compression
+       * enable inadvertently.
+       */
+      if (group == 8)
+         brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_2NDHALF);
+      else if (brw_inst_qtr_control(devinfo, inst) == BRW_COMPRESSION_2NDHALF)
+         brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_NONE);
+   }
+}
+
+void
+brw_set_default_group(struct brw_codegen *p, unsigned group)
+{
+   brw_inst_set_group(p->devinfo, p->current, group);
+}
+
 void brw_set_default_mask_control( struct brw_codegen *p, unsigned value )
 {
    brw_inst_set_mask_control(p->devinfo, p->current, value);
@@ -238,7 +305,6 @@ void brw_push_insn_state( struct brw_codegen *p )
 {
    assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
    memcpy(p->current + 1, p->current, sizeof(brw_inst));
-   p->compressed_stack[p->current - p->stack] = p->compressed;
    p->current++;
 }
 
@@ -246,14 +312,13 @@ void brw_pop_insn_state( struct brw_codegen *p )
 {
    assert(p->current != p->stack);
    p->current--;
-   p->compressed = p->compressed_stack[p->current - p->stack];
 }
 
 
 /***********************************************************************
  */
 void
-brw_init_codegen(const struct brw_device_info *devinfo,
+brw_init_codegen(const struct gen_device_info *devinfo,
                  struct brw_codegen *p, void *mem_ctx)
 {
    memset(p, 0, sizeof(*p));
@@ -268,7 +333,6 @@ brw_init_codegen(const struct brw_device_info *devinfo,
    p->store = rzalloc_array(mem_ctx, brw_inst, p->store_size);
    p->nr_insn = 0;
    p->current = p->stack;
-   p->compressed = false;
    memset(p->current, 0, sizeof(p->current[0]));
 
    p->mem_ctx = mem_ctx;
@@ -302,7 +366,7 @@ const unsigned *brw_get_program( struct brw_codegen *p,
 }
 
 void
-brw_disassemble(const struct brw_device_info *devinfo,
+brw_disassemble(const struct gen_device_info *devinfo,
                 void *assembly, int start, int end, FILE *out)
 {
    bool dump_hex = (INTEL_DEBUG & DEBUG_HEX) != 0;
@@ -352,10 +416,42 @@ enum gen {
    GEN_ALL = ~0
 };
 
-#define GEN_GE(gen) (~((gen) - 1) | gen)
-#define GEN_LE(gen) (((gen) - 1) | gen)
+#define GEN_LT(gen) ((gen) - 1)
+#define GEN_GE(gen) (~GEN_LT(gen))
+#define GEN_LE(gen) (GEN_LT(gen) | (gen))
+
+static const struct opcode_desc opcode_10_descs[] = {
+   { .name = "dim",   .nsrc = 1, .ndst = 1, .gens = GEN75 },
+   { .name = "smov",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN8) },
+};
+
+static const struct opcode_desc opcode_35_descs[] = {
+   { .name = "iff",   .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "brc",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN7) },
+};
+
+static const struct opcode_desc opcode_38_descs[] = {
+   { .name = "do",    .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "case",  .nsrc = 0, .ndst = 0, .gens = GEN6 },
+};
+
+static const struct opcode_desc opcode_44_descs[] = {
+   { .name = "msave", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "call",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN6) },
+};
+
+static const struct opcode_desc opcode_45_descs[] = {
+   { .name = "mrest", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "ret",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN6) },
+};
+
+static const struct opcode_desc opcode_46_descs[] = {
+   { .name = "push",  .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
+   { .name = "fork",  .nsrc = 0, .ndst = 0, .gens = GEN6 },
+   { .name = "goto",  .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN8) },
+};
 
-const struct opcode_desc opcode_descs[128] = {
+static const struct opcode_desc opcode_descs[128] = {
    [BRW_OPCODE_ILLEGAL] = {
       .name = "illegal", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
    },
@@ -386,7 +482,9 @@ const struct opcode_desc opcode_descs[128] = {
    [BRW_OPCODE_SHL] = {
       .name = "shl",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
    },
-   /* BRW_OPCODE_DIM / BRW_OPCODE_SMOV */
+   [10] = {
+      .table = opcode_10_descs, .size = ARRAY_SIZE(opcode_10_descs),
+   },
    /* Reserved - 11 */
    [BRW_OPCODE_ASR] = {
       .name = "asr",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
@@ -424,12 +522,14 @@ const struct opcode_desc opcode_descs[128] = {
    [BRW_OPCODE_JMPI] = {
       .name = "jmpi",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
    },
-   /* BRW_OPCODE_BRD */
+   [33] = {
+      .name = "brd",     .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN7),
+   },
    [BRW_OPCODE_IF] = {
       .name = "if",      .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
    },
-   [BRW_OPCODE_IFF] = { /* also BRW_OPCODE_BRC */
-      .name = "iff",     .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5),
+   [35] = {
+      .table = opcode_35_descs, .size = ARRAY_SIZE(opcode_35_descs),
    },
    [BRW_OPCODE_ELSE] = {
       .name = "else",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
@@ -437,8 +537,8 @@ const struct opcode_desc opcode_descs[128] = {
    [BRW_OPCODE_ENDIF] = {
       .name = "endif",   .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
    },
-   [BRW_OPCODE_DO] = { /* also BRW_OPCODE_CASE */
-      .name = "do",      .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5),
+   [38] = {
+      .table = opcode_38_descs, .size = ARRAY_SIZE(opcode_38_descs),
    },
    [BRW_OPCODE_WHILE] = {
       .name = "while",   .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
@@ -452,11 +552,21 @@ const struct opcode_desc opcode_descs[128] = {
    [BRW_OPCODE_HALT] = {
       .name = "halt",    .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
    },
-   /* BRW_OPCODE_CALLA */
-   /* BRW_OPCODE_MSAVE / BRW_OPCODE_CALL */
-   /* BRW_OPCODE_MREST / BRW_OPCODE_RET */
-   /* BRW_OPCODE_PUSH / BRW_OPCODE_FORK / BRW_OPCODE_GOTO */
-   /* BRW_OPCODE_POP */
+   [43] = {
+      .name = "calla",   .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN75),
+   },
+   [44] = {
+      .table = opcode_44_descs, .size = ARRAY_SIZE(opcode_44_descs),
+   },
+   [45] = {
+      .table = opcode_45_descs, .size = ARRAY_SIZE(opcode_45_descs),
+   },
+   [46] = {
+      .table = opcode_46_descs, .size = ARRAY_SIZE(opcode_46_descs),
+   },
+   [47] = {
+      .name = "pop",     .nsrc = 2, .ndst = 0, .gens = GEN_LE(GEN5),
+   },
    [BRW_OPCODE_WAIT] = {
       .name = "wait",    .nsrc = 1, .ndst = 0, .gens = GEN_ALL,
    },
@@ -557,7 +667,10 @@ const struct opcode_desc opcode_descs[128] = {
    [BRW_OPCODE_LRP] = {
       .name = "lrp",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6),
    },
-   /* Reserved 93-124 */
+   [93] = {
+      .name = "madm",    .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN8),
+   },
+   /* Reserved 94-124 */
    [BRW_OPCODE_NENOP] = {
       .name = "nenop",   .nsrc = 0, .ndst = 0, .gens = GEN45,
    },
@@ -566,8 +679,8 @@ const struct opcode_desc opcode_descs[128] = {
    },
 };
 
-int
-gen_from_devinfo(const struct brw_device_info *devinfo)
+static enum gen
+gen_from_devinfo(const struct gen_device_info *devinfo)
 {
    switch (devinfo->gen) {
    case 4: return devinfo->is_g4x ? GEN45 : GEN4;
@@ -583,16 +696,25 @@ gen_from_devinfo(const struct brw_device_info *devinfo)
 
 /* Return the matching opcode_desc for the specified opcode number and
  * hardware generation, or NULL if the opcode is not supported by the device.
- * XXX -- Actually check whether the opcode is supported.
  */
 const struct opcode_desc *
-brw_opcode_desc(const struct brw_device_info *devinfo, enum opcode opcode)
+brw_opcode_desc(const struct gen_device_info *devinfo, enum opcode opcode)
 {
    if (opcode >= ARRAY_SIZE(opcode_descs))
       return NULL;
 
-   if (opcode_descs[opcode].name)
-      return &opcode_descs[opcode];
-   else
-      return NULL;
+   enum gen gen = gen_from_devinfo(devinfo);
+   if (opcode_descs[opcode].gens != 0) {
+      if ((opcode_descs[opcode].gens & gen) != 0) {
+         return &opcode_descs[opcode];
+      }
+   } else if (opcode_descs[opcode].table != NULL) {
+      const struct opcode_desc *table = opcode_descs[opcode].table;
+      for (unsigned i = 0; i < opcode_descs[opcode].size; i++) {
+         if ((table[i].gens & gen) != 0) {
+            return &table[i];
+         }
+      }
+   }
+   return NULL;
 }