pan/bi: Support indirect jumps
We need that for blend shaders which are passed the return address
through r48.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7151>
diff --git a/src/panfrost/bifrost/bi_pack.c b/src/panfrost/bifrost/bi_pack.c
index 310216f..f6e18fc 100644
--- a/src/panfrost/bifrost/bi_pack.c
+++ b/src/panfrost/bifrost/bi_pack.c
@@ -611,18 +611,25 @@
/* EQ swap to NE */
bool slot_swapped = false;
- /* We assigned the constant slot to fetch the branch offset so we can
- * just passthrough here. We put in the HI slot to match the blob since
- * that's where the magic flags end up */
struct bifrost_branch pack = {
.src0 = bi_get_src(ins, regs, 0),
.src1 = (zero_ctrl << 1) | !slot_swapped,
- .src2 = BIFROST_SRC_FAU_HI,
.cond = BR_COND_EQ,
.size = BR_SIZE_ZERO,
.op = BIFROST_ADD_OP_BRANCH
};
+ if (ins->branch_target) {
+ /* We assigned the constant slot to fetch the branch offset so
+ * we can just passthrough here. We put in the HI slot to match
+ * the blob since that's where the magic flags end up
+ */
+ assert(!ins->src[2]);
+ pack.src2 = BIFROST_SRC_FAU_HI;
+ } else {
+ pack.src2 = bi_get_src(ins, regs, 2);
+ }
+
RETURN_PACKED(pack);
}
@@ -634,15 +641,22 @@
.src0 = BIFROST_SRC_FAU_LO,
.src1 = BIFROST_SRC_PASS_FMA,
- /* Offset, see above */
- .src2 = BIFROST_SRC_FAU_HI,
-
/* All ones in fact */
.cond = (BR_ALWAYS & 0x7),
.size = (BR_ALWAYS >> 3),
.op = BIFROST_ADD_OP_BRANCH
};
+ if (ins->branch_target) {
+ /* Offset is passed as a PC-relative offset through an
+ * embedded constant.
+ */
+ assert(!ins->src[2]);
+ pack.src2 = BIFROST_SRC_FAU_HI;
+ } else {
+ pack.src2 = bi_get_src(ins, regs, 2);
+ }
+
RETURN_PACKED(pack);
}
diff --git a/src/panfrost/bifrost/bi_schedule.c b/src/panfrost/bifrost/bi_schedule.c
index 3e615f0..3fd1dfb 100644
--- a/src/panfrost/bifrost/bi_schedule.c
+++ b/src/panfrost/bifrost/bi_schedule.c
@@ -228,8 +228,7 @@
u->constant_count = 1;
u->constants[0] = ins->constant.u64;
- /* No indirect jumps yet */
- if (ins->type == BI_BRANCH)
+ if (ins->type == BI_BRANCH && ins->branch_target)
u->branch_constant = true;
/* We always prefetch except unconditional branches */