pan/bit: Add swizzles to round tests
[mesa.git] / src / panfrost / bifrost / bi_ra.c
index b30f0e7aceb3180ed5c930e0f717686a546492c8..0124bf5ebc96200a0714a8a3de8dd930de1867ed 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "compiler.h"
+#include "bi_print.h"
 #include "panfrost/util/lcra.h"
 #include "util/u_memory.h"
 
@@ -44,7 +45,7 @@ bi_compute_interference(bi_context *ctx, struct lcra_state *l)
                         if (ins->dest && (ins->dest < l->node_count)) {
                                 for (unsigned i = 1; i < l->node_count; ++i) {
                                         if (live[i])
-                                                lcra_add_node_interference(l, ins->dest, ins->writemask, i, live[i]);
+                                                lcra_add_node_interference(l, ins->dest, bi_writemask(ins), i, live[i]);
                                 }
                         }
 
@@ -89,6 +90,83 @@ bi_allocate_registers(bi_context *ctx, bool *success)
         return l;
 }
 
+static unsigned
+bi_reg_from_index(struct lcra_state *l, unsigned index, unsigned offset)
+{
+        /* Did we run RA for this index at all */
+        if (index >= l->node_count)
+                return index;
+
+        /* LCRA didn't bother solving this index (how lazy!) */
+        signed solution = l->solutions[index];
+        if (solution < 0)
+                return index;
+
+        assert((solution & 0x3) == 0);
+        unsigned reg = solution / 4;
+        reg += offset;
+
+        return BIR_INDEX_REGISTER | reg;
+}
+
+static void
+bi_adjust_src_ra(bi_instruction *ins, struct lcra_state *l, unsigned src)
+{
+        if (ins->src[src] >= l->node_count)
+                return;
+
+        bool vector = (bi_class_props[ins->type] & BI_VECTOR) && src == 0;
+        unsigned offset = 0;
+
+        if (vector) {
+                /* TODO: Do we do anything here? */
+        } else {
+                /* Use the swizzle as component select */
+                unsigned components = bi_get_component_count(ins, src);
+
+                nir_alu_type T = ins->src_types[src];
+                unsigned size = nir_alu_type_get_type_size(T);
+                /* TODO: 64-bit? */
+                unsigned components_per_word = MAX2(32 / size, 1);
+
+                for (unsigned i = 0; i < components; ++i) {
+                        unsigned off = ins->swizzle[src][i] / components_per_word;
+
+                        /* We can't cross register boundaries in a swizzle */
+                        if (i == 0)
+                                offset = off;
+                        else
+                                assert(off == offset);
+
+                        ins->swizzle[src][i] %= components_per_word;
+                }
+        }
+
+        ins->src[src] = bi_reg_from_index(l, ins->src[src], offset);
+}
+
+static void
+bi_adjust_dest_ra(bi_instruction *ins, struct lcra_state *l)
+{
+        if (ins->dest >= l->node_count)
+                return;
+
+        ins->dest = bi_reg_from_index(l, ins->dest, ins->dest_offset);
+        ins->dest_offset = 0;
+}
+
+static void
+bi_install_registers(bi_context *ctx, struct lcra_state *l)
+{
+        bi_foreach_instr_global(ctx, ins) {
+                bi_adjust_dest_ra(ins, l);
+
+                bi_foreach_src(ins, s)
+                        bi_adjust_src_ra(ins, l, s);
+        }
+}
+
 void
 bi_register_allocate(bi_context *ctx)
 {
@@ -108,5 +186,7 @@ bi_register_allocate(bi_context *ctx)
                 assert(success);
         } while(!success);
 
+        bi_install_registers(ctx, l);
+
         lcra_free(l);
 }