intel/compiler: Fix pointer arithmetic when reading shader assembly
[mesa.git] / src / intel / compiler / brw_eu.cpp
index 11bdddcc7cba0ebe66ca6529dd8fcced92dd205e..51ae8cdc2210a9883baab279a838dc8595c872d3 100644 (file)
@@ -35,6 +35,7 @@
 #include "brw_eu_defines.h"
 #include "brw_eu.h"
 #include "brw_shader.h"
+#include "brw_gen_enum.h"
 #include "dev/gen_debug.h"
 
 #include "util/ralloc.h"
@@ -146,6 +147,12 @@ brw_get_default_access_mode(struct brw_codegen *p)
    return p->current->access_mode;
 }
 
+tgl_swsb
+brw_get_default_swsb(struct brw_codegen *p)
+{
+   return p->current->swsb;
+}
+
 void
 brw_set_default_exec_size(struct brw_codegen *p, unsigned value)
 {
@@ -288,6 +295,11 @@ void brw_set_default_acc_write_control(struct brw_codegen *p, unsigned value)
    p->current->acc_wr_control = value;
 }
 
+void brw_set_default_swsb(struct brw_codegen *p, tgl_swsb value)
+{
+   p->current->swsb = value;
+}
+
 void brw_push_insn_state( struct brw_codegen *p )
 {
    assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
@@ -382,26 +394,147 @@ bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
    p->store = (brw_inst *)reralloc_size(p->mem_ctx, p->store, p->next_insn_offset);
    assert(p->store);
 
-   read(fd, p->store + start_offset, sb.st_size);
+   ssize_t ret = read(fd, (char *)p->store + start_offset, sb.st_size);
    close(fd);
+   if (ret != sb.st_size) {
+      return false;
+   }
 
-   bool valid = brw_validate_instructions(p->devinfo, p->store,
-                                          start_offset, p->next_insn_offset,
-                                          0);
+   ASSERTED bool valid =
+      brw_validate_instructions(p->devinfo, p->store,
+                                start_offset, p->next_insn_offset,
+                                NULL);
    assert(valid);
 
    return true;
 }
 
+const struct brw_label *
+brw_find_label(const struct brw_label *root, int offset)
+{
+   const struct brw_label *curr = root;
+
+   if (curr != NULL)
+   {
+      do {
+         if (curr->offset == offset)
+            return curr;
+
+         curr = curr->next;
+      } while (curr != NULL);
+   }
+
+   return curr;
+}
+
+void
+brw_create_label(struct brw_label **labels, int offset, void *mem_ctx)
+{
+   if (*labels != NULL) {
+      struct brw_label *curr = *labels;
+      struct brw_label *prev;
+
+      do {
+         prev = curr;
+
+         if (curr->offset == offset)
+            return;
+
+         curr = curr->next;
+      } while (curr != NULL);
+
+      curr = ralloc(mem_ctx, struct brw_label);
+      curr->offset = offset;
+      curr->number = prev->number + 1;
+      curr->next = NULL;
+      prev->next = curr;
+   } else {
+      struct brw_label *root = ralloc(mem_ctx, struct brw_label);
+      root->number = 0;
+      root->offset = offset;
+      root->next = NULL;
+      *labels = root;
+   }
+}
+
+const struct brw_label *
+brw_label_assembly(const struct gen_device_info *devinfo,
+                   const void *assembly, int start, int end, void *mem_ctx)
+{
+   struct brw_label *root_label = NULL;
+
+   int to_bytes_scale = sizeof(brw_inst) / brw_jump_scale(devinfo);
+
+   for (int offset = start; offset < end;) {
+      const brw_inst *inst = (const brw_inst *) ((const char *) assembly + offset);
+      brw_inst uncompacted;
+
+      bool is_compact = brw_inst_cmpt_control(devinfo, inst);
+
+      if (is_compact) {
+         brw_compact_inst *compacted = (brw_compact_inst *)inst;
+         brw_uncompact_instruction(devinfo, &uncompacted, compacted);
+         inst = &uncompacted;
+      }
+
+      if (brw_has_uip(devinfo, brw_inst_opcode(devinfo, inst))) {
+         /* Instructions that have UIP also have JIP. */
+         brw_create_label(&root_label,
+            offset + brw_inst_uip(devinfo, inst) * to_bytes_scale, mem_ctx);
+         brw_create_label(&root_label,
+            offset + brw_inst_jip(devinfo, inst) * to_bytes_scale, mem_ctx);
+      } else if (brw_has_jip(devinfo, brw_inst_opcode(devinfo, inst))) {
+         int jip;
+         if (devinfo->gen >= 7) {
+            jip = brw_inst_jip(devinfo, inst);
+         } else {
+            jip = brw_inst_gen6_jump_count(devinfo, inst);
+         }
+
+         brw_create_label(&root_label, offset + jip * to_bytes_scale, mem_ctx);
+      }
+
+      if (is_compact) {
+         offset += sizeof(brw_compact_inst);
+      } else {
+         offset += sizeof(brw_inst);
+      }
+   }
+
+   return root_label;
+}
+
+void
+brw_disassemble_with_labels(const struct gen_device_info *devinfo,
+                            const void *assembly, int start, int end, FILE *out)
+{
+   void *mem_ctx = ralloc_context(NULL);
+   const struct brw_label *root_label =
+      brw_label_assembly(devinfo, assembly, start, end, mem_ctx);
+
+   brw_disassemble(devinfo, assembly, start, end, root_label, out);
+
+   ralloc_free(mem_ctx);
+}
+
 void
 brw_disassemble(const struct gen_device_info *devinfo,
-                const void *assembly, int start, int end, FILE *out)
+                const void *assembly, int start, int end,
+                const struct brw_label *root_label, FILE *out)
 {
    bool dump_hex = (INTEL_DEBUG & DEBUG_HEX) != 0;
 
    for (int offset = start; offset < end;) {
       const brw_inst *insn = (const brw_inst *)((char *)assembly + offset);
       brw_inst uncompacted;
+
+      if (root_label != NULL) {
+        const struct brw_label *label = brw_find_label(root_label, offset);
+        if (label != NULL) {
+           fprintf(out, "\nLABEL%d:\n", label->number);
+        }
+      }
+
       bool compacted = brw_inst_cmpt_control(devinfo, insn);
       if (0)
          fprintf(out, "0x%08x: ", offset);
@@ -426,8 +559,6 @@ brw_disassemble(const struct gen_device_info *devinfo,
 
          brw_uncompact_instruction(devinfo, &uncompacted, compacted);
          insn = &uncompacted;
-         offset += 8;
-      } else {
          if (dump_hex) {
             unsigned char * insn_ptr = ((unsigned char *)&insn[0]);
             for (int i = 0 ; i < 16; i = i + 4) {
@@ -438,57 +569,65 @@ brw_disassemble(const struct gen_device_info *devinfo,
                        insn_ptr[i + 3]);
             }
          }
-         offset += 16;
       }
 
-      brw_disassemble_inst(out, devinfo, insn, compacted);
+      brw_disassemble_inst(out, devinfo, insn, compacted, offset, root_label);
+
+      if (compacted) {
+         offset += sizeof(brw_compact_inst);
+      } else {
+         offset += sizeof(brw_inst);
+      }
    }
 }
 
-enum gen {
-   GEN4  = (1 << 0),
-   GEN45 = (1 << 1),
-   GEN5  = (1 << 2),
-   GEN6  = (1 << 3),
-   GEN7  = (1 << 4),
-   GEN75 = (1 << 5),
-   GEN8  = (1 << 6),
-   GEN9  = (1 << 7),
-   GEN10 = (1 << 8),
-   GEN11 = (1 << 9),
-   GEN_ALL = ~0
-};
-
-#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_descs[] = {
    /* IR,                 HW,  name,      nsrc, ndst, gens */
    { BRW_OPCODE_ILLEGAL,  0,   "illegal", 0,    0,    GEN_ALL },
-   { BRW_OPCODE_MOV,      1,   "mov",     1,    1,    GEN_ALL },
-   { BRW_OPCODE_SEL,      2,   "sel",     2,    1,    GEN_ALL },
-   { BRW_OPCODE_MOVI,     3,   "movi",    2,    1,    GEN_GE(GEN45) },
-   { BRW_OPCODE_NOT,      4,   "not",     1,    1,    GEN_ALL },
-   { BRW_OPCODE_AND,      5,   "and",     2,    1,    GEN_ALL },
-   { BRW_OPCODE_OR,       6,   "or",      2,    1,    GEN_ALL },
-   { BRW_OPCODE_XOR,      7,   "xor",     2,    1,    GEN_ALL },
-   { BRW_OPCODE_SHR,      8,   "shr",     2,    1,    GEN_ALL },
-   { BRW_OPCODE_SHL,      9,   "shl",     2,    1,    GEN_ALL },
+   { BRW_OPCODE_SYNC,     1,   "sync",    1,    0,    GEN_GE(GEN12) },
+   { BRW_OPCODE_MOV,      1,   "mov",     1,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_MOV,      97,  "mov",     1,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_SEL,      2,   "sel",     2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_SEL,      98,  "sel",     2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_MOVI,     3,   "movi",    2,    1,    GEN_GE(GEN45) & GEN_LT(GEN12) },
+   { BRW_OPCODE_MOVI,     99,  "movi",    2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_NOT,      4,   "not",     1,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_NOT,      100, "not",     1,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_AND,      5,   "and",     2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_AND,      101, "and",     2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_OR,       6,   "or",      2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_OR,       102, "or",      2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_XOR,      7,   "xor",     2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_XOR,      103, "xor",     2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_SHR,      8,   "shr",     2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_SHR,      104, "shr",     2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_SHL,      9,   "shl",     2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_SHL,      105, "shl",     2,    1,    GEN_GE(GEN12) },
    { BRW_OPCODE_DIM,      10,  "dim",     1,    1,    GEN75 },
-   { BRW_OPCODE_SMOV,     10,  "smov",    0,    0,    GEN_GE(GEN8) },
-   { BRW_OPCODE_ASR,      12,  "asr",     2,    1,    GEN_ALL },
-   { BRW_OPCODE_ROR,      14,  "ror",     2,    1,    GEN_GE(GEN11) },
-   { BRW_OPCODE_ROL,      15,  "rol",     2,    1,    GEN_GE(GEN11) },
-   { BRW_OPCODE_CMP,      16,  "cmp",     2,    1,    GEN_ALL },
-   { BRW_OPCODE_CMPN,     17,  "cmpn",    2,    1,    GEN_ALL },
-   { BRW_OPCODE_CSEL,     18,  "csel",    3,    1,    GEN_GE(GEN8) },
+   { BRW_OPCODE_SMOV,     10,  "smov",    0,    0,    GEN_GE(GEN8) & GEN_LT(GEN12) },
+   { BRW_OPCODE_SMOV,     106, "smov",    0,    0,    GEN_GE(GEN12) },
+   { BRW_OPCODE_ASR,      12,  "asr",     2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_ASR,      108, "asr",     2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_ROR,      14,  "ror",     2,    1,    GEN11 },
+   { BRW_OPCODE_ROR,      110, "ror",     2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_ROL,      15,  "rol",     2,    1,    GEN11 },
+   { BRW_OPCODE_ROL,      111, "rol",     2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_CMP,      16,  "cmp",     2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_CMP,      112, "cmp",     2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_CMPN,     17,  "cmpn",    2,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_CMPN,     113, "cmpn",    2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_CSEL,     18,  "csel",    3,    1,    GEN_GE(GEN8) & GEN_LT(GEN12) },
+   { BRW_OPCODE_CSEL,     114, "csel",    3,    1,    GEN_GE(GEN12) },
    { BRW_OPCODE_F32TO16,  19,  "f32to16", 1,    1,    GEN7 | GEN75 },
    { BRW_OPCODE_F16TO32,  20,  "f16to32", 1,    1,    GEN7 | GEN75 },
-   { BRW_OPCODE_BFREV,    23,  "bfrev",   1,    1,    GEN_GE(GEN7) },
-   { BRW_OPCODE_BFE,      24,  "bfe",     3,    1,    GEN_GE(GEN7) },
-   { BRW_OPCODE_BFI1,     25,  "bfi1",    2,    1,    GEN_GE(GEN7) },
-   { BRW_OPCODE_BFI2,     26,  "bfi2",    3,    1,    GEN_GE(GEN7) },
+   { BRW_OPCODE_BFREV,    23,  "bfrev",   1,    1,    GEN_GE(GEN7) & GEN_LT(GEN12) },
+   { BRW_OPCODE_BFREV,    119, "bfrev",   1,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_BFE,      24,  "bfe",     3,    1,    GEN_GE(GEN7) & GEN_LT(GEN12) },
+   { BRW_OPCODE_BFE,      120, "bfe",     3,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_BFI1,     25,  "bfi1",    2,    1,    GEN_GE(GEN7) & GEN_LT(GEN12) },
+   { BRW_OPCODE_BFI1,     121, "bfi1",    2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_BFI2,     26,  "bfi2",    3,    1,    GEN_GE(GEN7) & GEN_LT(GEN12) },
+   { BRW_OPCODE_BFI2,     122, "bfi2",    3,    1,    GEN_GE(GEN12) },
    { BRW_OPCODE_JMPI,     32,  "jmpi",    0,    0,    GEN_ALL },
    { BRW_OPCODE_BRD,      33,  "brd",     0,    0,    GEN_GE(GEN7) },
    { BRW_OPCODE_IF,       34,  "if",      0,    0,    GEN_ALL },
@@ -511,11 +650,13 @@ static const struct opcode_desc opcode_descs[] = {
    { BRW_OPCODE_FORK,     46,  "fork",    0,    0,    GEN6 },
    { BRW_OPCODE_GOTO,     46,  "goto",    0,    0,    GEN_GE(GEN8) },
    { BRW_OPCODE_POP,      47,  "pop",     2,    0,    GEN_LE(GEN5) },
-   { BRW_OPCODE_WAIT,     48,  "wait",    1,    0,    GEN_ALL },
-   { BRW_OPCODE_SEND,     49,  "send",    1,    1,    GEN_ALL },
-   { BRW_OPCODE_SENDC,    50,  "sendc",   1,    1,    GEN_ALL },
-   { BRW_OPCODE_SENDS,    51,  "sends",   2,    1,    GEN_GE(GEN9) },
-   { BRW_OPCODE_SENDSC,   52,  "sendsc",  2,    1,    GEN_GE(GEN9) },
+   { BRW_OPCODE_WAIT,     48,  "wait",    1,    0,    GEN_LT(GEN12) },
+   { BRW_OPCODE_SEND,     49,  "send",    1,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_SENDC,    50,  "sendc",   1,    1,    GEN_LT(GEN12) },
+   { BRW_OPCODE_SEND,     49,  "send",    2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_SENDC,    50,  "sendc",   2,    1,    GEN_GE(GEN12) },
+   { BRW_OPCODE_SENDS,    51,  "sends",   2,    1,    GEN_GE(GEN9) & GEN_LT(GEN12) },
+   { BRW_OPCODE_SENDSC,   52,  "sendsc",  2,    1,    GEN_GE(GEN9) & GEN_LT(GEN12) },
    { BRW_OPCODE_MATH,     56,  "math",    2,    1,    GEN_GE(GEN6) },
    { BRW_OPCODE_ADD,      64,  "add",     2,    1,    GEN_ALL },
    { BRW_OPCODE_MUL,      65,  "mul",     2,    1,    GEN_ALL },
@@ -545,26 +686,10 @@ static const struct opcode_desc opcode_descs[] = {
    { BRW_OPCODE_LRP,      92,  "lrp",     3,    1,    GEN_GE(GEN6) & GEN_LE(GEN10) },
    { BRW_OPCODE_MADM,     93,  "madm",    3,    1,    GEN_GE(GEN8) },
    { BRW_OPCODE_NENOP,    125, "nenop",   0,    0,    GEN45 },
-   { BRW_OPCODE_NOP,      126, "nop",     0,    0,    GEN_ALL },
+   { BRW_OPCODE_NOP,      126, "nop",     0,    0,    GEN_LT(GEN12) },
+   { BRW_OPCODE_NOP,      96,  "nop",     0,    0,    GEN_GE(GEN12) }
 };
 
-static enum gen
-gen_from_devinfo(const struct gen_device_info *devinfo)
-{
-   switch (devinfo->gen) {
-   case 4: return devinfo->is_g4x ? GEN45 : GEN4;
-   case 5: return GEN5;
-   case 6: return GEN6;
-   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");
-   }
-}
-
 /**
  * Look up the opcode_descs[] entry with \p key member matching \p k which is
  * supported by the device specified by \p devinfo, or NULL if there is no