freedreno/ir3: fix regmask for merged regs
authorRob Clark <robdclark@gmail.com>
Sat, 16 Mar 2019 15:45:16 +0000 (11:45 -0400)
committerRob Clark <robdclark@gmail.com>
Thu, 21 Mar 2019 13:13:05 +0000 (09:13 -0400)
On a6xx+ with half-regs conflicting with full-regs, the legalize pass
needs to set appropriate sync bits, such as (sy), on writes to full regs
that conflict with half regs, and visa-versa.

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

index 9169d2c15f3b23e96f4c1f32d212af9f362990f8..23b12a6fc5f2d064060f1fdb63eda0fe9fa848a3 100644 (file)
@@ -35,6 +35,7 @@
 #include "util/u_math.h"
 
 #include "instr-a3xx.h"
+#include "ir3_compiler.h"
 
 /* simple allocator to carve allocations out of an up-front allocated heap,
  * so that we can free everything easily in one shot.
@@ -899,6 +900,8 @@ static struct ir3_register * reg_create(struct ir3 *shader,
        reg->wrmask = 1;
        reg->flags = flags;
        reg->num = num;
+       if (shader->compiler->gpu_id >= 600)
+               reg->merged = true;
        return reg;
 }
 
index 4bd7601b8dd4f79b9d1e24e8970b72ebb3eb12ac..b42524d22ae7ee7a4b1acecf88f676b4ec6b63d1 100644 (file)
@@ -98,11 +98,13 @@ struct ir3_register {
 
        } flags;
 
+       bool merged : 1;    /* half-regs conflict with full regs (ie >= a6xx) */
+
        /* normal registers:
         * the component is in the low two bits of the reg #, so
         * rN.x becomes: (N << 2) | x
         */
-       int   num;
+       uint16_t num;
        union {
                /* immediate: */
                int32_t  iim_val;
@@ -1426,8 +1428,13 @@ static inline unsigned regmask_idx(struct ir3_register *reg)
 {
        unsigned num = (reg->flags & IR3_REG_RELATIV) ? reg->array.offset : reg->num;
        debug_assert(num < MAX_REG);
-       if (reg->flags & IR3_REG_HALF)
-               num += MAX_REG;
+       if (reg->flags & IR3_REG_HALF) {
+               if (reg->merged) {
+                       num /= 2;
+               } else {
+                       num += MAX_REG;
+               }
+       }
        return num;
 }