Skip to content

Commit ffeaddc

Browse files
committed
Codegen: add continuation re-entry loop for nested callee yields
When a callee yields at an internal continuation PC, the caller now re-enters it in a while loop until it exits to the real fallthrough. Prevents nested continuations from leaking as false PC_MISMATCH.
1 parent ab0832d commit ffeaddc

1 file changed

Lines changed: 30 additions & 3 deletions

File tree

ps2xRecomp/src/lib/code_generator.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,17 @@ namespace ps2recomp
387387
{
388388
ss << " const uint32_t __entryPc = ctx->pc;\n";
389389
ss << " targetFn(rdram, ctx, runtime);\n";
390+
ss << fmt::format(" while (runtime->hasFunction(ctx->pc) && runtime->lookupFunction(ctx->pc) == targetFn) {{\n");
391+
ss << " const uint32_t __resumePc = ctx->pc;\n";
392+
ss << fmt::format(" if (__resumePc == 0x{:X}u) {{ break; }}\n", fallthroughPc);
393+
ss << " targetFn(rdram, ctx, runtime);\n";
394+
ss << fmt::format(" if (ctx->pc == __resumePc) {{ ctx->pc = 0x{:X}u; break; }}\n", fallthroughPc);
395+
ss << " }\n";
390396
ss << fmt::format(" if (ctx->pc == __entryPc) {{ ctx->pc = 0x{:X}u; }}\n", fallthroughPc);
391-
ss << fmt::format(" if (ctx->pc != 0x{:X}u) {{ fprintf(stderr, \"[PC_MISMATCH] at 0x{:X}: called 0x%x, expected ret 0x{:X}, got 0x%x\\n\", __entryPc, ctx->pc); return; }}\n", fallthroughPc, branchInst.address, fallthroughPc);
397+
ss << fmt::format(" if (ctx->pc != 0x{:X}u) {{\n", fallthroughPc);
398+
ss << fmt::format(" fprintf(stderr, \"[PC_MISMATCH] at 0x{:X}: called 0x%x, expected ret 0x{:X}, got 0x%x\\n\", __entryPc, ctx->pc);\n", branchInst.address, fallthroughPc);
399+
ss << " return;\n";
400+
ss << " }\n";
392401
}
393402
ss << " }\n";
394403
}
@@ -439,8 +448,17 @@ namespace ps2recomp
439448
}
440449
else
441450
{
451+
ss << fmt::format(" while (runtime->hasFunction(ctx->pc) && runtime->lookupFunction(ctx->pc) == targetFn) {{\n");
452+
ss << " const uint32_t __resumePc = ctx->pc;\n";
453+
ss << fmt::format(" if (__resumePc == 0x{:X}u) {{ break; }}\n", fallthroughPc);
454+
ss << " targetFn(rdram, ctx, runtime);\n";
455+
ss << fmt::format(" if (ctx->pc == __resumePc) {{ ctx->pc = 0x{:X}u; break; }}\n", fallthroughPc);
456+
ss << " }\n";
442457
ss << fmt::format(" if (ctx->pc == __entryPc) {{ ctx->pc = 0x{:X}u; }}\n", fallthroughPc);
443-
ss << fmt::format(" if (ctx->pc != 0x{:X}u) {{ fprintf(stderr, \"[PC_MISMATCH] at 0x{:X}: called 0x{:X}, expected ret 0x{:X}, got 0x%x\\n\", ctx->pc); return; }}\n", fallthroughPc, branchInst.address, target, fallthroughPc);
458+
ss << fmt::format(" if (ctx->pc != 0x{:X}u) {{\n", fallthroughPc);
459+
ss << fmt::format(" fprintf(stderr, \"[PC_MISMATCH] at 0x{:X}: called 0x{:X}, expected ret 0x{:X}, got 0x%x\\n\", ctx->pc);\n", branchInst.address, target, fallthroughPc);
460+
ss << " return;\n";
461+
ss << " }\n";
444462
}
445463
ss << " }\n";
446464
}
@@ -497,8 +515,17 @@ namespace ps2recomp
497515
ss << " auto targetFn = runtime->lookupFunction(jumpTarget);\n";
498516
ss << " const uint32_t __entryPc = ctx->pc;\n";
499517
ss << " targetFn(rdram, ctx, runtime);\n";
518+
ss << fmt::format(" while (runtime->hasFunction(ctx->pc) && runtime->lookupFunction(ctx->pc) == targetFn) {{\n");
519+
ss << " const uint32_t __resumePc = ctx->pc;\n";
520+
ss << fmt::format(" if (__resumePc == 0x{:X}u) {{ break; }}\n", fallthroughPc);
521+
ss << " targetFn(rdram, ctx, runtime);\n";
522+
ss << fmt::format(" if (ctx->pc == __resumePc) {{ ctx->pc = 0x{:X}u; break; }}\n", fallthroughPc);
523+
ss << " }\n";
500524
ss << fmt::format(" if (ctx->pc == __entryPc) {{ ctx->pc = 0x{:X}u; }}\n", fallthroughPc);
501-
ss << fmt::format(" if (ctx->pc != 0x{:X}u) {{ fprintf(stderr, \"[PC_MISMATCH] at 0x{:X}: jalr 0x%x, expected ret 0x{:X}, got 0x%x\\n\", __entryPc, ctx->pc); return; }}\n", fallthroughPc, branchInst.address, fallthroughPc);
525+
ss << fmt::format(" if (ctx->pc != 0x{:X}u) {{\n", fallthroughPc);
526+
ss << fmt::format(" fprintf(stderr, \"[PC_MISMATCH] at 0x{:X}: jalr 0x%x, expected ret 0x{:X}, got 0x%x\\n\", __entryPc, ctx->pc);\n", branchInst.address, fallthroughPc);
527+
ss << " return;\n";
528+
ss << " }\n";
502529
ss << " }\n";
503530
}
504531

0 commit comments

Comments
 (0)