intel/eu: Split brw_inst ex_desc accessors for SEND(C) vs. SENDS(C).
[mesa.git] / src / intel / compiler / brw_eu.c
index 77400c19914a74b0db719b5ce1597e939cac7182..db08999c7ee759bac29ab4df6f0dc01d41a4133b 100644 (file)
   *   Keith Whitwell <keithw@vmware.com>
   */
 
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include "brw_eu_defines.h"
 #include "brw_eu.h"
 #include "brw_shader.h"
-#include "common/gen_debug.h"
+#include "dev/gen_debug.h"
 
 #include "util/ralloc.h"
 
-/**
- * Converts a BRW_REGISTER_TYPE_* enum to a short string (F, UD, and so on).
- *
- * This is different than reg_encoding from brw_disasm.c in that it operates
- * on the abstract enum values, rather than the generation-specific encoding.
- */
-const char *
-brw_reg_type_letters(unsigned type)
-{
-   const char *names[] = {
-      [BRW_REGISTER_TYPE_UD] = "UD",
-      [BRW_REGISTER_TYPE_D]  = "D",
-      [BRW_REGISTER_TYPE_UW] = "UW",
-      [BRW_REGISTER_TYPE_W]  = "W",
-      [BRW_REGISTER_TYPE_F]  = "F",
-      [BRW_REGISTER_TYPE_UB] = "UB",
-      [BRW_REGISTER_TYPE_B]  = "B",
-      [BRW_REGISTER_TYPE_UV] = "UV",
-      [BRW_REGISTER_TYPE_V]  = "V",
-      [BRW_REGISTER_TYPE_VF] = "VF",
-      [BRW_REGISTER_TYPE_DF] = "DF",
-      [BRW_REGISTER_TYPE_HF] = "HF",
-      [BRW_REGISTER_TYPE_UQ] = "UQ",
-      [BRW_REGISTER_TYPE_Q]  = "Q",
-   };
-   assert(type <= BRW_REGISTER_TYPE_Q);
-   return names[type];
-}
-
 /* Returns a conditional modifier that negates the condition. */
 enum brw_conditional_mod
 brw_negate_cmod(uint32_t cmod)
@@ -155,65 +128,79 @@ brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz)
    }
 }
 
+unsigned
+brw_get_default_exec_size(struct brw_codegen *p)
+{
+   return p->current->exec_size;
+}
+
+unsigned
+brw_get_default_group(struct brw_codegen *p)
+{
+   return p->current->group;
+}
+
+unsigned
+brw_get_default_access_mode(struct brw_codegen *p)
+{
+   return p->current->access_mode;
+}
+
 void
 brw_set_default_exec_size(struct brw_codegen *p, unsigned value)
 {
-   brw_inst_set_exec_size(p->devinfo, p->current, value);
+   p->current->exec_size = value;
 }
 
 void brw_set_default_predicate_control( struct brw_codegen *p, unsigned pc )
 {
-   brw_inst_set_pred_control(p->devinfo, p->current, pc);
+   p->current->predicate = pc;
 }
 
 void brw_set_default_predicate_inverse(struct brw_codegen *p, bool predicate_inverse)
 {
-   brw_inst_set_pred_inv(p->devinfo, p->current, predicate_inverse);
+   p->current->pred_inv = predicate_inverse;
 }
 
 void brw_set_default_flag_reg(struct brw_codegen *p, int reg, int subreg)
 {
-   if (p->devinfo->gen >= 7)
-      brw_inst_set_flag_reg_nr(p->devinfo, p->current, reg);
-
-   brw_inst_set_flag_subreg_nr(p->devinfo, p->current, subreg);
+   assert(subreg < 2);
+   p->current->flag_subreg = reg * 2 + subreg;
 }
 
 void brw_set_default_access_mode( struct brw_codegen *p, unsigned access_mode )
 {
-   brw_inst_set_access_mode(p->devinfo, p->current, access_mode);
+   p->current->access_mode = access_mode;
 }
 
 void
 brw_set_default_compression_control(struct brw_codegen *p,
                            enum brw_compression compression_control)
 {
-   if (p->devinfo->gen >= 6) {
-      /* Since we don't use the SIMD32 support in gen6, we translate
-       * the pre-gen6 compression control here.
+   switch (compression_control) {
+   case BRW_COMPRESSION_NONE:
+      /* This is the "use the first set of bits of dmask/vmask/arf
+       * according to execsize" option.
        */
-      switch (compression_control) {
-      case BRW_COMPRESSION_NONE:
-        /* This is the "use the first set of bits of dmask/vmask/arf
-         * according to execsize" option.
-         */
-         brw_inst_set_qtr_control(p->devinfo, p->current, GEN6_COMPRESSION_1Q);
-        break;
-      case BRW_COMPRESSION_2NDHALF:
-        /* For SIMD8, this is "use the second set of 8 bits." */
-         brw_inst_set_qtr_control(p->devinfo, p->current, GEN6_COMPRESSION_2Q);
-        break;
-      case BRW_COMPRESSION_COMPRESSED:
-        /* For SIMD16 instruction compression, use the first set of 16 bits
-         * since we don't do SIMD32 dispatch.
-         */
-         brw_inst_set_qtr_control(p->devinfo, p->current, GEN6_COMPRESSION_1H);
-        break;
-      default:
-         unreachable("not reached");
-      }
-   } else {
-      brw_inst_set_qtr_control(p->devinfo, p->current, compression_control);
+      p->current->group = 0;
+      break;
+   case BRW_COMPRESSION_2NDHALF:
+      /* For SIMD8, this is "use the second set of 8 bits." */
+      p->current->group = 8;
+      break;
+   case BRW_COMPRESSION_COMPRESSED:
+      /* For SIMD16 instruction compression, use the first set of 16 bits
+       * since we don't do SIMD32 dispatch.
+       */
+      p->current->group = 0;
+      break;
+   default:
+      unreachable("not reached");
+   }
+
+   if (p->devinfo->gen <= 6) {
+      p->current->compressed =
+         (compression_control == BRW_COMPRESSION_COMPRESSED);
    }
 }
 
@@ -246,7 +233,7 @@ brw_inst_set_compression(const struct gen_device_info *devinfo,
 void
 brw_set_default_compression(struct brw_codegen *p, bool on)
 {
-   brw_inst_set_compression(p->devinfo, p->current, on);
+   p->current->compressed = on;
 }
 
 /**
@@ -283,29 +270,28 @@ brw_inst_set_group(const struct gen_device_info *devinfo,
 void
 brw_set_default_group(struct brw_codegen *p, unsigned group)
 {
-   brw_inst_set_group(p->devinfo, p->current, group);
+   p->current->group = group;
 }
 
 void brw_set_default_mask_control( struct brw_codegen *p, unsigned value )
 {
-   brw_inst_set_mask_control(p->devinfo, p->current, value);
+   p->current->mask_control = value;
 }
 
 void brw_set_default_saturate( struct brw_codegen *p, bool enable )
 {
-   brw_inst_set_saturate(p->devinfo, p->current, enable);
+   p->current->saturate = enable;
 }
 
 void brw_set_default_acc_write_control(struct brw_codegen *p, unsigned value)
 {
-   if (p->devinfo->gen >= 6)
-      brw_inst_set_acc_wr_control(p->devinfo, p->current, value);
+   p->current->acc_wr_control = value;
 }
 
 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->current + 1) = *p->current;
    p->current++;
 }
 
@@ -325,6 +311,7 @@ brw_init_codegen(const struct gen_device_info *devinfo,
    memset(p, 0, sizeof(*p));
 
    p->devinfo = devinfo;
+   p->automatic_exec_sizes = true;
    /*
     * Set the initial instruction store array size to 1024, if found that
     * isn't enough, then it will double the store size at brw_next_insn()
@@ -364,14 +351,56 @@ const unsigned *brw_get_program( struct brw_codegen *p,
    return (const unsigned *)p->store;
 }
 
+bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
+                               const char *identifier)
+{
+   const char *read_path = getenv("INTEL_SHADER_ASM_READ_PATH");
+   if (!read_path) {
+      return false;
+   }
+
+   char *name = ralloc_asprintf(NULL, "%s/%s.bin", read_path, identifier);
+
+   int fd = open(name, O_RDONLY);
+   ralloc_free(name);
+
+   if (fd == -1) {
+      return false;
+   }
+
+   struct stat sb;
+   if (fstat(fd, &sb) != 0 || (!S_ISREG(sb.st_mode))) {
+      close(fd);
+      return false;
+   }
+
+   p->nr_insn -= (p->next_insn_offset - start_offset) / sizeof(brw_inst);
+   p->nr_insn += sb.st_size / sizeof(brw_inst);
+
+   p->next_insn_offset = start_offset + sb.st_size;
+   p->store_size = (start_offset + sb.st_size) / sizeof(brw_inst);
+   p->store = reralloc_size(p->mem_ctx, p->store, p->next_insn_offset);
+   assert(p->store);
+
+   read(fd, p->store + start_offset, sb.st_size);
+   close(fd);
+
+   bool valid = brw_validate_instructions(p->devinfo, p->store,
+                                          start_offset, p->next_insn_offset,
+                                          0);
+   assert(valid);
+
+   return true;
+}
+
 void
 brw_disassemble(const struct gen_device_info *devinfo,
-                void *assembly, int start, int end, FILE *out)
+                const void *assembly, int start, int end, FILE *out)
 {
    bool dump_hex = (INTEL_DEBUG & DEBUG_HEX) != 0;
 
    for (int offset = start; offset < end;) {
-      brw_inst *insn = assembly + offset;
+      const brw_inst *insn = assembly + offset;
       brw_inst uncompacted;
       bool compacted = brw_inst_cmpt_control(devinfo, insn);
       if (0)
@@ -379,24 +408,37 @@ brw_disassemble(const struct gen_device_info *devinfo,
 
       if (compacted) {
          brw_compact_inst *compacted = (void *)insn;
-        if (dump_hex) {
-           fprintf(out, "0x%08x 0x%08x                       ",
-                   ((uint32_t *)insn)[1],
-                   ((uint32_t *)insn)[0]);
-        }
-
-        brw_uncompact_instruction(devinfo, &uncompacted, compacted);
-        insn = &uncompacted;
-        offset += 8;
+         if (dump_hex) {
+            unsigned char * insn_ptr = ((unsigned char *)&insn[0]);
+            const unsigned int blank_spaces = 24;
+            for (int i = 0 ; i < 8; i = i + 4) {
+               fprintf(out, "%02x %02x %02x %02x ",
+                       insn_ptr[i],
+                       insn_ptr[i + 1],
+                       insn_ptr[i + 2],
+                       insn_ptr[i + 3]);
+            }
+            /* Make compacted instructions hex value output vertically aligned
+             * with uncompacted instructions hex value
+             */
+            fprintf(out, "%*c", blank_spaces, ' ');
+         }
+
+         brw_uncompact_instruction(devinfo, &uncompacted, compacted);
+         insn = &uncompacted;
+         offset += 8;
       } else {
-        if (dump_hex) {
-           fprintf(out, "0x%08x 0x%08x 0x%08x 0x%08x ",
-                   ((uint32_t *)insn)[3],
-                   ((uint32_t *)insn)[2],
-                   ((uint32_t *)insn)[1],
-                   ((uint32_t *)insn)[0]);
-        }
-        offset += 16;
+         if (dump_hex) {
+            unsigned char * insn_ptr = ((unsigned char *)&insn[0]);
+            for (int i = 0 ; i < 16; i = i + 4) {
+               fprintf(out, "%02x %02x %02x %02x ",
+                       insn_ptr[i],
+                       insn_ptr[i + 1],
+                       insn_ptr[i + 2],
+                       insn_ptr[i + 3]);
+            }
+         }
+         offset += 16;
       }
 
       brw_disassemble_inst(out, devinfo, insn, compacted);
@@ -412,6 +454,8 @@ enum gen {
    GEN75 = (1 << 5),
    GEN8  = (1 << 6),
    GEN9  = (1 << 7),
+   GEN10 = (1 << 8),
+   GEN11 = (1 << 9),
    GEN_ALL = ~0
 };
 
@@ -488,7 +532,13 @@ static const struct opcode_desc opcode_descs[128] = {
    [BRW_OPCODE_ASR] = {
       .name = "asr",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
    },
-   /* Reserved - 13-15 */
+   /* Reserved - 13 */
+   [BRW_OPCODE_ROR] = {
+      .name = "ror",     .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN11),
+   },
+   [BRW_OPCODE_ROL] = {
+      .name = "rol",     .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN11),
+   },
    [BRW_OPCODE_CMP] = {
       .name = "cmp",     .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
    },
@@ -655,16 +705,16 @@ static const struct opcode_desc opcode_descs[128] = {
    },
    /* Reserved 88 */
    [BRW_OPCODE_LINE] = {
-      .name = "line",    .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
+      .name = "line",    .nsrc = 2, .ndst = 1, .gens = GEN_LE(GEN10),
    },
    [BRW_OPCODE_PLN] = {
-      .name = "pln",     .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN45),
+      .name = "pln",     .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN45) & GEN_LE(GEN10),
    },
    [BRW_OPCODE_MAD] = {
       .name = "mad",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6),
    },
    [BRW_OPCODE_LRP] = {
-      .name = "lrp",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6),
+      .name = "lrp",     .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6) & GEN_LE(GEN10),
    },
    [93] = {
       .name = "madm",    .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN8),
@@ -688,6 +738,8 @@ gen_from_devinfo(const struct gen_device_info *devinfo)
    case 7: return devinfo->is_haswell ? GEN75 : GEN7;
    case 8: return GEN8;
    case 9: return GEN9;
+   case 10: return GEN10;
+   case 11: return GEN11;
    default:
       unreachable("not reached");
    }