pan/midgard: Add mir_upper_override helper
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 13 Nov 2019 02:22:53 +0000 (21:22 -0500)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 25 Dec 2019 00:23:02 +0000 (19:23 -0500)
Checks if we should emit a dest_override=upper, given a mask.

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

index 723406cdb46acead2a8a960fefdbd24b833513f3..92712dde92b69c429f86933c1ea2afb4e400e089 100644 (file)
@@ -534,6 +534,7 @@ uint16_t mir_to_bytemask(midgard_reg_mode mode, unsigned mask);
 uint16_t mir_bytemask(midgard_instruction *ins);
 uint16_t mir_round_bytemask_down(uint16_t mask, midgard_reg_mode mode);
 void mir_set_bytemask(midgard_instruction *ins, uint16_t bytemask);
+unsigned mir_upper_override(midgard_instruction *ins);
 
 /* MIR printing */
 
index 68b7f68c72bda65e36571bed43b74a30fc421b05..eba772e13b1ac82c180369a97091889d1d81eb9e 100644 (file)
@@ -416,6 +416,35 @@ mir_set_bytemask(midgard_instruction *ins, uint16_t bytemask)
         ins->mask = mir_from_bytemask(bytemask, mir_typesize(ins));
 }
 
+/* Checks if we should use an upper destination override, rather than the lower
+ * one in the IR. Returns zero if no, returns the bytes to shift otherwise */
+
+unsigned
+mir_upper_override(midgard_instruction *ins)
+{
+        /* If there is no override, there is no upper override, tautology */
+        if (ins->alu.dest_override == midgard_dest_override_none)
+                return 0;
+
+        /* Make sure we didn't already lower somehow */
+        assert(ins->alu.dest_override == midgard_dest_override_lower);
+
+        /* What is the mask in terms of currently? */
+        midgard_reg_mode type = mir_typesize(ins);
+
+        /* There are 16 bytes per vector, so there are (16/bytes)
+         * components per vector. So the magic half is half of
+         * (16/bytes), which simplifies to 8/bytes */
+
+        unsigned threshold = 8 / mir_bytes_for_mode(type);
+
+        /* How many components did we shift over? */
+        unsigned zeroes = __builtin_ctz(ins->mask);
+
+        /* Did we hit the threshold? */
+        return (zeroes >= threshold) ? threshold : 0;
+}
+
 /* Creates a mask of the components of a node read by an instruction, by
  * analyzing the swizzle with respect to the instruction's mask. E.g.:
  *