summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2015-01-02 13:44:26 -0500
committerRob Clark <[email protected]>2015-01-07 19:37:28 -0500
commitdddfe6c21ee92f015b78060545f08239c331ceba (patch)
treed2961d7bde4a2a802ce7387464a81e065b14f874 /src/gallium
parent9bb865b3cf5b283a877ef937919e62e7e71ad588 (diff)
freedreno/ir3: regmask support for relative addr
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3.h66
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_dump.c2
2 files changed, 51 insertions, 17 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h
index ad1e730ad4c..bd0c0a5b693 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3.h
@@ -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;
}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_dump.c b/src/gallium/drivers/freedreno/ir3/ir3_dump.c
index 60be64c0e5a..e4a13f9b4b8 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_dump.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_dump.c
@@ -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");