panfrost: bifrost: disassemble: Fix decoding of next_regs

next_regs decoding is wrong for the first and last instructions in a
clause:
- the first instruction has its destination encoded in the second reg
  block
- the last instruction has its destination encoded in the first reg block
  (things wrap around)

So, only the last instruction should pass first=true when decoding
next_regs. Fix that by passing the is_last_instruction information
instead of is_first_instruction to the disasm helpers.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7040>
This commit is contained in:
Boris Brezillon 2020-10-07 08:42:00 +02:00
parent 19561f31a8
commit ccb3d7d8be
2 changed files with 15 additions and 11 deletions

View File

@ -214,9 +214,10 @@ bi_disasm_dest_mask(FILE *fp, enum bifrost_reg_op op)
}
void
bi_disasm_dest_fma(FILE *fp, struct bifrost_regs *next_regs, bool first)
bi_disasm_dest_fma(FILE *fp, struct bifrost_regs *next_regs, bool last)
{
struct bifrost_reg_ctrl ctrl = DecodeRegCtrl(fp, *next_regs, first);
/* If this is the last instruction, next_regs points to the first reg entry. */
struct bifrost_reg_ctrl ctrl = DecodeRegCtrl(fp, *next_regs, last);
if (ctrl.slot23.slot2 >= BIFROST_OP_WRITE) {
fprintf(fp, "r%u:t0", next_regs->reg2);
bi_disasm_dest_mask(fp, ctrl.slot23.slot2);
@ -228,9 +229,10 @@ bi_disasm_dest_fma(FILE *fp, struct bifrost_regs *next_regs, bool first)
}
void
bi_disasm_dest_add(FILE *fp, struct bifrost_regs *next_regs, bool first)
bi_disasm_dest_add(FILE *fp, struct bifrost_regs *next_regs, bool last)
{
struct bifrost_reg_ctrl ctrl = DecodeRegCtrl(fp, *next_regs, first);
/* If this is the last instruction, next_regs points to the first reg entry. */
struct bifrost_reg_ctrl ctrl = DecodeRegCtrl(fp, *next_regs, last);
if (ctrl.slot23.slot3 >= BIFROST_OP_WRITE && !ctrl.slot23.slot3_fma) {
fprintf(fp, "r%u:t0", next_regs->reg3);
@ -671,12 +673,14 @@ static bool dump_clause(FILE *fp, uint32_t *words, unsigned *size, unsigned offs
memcpy((char *) &regs, (char *) &instrs[i].reg_bits, sizeof(regs));
if (verbose) {
fprintf(fp, "# regs: %016" PRIx64 "\n", instrs->reg_bits);
fprintf(fp, "# regs: %016" PRIx64 "\n", instrs[i].reg_bits);
dump_regs(fp, regs, i == 0);
}
bi_disasm_fma(fp, instrs[i].fma_bits, &regs, &next_regs, header.datareg, offset, &consts, i == 0);
bi_disasm_add(fp, instrs[i].add_bits, &regs, &next_regs, header.datareg, offset, &consts, i == 0);
bi_disasm_fma(fp, instrs[i].fma_bits, &regs, &next_regs, header.datareg,
offset, &consts, i + 1 == num_instrs);
bi_disasm_add(fp, instrs[i].add_bits, &regs, &next_regs, header.datareg,
offset, &consts, i + 1 == num_instrs);
}
fprintf(fp, "}\n");

View File

@ -64,7 +64,7 @@ def decode_op(instructions, is_fma):
# Generate checks in order
template = """void
bi_disasm_${unit}(FILE *fp, unsigned bits, struct bifrost_regs *srcs, struct bifrost_regs *next_regs, unsigned staging_register, unsigned branch_offset, struct bi_constants *consts, bool first)
bi_disasm_${unit}(FILE *fp, unsigned bits, struct bifrost_regs *srcs, struct bifrost_regs *next_regs, unsigned staging_register, unsigned branch_offset, struct bi_constants *consts, bool last)
{
% for (i, (name, (emask, ebits), derived)) in enumerate(options):
% if len(derived) > 0:
@ -76,7 +76,7 @@ bi_disasm_${unit}(FILE *fp, unsigned bits, struct bifrost_regs *srcs, struct bif
% else:
${"else " if i > 0 else ""}if (unlikely(((bits & ${hex(emask)}) == ${hex(ebits)})))
% endif
bi_disasm_${name}(fp, bits, srcs, next_regs, staging_register, branch_offset, consts, first);
bi_disasm_${name}(fp, bits, srcs, next_regs, staging_register, branch_offset, consts, last);
% endfor
else
fprintf(fp, "INSTR_INVALID_ENC ${unit} %X\\n", bits);
@ -89,7 +89,7 @@ bi_disasm_${unit}(FILE *fp, unsigned bits, struct bifrost_regs *srcs, struct bif
# state. Sync prototypes to avoid moves when calling.
disasm_op_template = Template("""static void
bi_disasm_${c_name}(FILE *fp, unsigned bits, struct bifrost_regs *srcs, struct bifrost_regs *next_regs, unsigned staging_register, unsigned branch_offset, struct bi_constants *consts, bool first)
bi_disasm_${c_name}(FILE *fp, unsigned bits, struct bifrost_regs *srcs, struct bifrost_regs *next_regs, unsigned staging_register, unsigned branch_offset, struct bi_constants *consts, bool last)
{
${body.strip()}
}
@ -316,7 +316,7 @@ def disasm_op(name, op):
body += disasm_mod(mod, skip_mods)
body += ' fputs(" ", fp);\n'
body += ' bi_disasm_dest_{}(fp, next_regs, first);\n'.format('fma' if is_fma else 'add')
body += ' bi_disasm_dest_{}(fp, next_regs, last);\n'.format('fma' if is_fma else 'add')
# Next up, each source. Source modifiers are inserterd here