panfrost/midgard: Disambiguate register mode
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 5 Jun 2019 22:43:52 +0000 (15:43 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 10 Jun 2019 13:50:12 +0000 (06:50 -0700)
We postfix instructions by their size if a destination override is in
place (a la AT&T assembly), disambiguating instruction sizes.
Previously, "16-bit instruction, 16-bit dest, 16-bit sources"
disassembled identically to "32-bit instruction, 16-bit dest, 16-bit
sources", which is semantically distinct due to the lessened opportunity
for parallelism but (potentially) greater precision. Adding a postfix
removes the ambiguity and relieves mental gymnastics reading weird
disassemblies even in some cases that are not ambiguous.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/midgard/disassemble.c

index c02387d..3d4a56f 100644 (file)
@@ -470,14 +470,25 @@ print_vector_field(const char *name, uint16_t *words, uint16_t reg_word,
         midgard_reg_info *reg_info = (midgard_reg_info *)&reg_word;
         midgard_vector_alu *alu_field = (midgard_vector_alu *) words;
         midgard_reg_mode mode = alu_field->reg_mode;
+        unsigned override = alu_field->dest_override;
 
         /* For now, prefix instruction names with their unit, until we
          * understand how this works on a deeper level */
         printf("%s.", name);
 
         print_alu_opcode(alu_field->op);
+
+        /* Postfix with the size to disambiguate if necessary */
+        char postfix = prefix_for_bits(bits_for_mode(mode));
+        bool size_ambiguous = override != midgard_dest_override_none;
+
+        if (size_ambiguous)
+                printf("%c", postfix ? postfix : 'r');
+
+        /* Print the outmod, if there is one */
         print_outmod(alu_field->outmod,
                 midgard_is_integer_out_op(alu_field->op));
+
         printf(" ");
 
         /* Mask denoting status of 8-lanes */
@@ -488,7 +499,6 @@ print_vector_field(const char *name, uint16_t *words, uint16_t reg_word,
                 print_dest(reg_info->out_reg, mode, alu_field->dest_override);
 
         /* Apply the destination override to the mask */
-        unsigned override = alu_field->dest_override;
 
         if (mode == midgard_reg_mode_32 || mode == midgard_reg_mode_64) {
                 if (override == midgard_dest_override_lower)