Commit adf7c955 authored by Alyssa Rosenzweig's avatar Alyssa Rosenzweig 💜
Browse files

pan/va: Lower branch offsets



Logic is lifted from bi_layout.c, adapted to work on instructions (not
clauses) and for Valhall's off-by-one semantic which is annoyingly
different than Bifrost. (But the same as Midgard -- Bifrost was
annoyingly different than Midgard!)
Signed-off-by: Alyssa Rosenzweig's avatarAlyssa Rosenzweig <alyssa@collabora.com>
parent ef0c4d5f
......@@ -396,6 +396,77 @@ va_pack_action(bi_block *block, bi_instr *I)
return 0;
}
static unsigned
va_instructions_in_block(bi_block *block)
{
unsigned offset = 0;
bi_foreach_instr_in_block(block, _) {
offset++;
}
return offset;
}
/* Calculate branch_offset from a branch_target for a direct relative branch */
static void
va_lower_branch_target(bi_context *ctx, bi_block *start, bi_instr *I)
{
/* Precondition: unlowered relative branch */
bi_block *target = I->branch_target;
assert(target != NULL);
/* Signed since we might jump backwards */
signed offset = 0;
/* Determine if the target block is strictly greater in source order */
bool forwards = target->name > start->name;
if (forwards) {
/* We have to jump through this block */
bi_foreach_instr_in_block_from(start, _, I) {
offset++;
}
/* We then need to jump over every following block until the target */
bi_foreach_block_from(ctx, start, blk) {
/* End just before the target */
if (blk == target)
break;
/* Count other blocks */
if (blk != start)
offset += va_instructions_in_block(blk);
}
} else {
/* Jump through the beginning of this block */
bi_foreach_instr_in_block_from_rev(start, ins, I) {
if (ins != I)
offset--;
}
/* Jump over preceding blocks up to and including the target to get to
* the beginning of the target */
bi_foreach_block_from_rev(ctx, start, blk) {
if (blk == start)
continue;
offset -= va_instructions_in_block(blk);
/* End just after the target */
if (blk == target)
break;
}
}
/* Offset is relative to the next instruction, so bias */
offset--;
/* Update the instruction */
I->branch_offset = offset;
}
void
bi_pack_valhall(bi_context *ctx, struct util_dynarray *emission)
{
......@@ -403,6 +474,9 @@ bi_pack_valhall(bi_context *ctx, struct util_dynarray *emission)
bi_foreach_block(ctx, block) {
bi_foreach_instr_in_block(block, I) {
if (I->op == BI_OPCODE_BRANCHZ_I16)
va_lower_branch_target(ctx, block, I);
unsigned action = va_pack_action(block, I);
uint64_t hex = va_pack_instr(I, action);
util_dynarray_append(emission, uint64_t, hex);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment