X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fpanfrost%2Fbifrost%2Fbi_layout.c;h=c00cdc760fe0c45aa1ede077f6aa98afb802ada2;hb=c9bb5dc911a1de4a1178af458babcaaa64998327;hp=1c700b138401df6c7a574abea0713fe5568676ba;hpb=b3ae088b96d9242d7d0fabde0516ccd76279ffd5;p=mesa.git diff --git a/src/panfrost/bifrost/bi_layout.c b/src/panfrost/bifrost/bi_layout.c index 1c700b13840..c00cdc760fe 100644 --- a/src/panfrost/bifrost/bi_layout.c +++ b/src/panfrost/bifrost/bi_layout.c @@ -89,3 +89,74 @@ bi_clause_quadwords(bi_clause *clause) return Y + DIV_ROUND_UP(constants, 2); } + +/* Measures the number of quadwords a branch jumps. Bifrost relative offsets + * are from the beginning of a clause so to jump forward we count the current + * clause length, but to jump backwards we do not. */ + +signed +bi_block_offset(bi_context *ctx, bi_clause *start, bi_block *target) +{ + /* Signed since we might jump backwards */ + signed ret = 0; + + /* Determine if the block we're branching to is strictly greater in + * source order */ + bool forwards = target->base.name > start->block->base.name; + + if (forwards) { + /* We have to jump through this block from the start of this + * clause to the end */ + bi_foreach_clause_in_block_from(start->block, clause, start) { + ret += bi_clause_quadwords(clause); + } + + /* We then need to jump through every clause of every following + * block until the target */ + bi_foreach_block_from(ctx, start->block, _blk) { + bi_block *blk = (bi_block *) _blk; + + /* Don't double-count the first block */ + if (blk == start->block) + continue; + + /* End just before the target */ + if (blk == target) + break; + + /* Count every clause in the block */ + bi_foreach_clause_in_block(blk, clause) { + ret += bi_clause_quadwords(clause); + } + } + } else { + /* We start at the beginning of the clause but have to jump + * through the clauses before us in the block */ + bi_foreach_clause_in_block_from_rev(start->block, clause, start) { + if (clause == start) + continue; + + ret -= bi_clause_quadwords(clause); + } + + /* And jump back every clause of preceding blocks up through + * and including the target to get to the beginning of the + * target */ + bi_foreach_block_from_rev(ctx, start->block, _blk) { + bi_block *blk = (bi_block *) _blk; + + if (blk == start->block) + continue; + + bi_foreach_clause_in_block(blk, clause) { + ret -= bi_clause_quadwords(clause); + } + + /* End just after the target */ + if (blk == target) + break; + } + } + + return ret; +}