vc4: Fix totally broken assertions about inter-instruction reg conflicts.
authorEric Anholt <eric@anholt.net>
Wed, 20 Aug 2014 21:20:17 +0000 (14:20 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 22 Aug 2014 17:16:57 +0000 (10:16 -0700)
The spec citation talked about A and B, and I proceeded to pay no
attention to whether the waddrs were for A or B.  As a result, this pair
of instructions would claim to conflict:

mov ra4, ra4 ; nop nop, r0, r0
mov.ns ra4, rb4 ; nop nop, r0, r0

src/gallium/drivers/vc4/vc4_qpu_validate.c

index b9f28528c399d373b796a9da4da59f6d8b0c584d..d0437332334d463b7aa52a3ac8e6e5e906e07432 100644 (file)
@@ -69,6 +69,12 @@ reads_a_reg(uint64_t inst, uint32_t r)
         return _reads_reg(inst, r, false, true);
 }
 
+static bool
+reads_b_reg(uint64_t inst, uint32_t r)
+{
+        return _reads_reg(inst, r, true, false);
+}
+
 static bool
 writes_sfu(uint64_t inst)
 {
@@ -167,10 +173,19 @@ vc4_qpu_validate(uint64_t *insts, uint32_t num_inst)
         for (int i = 0; i < num_inst - 1; i++) {
                 uint64_t inst = insts[i];
                 uint32_t add_waddr = QPU_GET_FIELD(inst, QPU_WADDR_ADD);
-                uint32_t mul_waddr = QPU_GET_FIELD(inst, QPU_WADDR_ADD);
+                uint32_t mul_waddr = QPU_GET_FIELD(inst, QPU_WADDR_MUL);
+                uint32_t waddr_a, waddr_b;
+
+                if (inst & QPU_WS) {
+                        waddr_b = add_waddr;
+                        waddr_a = mul_waddr;
+                } else {
+                        waddr_a = add_waddr;
+                        waddr_b = mul_waddr;
+                }
 
-                assert(add_waddr >= 32 || !reads_reg(insts[i + 1], add_waddr));
-                assert(mul_waddr >= 32 || !reads_reg(insts[i + 1], mul_waddr));
+                assert(waddr_a >= 32 || !reads_a_reg(insts[i + 1], waddr_a));
+                assert(waddr_b >= 32 || !reads_b_reg(insts[i + 1], waddr_b));
         }
 
         /* "After an SFU lookup instruction, accumulator r4 must not be read