[Mesa-dev] [PATCH 04/10] i965/disasm: Support for disassembling SENDS and SENDSC

Toni Lönnberg toni.lonnberg at intel.com
Mon Feb 20 13:27:44 UTC 2017


From: "Lonnberg, Toni" <toni.lonnberg at intel.com>

The shader disassembly now decodes SENDS/SENDSC instructions. Due to ambiguity
in the documentation, the decoding of the version where a scalar register is
used as the extra descriptor, this might need to be re-implemented.
---
 src/mesa/drivers/dri/i965/brw_disasm.c | 109 +++++++++++++++++++++++++++++++--
 src/mesa/drivers/dri/i965/brw_inst.h   |  31 +++++++++-
 2 files changed, 135 insertions(+), 5 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c
index b75e08d..426e4fa 100644
--- a/src/mesa/drivers/dri/i965/brw_disasm.c
+++ b/src/mesa/drivers/dri/i965/brw_disasm.c
@@ -723,6 +723,37 @@ dest(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
    unsigned elem_size = brw_element_size(devinfo, inst, dst);
    int err = 0;
 
+   if (brw_inst_opcode(devinfo, inst) == BRW_OPCODE_SENDS ||
+       brw_inst_opcode(devinfo, inst) == BRW_OPCODE_SENDSC) {
+
+      if (brw_inst_sends_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
+         err |= reg(file, brw_inst_sends_dst_reg_file(devinfo, inst),
+                    brw_inst_sends_dst_da_reg_nr(devinfo, inst));
+
+         if (err == -1)
+            return 0;
+
+         if (brw_inst_sends_dst_da_subreg_nr(devinfo, inst))
+            format(file, ".%"PRIu64, brw_inst_sends_dst_da_subreg_nr(devinfo, inst) /
+                   elem_size);
+         string(file, "<1>");
+         err |= control(file, "dest reg encoding", reg_encoding,
+                        brw_inst_sends_dst_reg_type(devinfo, inst), NULL);
+      } else {
+         string(file, "g[a0");
+         if (brw_inst_sends_dst_ia_subreg_nr(devinfo, inst))
+            format(file, ".%"PRIu64, brw_inst_sends_dst_ia_subreg_nr(devinfo, inst) /
+                   elem_size);
+         if (brw_inst_sends_dst_ia16_addr_imm(devinfo, inst))
+            format(file, " %d", brw_inst_sends_dst_ia16_addr_imm(devinfo, inst));
+         string(file, "]<1>");
+         err |= control(file, "dest reg encoding", reg_encoding,
+                        brw_inst_sends_dst_reg_type(devinfo, inst), NULL);
+      }
+
+      return err;
+   }
+
    if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
       if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
          err |= reg(file, brw_inst_dst_reg_file(devinfo, inst),
@@ -1067,6 +1098,40 @@ imm(FILE *file, const struct gen_device_info *devinfo, unsigned type, brw_inst *
 static int
 src0(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
 {
+   unsigned elem_size = brw_element_size(devinfo, inst, src0);
+   int err = 0;
+
+   if (brw_inst_opcode(devinfo, inst) == BRW_OPCODE_SENDS ||
+       brw_inst_opcode(devinfo, inst) == BRW_OPCODE_SENDSC) {
+
+      if (brw_inst_sends_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
+         err |= reg(file, BRW_GENERAL_REGISTER_FILE,
+                    brw_inst_sends_src0_da_reg_nr(devinfo, inst));
+
+         if (err == -1)
+            return 0;
+
+         if (brw_inst_sends_src0_da_subreg_nr(devinfo, inst))
+            format(file, ".%"PRIu64, brw_inst_sends_src0_da_subreg_nr(devinfo, inst) /
+                   elem_size);
+         string(file, "<1>");
+         err |= control(file, "dest reg encoding", reg_encoding,
+                        brw_inst_sends_dst_reg_type(devinfo, inst), NULL);
+      } else {
+         string(file, "g[a0");
+         if (brw_inst_sends_src0_ia_subreg_nr(devinfo, inst))
+            format(file, ".%"PRIu64, brw_inst_sends_src0_ia_subreg_nr(devinfo, inst) /
+                   elem_size);
+         if (brw_inst_sends_src0_ia16_addr_imm(devinfo, inst))
+            format(file, " %d", brw_inst_sends_src0_ia16_addr_imm(devinfo, inst));
+         string(file, "]<1>");
+         err |= control(file, "dest reg encoding", reg_encoding,
+                        brw_inst_sends_dst_reg_type(devinfo, inst), NULL);
+      }
+
+      return err;
+   }
+
    if (brw_inst_src0_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
       return imm(file, devinfo, brw_inst_src0_reg_type(devinfo, inst), inst);
    } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
@@ -1123,6 +1188,22 @@ src0(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
 static int
 src1(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
 {
+   int err = 0;
+
+   if (brw_inst_opcode(devinfo, inst) == BRW_OPCODE_SENDS ||
+       brw_inst_opcode(devinfo, inst) == BRW_OPCODE_SENDSC) {
+      assert(devinfo->gen >= 9);
+
+      err |= reg(file, brw_inst_sends_src1_reg_file(devinfo, inst),
+                 brw_inst_sends_src1_da_reg_nr(devinfo, inst));
+
+      string(file, "<1>");
+      err |= control(file, "dest reg encoding", reg_encoding,
+                     brw_inst_sends_dst_reg_type(devinfo, inst), NULL);
+
+      return err;
+   }
+
    if (brw_inst_src1_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
       return imm(file, devinfo, brw_inst_src1_reg_type(devinfo, inst), inst);
    } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
@@ -1261,7 +1342,8 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
       string(file, " ");
       err |= control(file, "function", math_function,
                      brw_inst_math_function(devinfo, inst), NULL);
-   } else if (opcode != BRW_OPCODE_SEND && opcode != BRW_OPCODE_SENDC) {
+   } else if (opcode != BRW_OPCODE_SEND && opcode != BRW_OPCODE_SENDC &&
+              opcode != BRW_OPCODE_SENDS && opcode != BRW_OPCODE_SENDSC) {
       err |= control(file, "conditional modifier", conditional_modifier,
                      brw_inst_cond_modifier(devinfo, inst), NULL);
 
@@ -1390,6 +1472,16 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
 
          pad(file, 64);
          err |= src1(file, devinfo, inst);
+      } else if (opcode == BRW_OPCODE_SENDS || opcode == BRW_OPCODE_SENDSC) {
+         pad(file, 64);
+         format(file, "0x%"PRIx32, brw_inst_sends_exdesc(devinfo, inst));
+
+         pad(file, 80);
+         if (brw_inst_sends_selreg32desc(devinfo, inst)) {
+            format(file, "a0.0<0;1,0>:ud");
+         } else {
+            format(file, "0x%"PRIx32, brw_inst_imm_ud(devinfo, inst));
+         }
       }
    }
 
@@ -1434,7 +1526,8 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
          err |= control(file, "acc write control", accwr,
                         brw_inst_acc_wr_control(devinfo, inst), &space);
       }
-      if (opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC)
+      if (opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC ||
+          opcode == BRW_OPCODE_SENDS || opcode == BRW_OPCODE_SENDSC)
          err |= control(file, "end of thread", end_of_thread,
                         brw_inst_eot(devinfo, inst), &space);
       if (space)
@@ -1443,7 +1536,8 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
    }
    string(file, ";");
 
-   if (opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC) {
+   if (opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC ||
+       opcode == BRW_OPCODE_SENDS || opcode == BRW_OPCODE_SENDSC) {
       enum brw_message_target sfid = brw_inst_sfid(devinfo, inst);
 
       space = 0;
@@ -1453,7 +1547,10 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
                      sfid, &space);
 
 
-      if (brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) {
+      if (((opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC) &&
+         (brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE)) ||
+         ((opcode == BRW_OPCODE_SENDS || opcode == BRW_OPCODE_SENDSC) &&
+         brw_inst_sends_selreg32desc(devinfo, inst))) {
          format(file, " indirect");
       } else {
          switch (sfid) {
@@ -1675,6 +1772,10 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
             string(file, " ");
          format(file, "mlen %"PRIu64, brw_inst_mlen(devinfo, inst));
          format(file, " rlen %"PRIu64, brw_inst_rlen(devinfo, inst));
+
+         if (opcode == BRW_OPCODE_SENDS || opcode == BRW_OPCODE_SENDSC) {
+            format(file, " exdesc len %"PRIu64, brw_inst_sends_exdesc_len(devinfo, inst));
+         }
       }
    }
    newline(file);
diff --git a/src/mesa/drivers/dri/i965/brw_inst.h b/src/mesa/drivers/dri/i965/brw_inst.h
index bcb6786..33b87d4 100644
--- a/src/mesa/drivers/dri/i965/brw_inst.h
+++ b/src/mesa/drivers/dri/i965/brw_inst.h
@@ -244,6 +244,33 @@ F(3src_opcode,           6,  0)
 /** @} */
 
 /**
+ * SENDS and SENDSC instructions:
+ *  @{
+ */
+F(sends_src0_address_mode,   79,  79)
+F(sends_selreg32desc,        77,  77)
+F(sends_src0_ia_subreg_nr,   76,  73)
+F(sends_src0_da_reg_nr,      76,  69)
+F(sends_src0_da_subreg_nr,   68,  68)
+F(sends_exdesc_len,          67,  64)
+F(sends_dst_address_mode,    63,  63)
+F(sends_dst_ia_subreg_nr,    60,  57)
+F(sends_dst_da_reg_nr,       60,  53)
+F(sends_dst_da_subreg_nr,    52,  52)
+F(sends_src1_da_reg_nr,      51,  44)
+F(sends_dst_reg_type,        40,  37)
+F(sends_src1_reg_file,       36,  36)
+F(sends_dst_reg_file,        35,  35)
+
+static inline int32_t
+brw_inst_sends_exdesc(const struct gen_device_info *devinfo, const brw_inst *inst)
+{
+   assert(devinfo->gen >= 9);
+   return (brw_inst_bits(inst, 95, 80) << 16) | (brw_inst_bits(inst, 67, 64) << 6) | brw_inst_bits(inst, 27, 24);
+}
+/** @} */
+
+/**
  * Flow control instruction bits:
  *  @{
  */
@@ -695,13 +722,15 @@ brw_inst_##reg##_ia16_addr_imm(const struct gen_device_info *devinfo,     \
    }                                                                      \
 }
 
-/* AddrImm[9:0] for Align16 Indirect Addressing:
+/* AddrImm[9:4] for Align16 Indirect Addressing:
  * Compared to Align1, these are missing the low 4 bits.
  *                     -Gen 4-  ----Gen8----
  */
 BRW_IA16_ADDR_IMM(src1, 105, 96, 121, 104, 100)
 BRW_IA16_ADDR_IMM(src0,  73, 64,  95,  72,  68)
 BRW_IA16_ADDR_IMM(dst,   57, 52,  47,  56,  52)
+BRW_IA16_ADDR_IMM(sends_src0,  -1, -1,  78,  72,  68)
+BRW_IA16_ADDR_IMM(sends_dst,   -1, -1,  62,  56,  52)
 
 /**
  * Fetch a set of contiguous bits from the instruction.
-- 
2.7.4



More information about the mesa-dev mailing list