summaryrefslogtreecommitdiffstats
path: root/src/panfrost/midgard
diff options
context:
space:
mode:
Diffstat (limited to 'src/panfrost/midgard')
-rw-r--r--src/panfrost/midgard/compiler.h7
-rw-r--r--src/panfrost/midgard/midgard_ra.c52
2 files changed, 48 insertions, 11 deletions
diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h
index abe8b3e90c5..804180e571a 100644
--- a/src/panfrost/midgard/compiler.h
+++ b/src/panfrost/midgard/compiler.h
@@ -454,9 +454,10 @@ struct ra_graph;
#define NR_REG_CLASSES 3
-#define REG_CLASS_WORK 0
-#define REG_CLASS_LDST 1
-#define REG_CLASS_TEX 2
+#define REG_CLASS_WORK 0
+#define REG_CLASS_LDST 1
+#define REG_CLASS_LDST27 2
+#define REG_CLASS_TEX 3
void mir_lower_special_reads(compiler_context *ctx);
struct ra_graph* allocate_registers(compiler_context *ctx, bool *spilled);
diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c
index dc3d22883ab..19c60f4b05d 100644
--- a/src/panfrost/midgard/midgard_ra.c
+++ b/src/panfrost/midgard/midgard_ra.c
@@ -44,6 +44,7 @@
*/
#define WORK_STRIDE 10
+#define SHADOW_R27 17
/* Prepacked masks/swizzles for virtual register types */
static unsigned reg_type_to_mask[WORK_STRIDE] = {
@@ -146,6 +147,11 @@ index_to_reg(compiler_context *ctx, struct ra_graph *g, int reg)
int phys = virt / WORK_STRIDE;
int type = virt % WORK_STRIDE;
+ /* Apply shadow registers */
+
+ if (phys == SHADOW_R27)
+ phys = 27;
+
struct phys_reg r = {
.reg = phys,
.mask = reg_type_to_mask[type],
@@ -184,12 +190,16 @@ create_register_set(unsigned work_count, unsigned *classes)
classes[4*c + 2] = work_vec3;
classes[4*c + 3] = work_vec4;
- /* Special register classes have two registers in them */
- unsigned count = (c == REG_CLASS_WORK) ? work_count : 2;
+ /* Special register classes have other register counts */
+ unsigned count =
+ (c == REG_CLASS_WORK) ? work_count :
+ (c == REG_CLASS_LDST27) ? 1 : 2;
+ /* We arbitraily pick r17 (RA unused) as the shadow for r27 */
unsigned first_reg =
- (c == REG_CLASS_LDST) ? 26 :
- (c == REG_CLASS_TEX) ? 28 : 0;
+ (c == REG_CLASS_LDST) ? 26 :
+ (c == REG_CLASS_LDST27) ? SHADOW_R27 :
+ (c == REG_CLASS_TEX) ? 28 : 0;
/* Add the full set of work registers */
for (unsigned i = first_reg; i < (first_reg + count); ++i) {
@@ -221,6 +231,21 @@ create_register_set(unsigned work_count, unsigned *classes)
}
}
+
+ /* All of the r27 registers in in LDST conflict with all of the
+ * registers in LD27 (pseudo/shadow register) */
+
+ for (unsigned a = 0; a < WORK_STRIDE; ++a) {
+ unsigned reg_a = (WORK_STRIDE * 27) + a;
+
+ for (unsigned b = 0; b < WORK_STRIDE; ++b) {
+ unsigned reg_b = (WORK_STRIDE * SHADOW_R27) + b;
+
+ ra_add_reg_conflict(regs, reg_a, reg_b);
+ ra_add_reg_conflict(regs, reg_b, reg_a);
+ }
+ }
+
/* We're done setting up */
ra_set_finalize(regs, NULL);
@@ -276,12 +301,19 @@ set_class(unsigned *classes, unsigned node, unsigned class)
if (class == current_class)
return;
+
+ if ((current_class == REG_CLASS_LDST27) && (class == REG_CLASS_LDST))
+ return;
+
/* If we're changing, we must not have already assigned a special class
*/
- assert(current_class == REG_CLASS_WORK);
- assert(REG_CLASS_WORK == 0);
+ bool compat = current_class == REG_CLASS_WORK;
+ compat |= (current_class == REG_CLASS_LDST) && (class == REG_CLASS_LDST27);
+
+ assert(compat);
+ classes[node] &= 0x3;
classes[node] |= (class << 2);
}
@@ -299,6 +331,7 @@ check_read_class(unsigned *classes, unsigned tag, unsigned node)
switch (current_class) {
case REG_CLASS_LDST:
+ case REG_CLASS_LDST27:
return (tag == TAG_LOAD_STORE_4);
default:
return (tag != TAG_LOAD_STORE_4);
@@ -476,8 +509,11 @@ allocate_registers(compiler_context *ctx, bool *spilled)
/* Check if this operation imposes any classes */
if (ins->type == TAG_LOAD_STORE_4) {
- set_class(found_class, ins->ssa_args.src0, REG_CLASS_LDST);
- set_class(found_class, ins->ssa_args.src1, REG_CLASS_LDST);
+ bool force_r27 = OP_IS_R27_ONLY(ins->load_store.op);
+ unsigned class = force_r27 ? REG_CLASS_LDST27 : REG_CLASS_LDST;
+
+ set_class(found_class, ins->ssa_args.src0, class);
+ set_class(found_class, ins->ssa_args.src1, class);
}
}