freedreno/ir3: regmask support for relative addr
authorRob Clark <robclark@freedesktop.org>
Fri, 2 Jan 2015 18:44:26 +0000 (13:44 -0500)
committerRob Clark <robclark@freedesktop.org>
Thu, 8 Jan 2015 00:37:28 +0000 (19:37 -0500)
For temp arrays, a 32bit mask won't be sufficient.. but otoh we don't
need to support an arbitrary mask.  So for this case use a simple size
field rather than a bitmask.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/ir3.h
src/gallium/drivers/freedreno/ir3/ir3_dump.c

index ad1e730ad4c49180ae95e406d5a15af84cb567f2..bd0c0a5b69344c557b4b0aa44d758a2527594104 100644 (file)
@@ -91,12 +91,19 @@ struct ir3_register {
                struct ir3_instruction *instr;
        };
 
-       /* used for cat5 instructions, but also for internal/IR level
-        * tracking of what registers are read/written by an instruction.
-        * wrmask may be a bad name since it is used to represent both
-        * src and dst that touch multiple adjacent registers.
-        */
-       int wrmask;
+       union {
+               /* used for cat5 instructions, but also for internal/IR level
+                * tracking of what registers are read/written by an instruction.
+                * wrmask may be a bad name since it is used to represent both
+                * src and dst that touch multiple adjacent registers.
+                */
+               unsigned wrmask;
+               /* for relative addressing, 32bits for array size is too small,
+                * but otoh we don't need to deal with disjoint sets, so instead
+                * use a simple size field (number of scalar components).
+                */
+               unsigned size;
+       };
 };
 
 #define IR3_INSTR_SRCS 10
@@ -477,10 +484,23 @@ static inline void regmask_init(regmask_t *regmask)
 static inline void regmask_set(regmask_t *regmask, struct ir3_register *reg)
 {
        unsigned idx = regmask_idx(reg);
-       unsigned i;
-       for (i = 0; i < IR3_INSTR_SRCS; i++, idx++)
-               if (reg->wrmask & (1 << i))
+       if (reg->flags & IR3_REG_RELATIV) {
+               unsigned i;
+               for (i = 0; i < reg->size; i++, idx++)
                        (*regmask)[idx / 8] |= 1 << (idx % 8);
+       } else {
+               unsigned mask;
+               for (mask = reg->wrmask; mask; mask >>= 1, idx++)
+                       if (mask & 1)
+                               (*regmask)[idx / 8] |= 1 << (idx % 8);
+       }
+}
+
+static inline void regmask_or(regmask_t *dst, regmask_t *a, regmask_t *b)
+{
+       unsigned i;
+       for (i = 0; i < ARRAY_SIZE(*dst); i++)
+               (*dst)[i] = (*a)[i] | (*b)[i];
 }
 
 /* set bits in a if not set in b, conceptually:
@@ -490,22 +510,36 @@ static inline void regmask_set_if_not(regmask_t *a,
                struct ir3_register *reg, regmask_t *b)
 {
        unsigned idx = regmask_idx(reg);
-       unsigned i;
-       for (i = 0; i < IR3_INSTR_SRCS; i++, idx++)
-               if (reg->wrmask & (1 << i))
+       if (reg->flags & IR3_REG_RELATIV) {
+               unsigned i;
+               for (i = 0; i < reg->size; i++, idx++)
                        if (!((*b)[idx / 8] & (1 << (idx % 8))))
                                (*a)[idx / 8] |= 1 << (idx % 8);
+       } else {
+               unsigned mask;
+               for (mask = reg->wrmask; mask; mask >>= 1, idx++)
+                       if (mask & 1)
+                               if (!((*b)[idx / 8] & (1 << (idx % 8))))
+                                       (*a)[idx / 8] |= 1 << (idx % 8);
+       }
 }
 
-static inline unsigned regmask_get(regmask_t *regmask,
+static inline bool regmask_get(regmask_t *regmask,
                struct ir3_register *reg)
 {
        unsigned idx = regmask_idx(reg);
-       unsigned i;
-       for (i = 0; i < IR3_INSTR_SRCS; i++, idx++)
-               if (reg->wrmask & (1 << i))
+       if (reg->flags & IR3_REG_RELATIV) {
+               unsigned i;
+               for (i = 0; i < reg->size; i++, idx++)
                        if ((*regmask)[idx / 8] & (1 << (idx % 8)))
                                return true;
+       } else {
+               unsigned mask;
+               for (mask = reg->wrmask; mask; mask >>= 1, idx++)
+                       if (mask & 1)
+                               if ((*regmask)[idx / 8] & (1 << (idx % 8)))
+                                       return true;
+       }
        return false;
 }
 
index 60be64c0e5a7deef93dfad5000166b6f19464f88..e4a13f9b4b89ea14f7ab0911d77dbe6af18ca603 100644 (file)
@@ -134,7 +134,7 @@ static void dump_reg_name(struct ir3_dump_ctx *ctx,
                if (reg->flags & IR3_REG_CONST)
                        fprintf(ctx->f, "c<a0.x + %u>", reg->num);
                else
-                       fprintf(ctx->f, "\x1b[0;31mr<a0.x + %u>\x1b[0m", reg->num);
+                       fprintf(ctx->f, "\x1b[0;31mr<a0.x + %u>\x1b[0m (%u)", reg->num, reg->size);
        } else {
                if (reg->flags & IR3_REG_HALF)
                        fprintf(ctx->f, "h");