diff options
author | Connor Abbott <cwabbott0@gmail.com> | 2021-05-28 16:03:16 +0200 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-07-08 16:02:41 +0000 |
commit | 2ff3ab0aed747cbb59d3b71ef459e70e9d346cdd (patch) | |
tree | 3181060aab579c12cf7b3431bb1fd2909a7f60a3 | |
parent | 66a275d50f8f7a431e3d9e6c38b64fa73a7e55ba (diff) |
ir3: Make MOVMSK use repeat
MOVMSK is a bit of a special case, because it takes multiple cycles (and
therefore reduces the nops needed if it's between some other assigner
and consumer) however weird things happen if you try to start reading
the first component while it isn't finished yet. On balance making it
use repeat seems to result in a fewer special cases.
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6752>
-rw-r--r-- | src/freedreno/ir3/ir3.h | 1 | ||||
-rw-r--r-- | src/freedreno/ir3/ir3_delay.c | 6 | ||||
-rw-r--r-- | src/freedreno/ir3/ir3_parser.y | 1 | ||||
-rw-r--r-- | src/freedreno/isa/ir3-cat1.xml | 10 |
4 files changed, 8 insertions, 10 deletions
diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 23762bd4936..9f9c0477d5d 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -1677,6 +1677,7 @@ ir3_MOVMSK(struct ir3_block *block, unsigned components) struct ir3_register *dst = __ssa_dst(instr); dst->flags |= IR3_REG_SHARED; dst->wrmask = (1 << components) - 1; + instr->repeat = components - 1; return instr; } diff --git a/src/freedreno/ir3/ir3_delay.c b/src/freedreno/ir3/ir3_delay.c index 006da3c6729..08fbf276646 100644 --- a/src/freedreno/ir3/ir3_delay.c +++ b/src/freedreno/ir3/ir3_delay.c @@ -247,6 +247,12 @@ delay_calc_srcn_postra(struct ir3_instruction *assigner, struct ir3_instruction if ((src->flags & IR3_REG_RELATIV) || (dst->flags & IR3_REG_RELATIV)) return delay; + /* MOVMSK seems to require that all users wait until the entire + * instruction is finished, so just bail here. + */ + if (assigner->opc == OPC_MOVMSK) + return delay; + /* TODO: Handle the combination of (rpt) and different component sizes * better like below. This complicates things significantly because the * components don't line up. diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index 47ca9eb0f59..ffc0f76b778 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -800,6 +800,7 @@ cat1_movmsk: T_OP_MOVMSK '.' T_W { new_instr(OPC_MOVMSK); instr->cat1.src_type = TYPE_U32; instr->cat1.dst_type = TYPE_U32; + instr->repeat = $3 - 1; } dst_reg { instr->dsts[0]->wrmask = (1 << $3) - 1; } diff --git a/src/freedreno/isa/ir3-cat1.xml b/src/freedreno/isa/ir3-cat1.xml index ed9fe59f016..384de201626 100644 --- a/src/freedreno/isa/ir3-cat1.xml +++ b/src/freedreno/isa/ir3-cat1.xml @@ -457,16 +457,6 @@ SOFTWARE. <pattern low="50" high="52">011</pattern> <!-- SRC_TYPE==u32 --> <pattern low="53" high="54">00</pattern> <pattern low="57" high="58">11</pattern> <!-- OPC --> - - <!-- - TODO in ir3 things are encoded w/ instr->repeat==0 and repeat field is - reconstructed from wrmask.. but I'm not sure if that is actually accurate - (in terms of how delay slots work).. for now, work around that to match - the existing stuff: - --> - <encode> - <map name="REPEAT">util_last_bit(src->dsts[0]->wrmask) - 1</map> - </encode> </bitset> |