From 9a5d462480d9d5d1f91fc7984a7f423dd6cd46a3 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 12 Nov 2019 21:22:53 -0500 Subject: [PATCH] pan/midgard: Add mir_upper_override helper Checks if we should emit a dest_override=upper, given a mask. Signed-off-by: Alyssa Rosenzweig --- src/panfrost/midgard/compiler.h | 1 + src/panfrost/midgard/mir.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index 723406cdb46..92712dde92b 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -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 */ diff --git a/src/panfrost/midgard/mir.c b/src/panfrost/midgard/mir.c index 68b7f68c72b..eba772e13b1 100644 --- a/src/panfrost/midgard/mir.c +++ b/src/panfrost/midgard/mir.c @@ -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.: * -- 2.30.2