From: "Lonnberg, Toni" <toni.lonnb...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev