From: Alyssa Rosenzweig Date: Wed, 12 Feb 2020 02:37:18 +0000 (-0500) Subject: pan/midgard: Imply next tags X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=57a84278fda2ce556905f800409658639d642962;p=mesa.git pan/midgard: Imply next tags As long as we can disambiguate a few edge cases, we can imply next tags entirely which cleans up the disassembly a fair bit (though not as much as implying tags entirely would -- we'll get there!) Signed-off-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/panfrost/midgard/disassemble.c b/src/panfrost/midgard/disassemble.c index adbe1c7c3ff..34b36af7134 100644 --- a/src/panfrost/midgard/disassemble.c +++ b/src/panfrost/midgard/disassemble.c @@ -1542,7 +1542,7 @@ disassemble_midgard(FILE *fp, uint8_t *code, size_t size, unsigned gpu_id, gl_sh while (i < num_words) { unsigned tag = words[i] & 0xF; unsigned next_tag = (words[i] >> 4) & 0xF; - fprintf(fp, "\t%X -> %X\n", tag, next_tag); + fprintf(fp, "\t%X\n", tag); unsigned num_quad_words = midgard_tag_props[tag].size; if (midg_tags[i] && midg_tags[i] != tag) { @@ -1553,7 +1553,27 @@ disassemble_midgard(FILE *fp, uint8_t *code, size_t size, unsigned gpu_id, gl_sh midg_tags[i] = tag; - /* Check the tag */ + /* Check the tag. The idea is to ensure that next_tag is + * *always* recoverable from the disassembly, such that we may + * safely omit printing next_tag. To show this, we first + * consider that next tags are semantically off-byone -- we end + * up parsing tag n during step n+1. So, we ensure after we're + * done disassembling the next tag of the final bundle is BREAK + * and warn otherwise. We also ensure that the next tag is + * never INVALID. Beyond that, since the last tag is checked + * outside the loop, we can check one tag prior. If equal to + * the current tag (which is unique), we're done. Otherwise, we + * print if that tag was > TAG_BREAK, which implies the tag was + * not TAG_BREAK or TAG_INVALID. But we already checked for + * TAG_INVALID, so it's just if the last tag was TAG_BREAK that + * we're silent. So we throw in a print for break-next on at + * the end of the bundle (if it's not the final bundle, which + * we already check for above), disambiguating this case as + * well. Hence in all cases we are unambiguous, QED. */ + + if (next_tag == TAG_INVALID) + fprintf(fp, "\t/* XXX: invalid next tag */\n"); + if (last_next_tag > TAG_BREAK && last_next_tag != tag) { fprintf(fp, "\t/* XXX: TAG ERROR sequence, got %s expexted %s */\n", midgard_tag_props[tag].name, @@ -1594,25 +1614,36 @@ disassemble_midgard(FILE *fp, uint8_t *code, size_t size, unsigned gpu_id, gl_sh break; } - if (next_tag == 1) - fprintf(fp, "\n"); - /* We are parsing per bundle anyway. Add before we start * breaking out so we don't miss the final bundle. */ midg_stats.bundle_count++; midg_stats.quadword_count += num_quad_words; - fprintf(fp, "\n"); - - unsigned next = (words[i] & 0xF0) >> 4; + /* Include a synthetic "break" instruction at the end of the + * bundle to signify that if, absent a branch, the shader + * execution will stop here. Stop disassembly at such a break + * based on a heuristic */ + + if (next_tag == TAG_BREAK) { + if (branch_forward) { + fprintf(fp, "break\n"); + } else { + fprintf(fp, "\n"); + break; + } + } - if (i < num_words && next == 1 && !branch_forward) - break; + fprintf(fp, "\n"); i += 4 * num_quad_words; } + if (last_next_tag != TAG_BREAK) { + fprintf(fp, "/* XXX: shader ended with tag %s */\n", + midgard_tag_props[last_next_tag].name); + } + free(midg_tags); /* We computed work_count as max_work_registers, so add one to get the