[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