Mesa (master): freedreno/ir3: regmask support for relative addr

Rob Clark robclark at kemper.freedesktop.org
Thu Jan 8 00:38:21 UTC 2015


Module: Mesa
Branch: master
Commit: dddfe6c21ee92f015b78060545f08239c331ceba
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=dddfe6c21ee92f015b78060545f08239c331ceba

Author: Rob Clark <robclark at freedesktop.org>
Date:   Fri Jan  2 13:44:26 2015 -0500

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 <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/ir3/ir3.h      |   66 +++++++++++++++++++-------
 src/gallium/drivers/freedreno/ir3/ir3_dump.c |    2 +-
 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 ad1e730..bd0c0a5 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 60be64c..e4a13f9 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");




More information about the mesa-commit mailing list