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 */