freedreno/ir3 better cat6 encoding detection
authorRob Clark <robdclark@gmail.com>
Fri, 15 Mar 2019 14:29:10 +0000 (10:29 -0400)
committerRob Clark <robdclark@gmail.com>
Thu, 21 Mar 2019 13:13:05 +0000 (09:13 -0400)
These two bits seem to be a better way to detect which encoding we are
looking at.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/freedreno/ir3/disasm-a3xx.c
src/freedreno/ir3/instr-a3xx.h

index b857b381212044e508aa47ea01276e87abaa3e88..7b2a773df469eee352ea857a282844f0fdaccddb 100644 (file)
@@ -827,10 +827,7 @@ static void print_instr_cat6_a6xx(struct disasm_ctx *ctx, instr_t *instr)
 
 static void print_instr_cat6(struct disasm_ctx *ctx, instr_t *instr)
 {
-       // TODO not sure if this is the best way to figure
-       // out if new vs old encoding, but it kinda seems
-       // to work:
-       if ((ctx->gpu_id >= 600) && (instr->cat6.opc == 0)) {
+       if (!is_cat6_legacy(instr, ctx->gpu_id)) {
                print_instr_cat6_a6xx(ctx, instr);
                if (debug & PRINT_VERBOSE)
                        fprintf(ctx->out, " NEW");
index 92d7de44d9f9ef6c7d07cc3f6530e849bec433e6..b0db28eb63583a07bfd8f896caaa75f0e770b9a3 100644 (file)
@@ -835,6 +835,28 @@ static inline bool instr_sat(instr_t *instr)
        }
 }
 
+/* We can probably drop the gpu_id arg, but keeping it for now so we can
+ * assert if we see something we think should be new encoding on an older
+ * gpu.
+ */
+static inline bool is_cat6_legacy(instr_t *instr, unsigned gpu_id)
+{
+       instr_cat6_a6xx_t *cat6 = &instr->cat6_a6xx;
+
+       /* At least one of these two bits is pad in all the possible
+        * "legacy" cat6 encodings, and a analysis of all the pre-a6xx
+        * cmdstream traces I have indicates that the pad bit is zero
+        * in all cases.  So we can use this to detect new encoding:
+        */
+       if ((cat6->pad2 & 0x8) && (cat6->pad4 & 0x2)) {
+               assert(gpu_id >= 600);
+               assert(instr->cat6.opc == 0);
+               return false;
+       }
+
+       return true;
+}
+
 static inline uint32_t instr_opc(instr_t *instr, unsigned gpu_id)
 {
        switch (instr->opc_cat) {
@@ -845,10 +867,7 @@ static inline uint32_t instr_opc(instr_t *instr, unsigned gpu_id)
        case 4:  return instr->cat4.opc;
        case 5:  return instr->cat5.opc;
        case 6:
-               // TODO not sure if this is the best way to figure
-               // out if new vs old encoding, but it kinda seems
-               // to work:
-               if ((gpu_id >= 600) && (instr->cat6.opc == 0))
+               if (!is_cat6_legacy(instr, gpu_id))
                        return instr->cat6_a6xx.opc;
                return instr->cat6.opc;
        case 7:  return instr->cat7.opc;