From 52c6b46ab595f9ead8e5442e5e1485f972573694 Mon Sep 17 00:00:00 2001 From: dougchansan Date: Fri, 4 Sep 2026 14:01:12 -1000 Subject: [PATCH] Mirror DolRecomp's cycle_budget, and bump the CPU ABI to 4 DolRecomp added `s64 cycle_budget` immediately after `downcount` in its generated-code CPUState in f0a86be ("rewrite llvm backend"). GXRuntime's header mirrors that prefix by contract, but was never updated, so every field from `exram` onward sat eight bytes off between generated code and the chassis. The header already warns not to touch the mirrored prefix without a coordinated ABI bump, so take the bump here: GXRUNTIME_CPU_ABI_VERSION goes to 4. That makes the mismatch a clean load-time rejection instead of silent corruption, and it re-keys consumers that fold the CPU ABI into their module cache identity. Field order and offsets now match DolRecomp main exactly. --- GXRuntime/include/core/cpu.h | 7 ++++++- GXRuntime/tests/runtime_tests.c | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/GXRuntime/include/core/cpu.h b/GXRuntime/include/core/cpu.h index 65f316fc2d..e242b00259 100644 --- a/GXRuntime/include/core/cpu.h +++ b/GXRuntime/include/core/cpu.h @@ -30,7 +30,11 @@ extern "C" { // consumes and resets it (Dolphin chassis: per-dispatch flush into // ppc_state.downcount). Hosts that do not meter guest time may ignore it // (s64: it cannot wrap in any realistic session). -#define GXRUNTIME_CPU_ABI_VERSION 3u +// - ABI v4 adds `cycle_budget` directly after `downcount`, mirroring the +// field DolRecomp added to its generated-code CPUState in f0a86be. The +// prefix is shared with generated code, so the field must sit at the same +// offset on both sides; hosts that do not meter guest time may ignore it. +#define GXRUNTIME_CPU_ABI_VERSION 4u #define GXRUNTIME_CPU_ABI_DOLRECOMP_PREFIX 1u #define GXRUNTIME_CPU_ABI_EXTERNAL_POINTER_EXTENSION 1u @@ -153,6 +157,7 @@ struct CPUState { u32 ram_size; PPCExternalPointer external_pointer; s64 downcount; + s64 cycle_budget; u8* exram; u32 exram_size; PPCSPRRead spr_read; diff --git a/GXRuntime/tests/runtime_tests.c b/GXRuntime/tests/runtime_tests.c index de7d77dcb1..b974ad1444 100644 --- a/GXRuntime/tests/runtime_tests.c +++ b/GXRuntime/tests/runtime_tests.c @@ -27,7 +27,7 @@ #include #include -_Static_assert(GXRUNTIME_CPU_ABI_VERSION == 3u, +_Static_assert(GXRUNTIME_CPU_ABI_VERSION == 4u, "update runtime ABI tests when the CPU ABI changes"); _Static_assert(GXRUNTIME_CPU_ABI_DOLRECOMP_PREFIX == 1u, "GXRuntime generated-code prefix must stay explicit"); @@ -49,6 +49,10 @@ _Static_assert(offsetof(CPUState, downcount) > offsetof(CPUState, external_point "ABI v2 downcount must remain the tail field"); _Static_assert(sizeof(((CPUState*)0)->downcount) == 8u, "downcount is s64 so unconsumed charges cannot wrap"); +_Static_assert(offsetof(CPUState, cycle_budget) > offsetof(CPUState, downcount), + "ABI v4 cycle_budget must follow downcount"); +_Static_assert(sizeof(((CPUState*)0)->cycle_budget) == 8u, + "cycle_budget is s64 to match DolRecomp's generated-code prefix"); _Static_assert(offsetof(CPUState, spr_read) > offsetof(CPUState, exram_size), "ABI v3 callbacks must remain tail fields"); _Static_assert(offsetof(CPUState, cache_control) > offsetof(CPUState, spr_write),