+static int lightrec_test_preload_pc(struct lightrec_state *state, struct block *block)
+{
+ unsigned int i;
+ union code c;
+ u32 flags;
+
+ for (i = 0; i < block->nb_ops; i++) {
+ c = block->opcode_list[i].c;
+ flags = block->opcode_list[i].flags;
+
+ if (op_flag_sync(flags))
+ break;
+
+ switch (c.i.op) {
+ case OP_J:
+ case OP_JAL:
+ block->flags |= BLOCK_PRELOAD_PC;
+ return 0;
+
+ case OP_REGIMM:
+ switch (c.r.rt) {
+ case OP_REGIMM_BLTZAL:
+ case OP_REGIMM_BGEZAL:
+ block->flags |= BLOCK_PRELOAD_PC;
+ return 0;
+ default:
+ break;
+ }
+ fallthrough;
+ case OP_BEQ:
+ case OP_BNE:
+ case OP_BLEZ:
+ case OP_BGTZ:
+ if (!op_flag_local_branch(flags)) {
+ block->flags |= BLOCK_PRELOAD_PC;
+ return 0;
+ }
+
+ case OP_SPECIAL:
+ switch (c.r.op) {
+ case OP_SPECIAL_JALR:
+ if (c.r.rd) {
+ block->flags |= BLOCK_PRELOAD_PC;
+ return 0;
+ }
+ break;
+ case OP_SPECIAL_SYSCALL:
+ case OP_SPECIAL_BREAK:
+ block->flags |= BLOCK_PRELOAD_PC;
+ return 0;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+