pan/midgard: Track csel swizzle
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 30 Aug 2019 17:42:05 +0000 (10:42 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 30 Aug 2019 22:50:24 +0000 (15:50 -0700)
While it doesn't matter with an unconditional move to the conditional
register (r31), when we try to elide that move we'll need to track the
swizzle explicitly, and there is no slot for that yet since ALU ops are
normally binary.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/panfrost/midgard/compiler.h
src/panfrost/midgard/midgard_compile.c

index 7747764791f15985c75cb8e0ace954177644c096..0c9d329c6bff51069fd99ac01fd1f85887fbd7dd 100644 (file)
@@ -88,6 +88,9 @@ typedef struct midgard_instruction {
         unsigned src[3];
         unsigned dest;
 
+        /* Swizzle for the conditional for a csel */
+        unsigned csel_swizzle;
+
         /* Special fields for an ALU instruction */
         midgard_reg_info registers;
 
index eaa5816cc7e27bc0ebc97f6218e0e9fc59bb05f8..765eab36d86a011c2c04d191b3841bf27981419e 100644 (file)
@@ -1011,7 +1011,8 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
          * needs it, or else we may segfault. */
 
         unsigned src0 = nir_alu_src_index(ctx, &instr->src[0]);
-        unsigned src1 = nr_inputs == 2 ? nir_alu_src_index(ctx, &instr->src[1]) : ~0;
+        unsigned src1 = nr_inputs >= 2 ? nir_alu_src_index(ctx, &instr->src[1]) : ~0;
+        unsigned src2 = nr_inputs == 3 ? nir_alu_src_index(ctx, &instr->src[2]) : ~0;
 
         /* Rather than use the instruction generation helpers, we do it
          * ourselves here to avoid the mess */
@@ -1021,14 +1022,14 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
                 .src = {
                         quirk_flipped_r24 ? ~0 : src0,
                         quirk_flipped_r24 ? src0       : src1,
-                        ~0
+                        src2,
                 },
                 .dest = dest,
         };
 
-        nir_alu_src *nirmods[2] = { NULL };
+        nir_alu_src *nirmods[3] = { NULL };
 
-        if (nr_inputs == 2) {
+        if (nr_inputs >= 2) {
                 nirmods[0] = &instr->src[0];
                 nirmods[1] = &instr->src[1];
         } else if (nr_inputs == 1) {
@@ -1037,6 +1038,9 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
                 assert(0);
         }
 
+        if (nr_inputs == 3)
+                nirmods[2] = &instr->src[2];
+
         /* These were lowered to a move, so apply the corresponding mod */
 
         if (instr->op == nir_op_fneg || instr->op == nir_op_fabs) {
@@ -1063,6 +1067,12 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
                 .src2 = vector_alu_srco_unsigned(vector_alu_modifiers(nirmods[1], is_int, broadcast_swizzle, half_2, sext_2)),
         };
 
+        if (nr_inputs == 3) {
+                ins.csel_swizzle = SWIZZLE_FROM_ARRAY(nirmods[2]->swizzle);
+                assert(!nirmods[2]->abs);
+                assert(!nirmods[2]->negate);
+        }
+
         /* Apply writemask if non-SSA, keeping in mind that we can't write to components that don't exist */
 
         if (!is_ssa)