diff --git a/docs/internal/FAITHFUL_TIMING_PLAN.md b/docs/internal/FAITHFUL_TIMING_PLAN.md index 4986a09b..02436fcc 100644 --- a/docs/internal/FAITHFUL_TIMING_PLAN.md +++ b/docs/internal/FAITHFUL_TIMING_PLAN.md @@ -213,7 +213,7 @@ on a fixed region -> next. ## 5. Status / Log (update every session) -- **2026-10-21 (BRIEF-4 full-range work):** Reuse exact indexed 1555 page decoding and epoch lookup from `ab784091`/`341a3598`, restricted to raw VRAM-backed source/palette to avoid mutable bank-name reuse. Coherency writes and transaction restoration invalidate affected regions. Skip debug-only NCLIP hash-table receipts in production; retain culling math and summary counters. R4 failing quiet/loaded acceptance cases will be repeated after these fixes. +- **2026-10-21 (BRIEF-4 full-range work):** Removed the unsuccessful indexed-decode and PGXP ALU experiments after regressive full-circuit R4 measurements. Runtime source matches `4b2fdfad`: qualified far projection, material recording cache and opaque bloom fusion remain. R4 Stage 2 is not accepted (performance and reported-building visual gate open); Stage 1 remains pushed and accepted. See R4 `analysis/STATUS.md`. - **2026-10-21 (BRIEF-4 far projection):** Opt-in preserve-projection can recover IR-saturated X/Y from qualified unshifted MACs. A new intact-word tag requires validated GTE dataflow; modified words, half writes, cache fallback, lm sign clamps and accumulator/SZ overflow keep rejection. Guest registers and the faithful default are unchanged. R4 maximum-range visual/performance acceptance remains pending. diff --git a/runtime/src/gte.cpp b/runtime/src/gte.cpp index 566c586c..91d3faac 100644 --- a/runtime/src/gte.cpp +++ b/runtime/src/gte.cpp @@ -1368,7 +1368,6 @@ extern "C" int32_t gte_nclip_exact_sign(int32_t native_mac0, uint32_t pc) { const bool usable = s_nclip_exact_enabled && s_nclip_last_precise_valid && native_mac0 == s_nclip_last_native; const int32_t sign = usable ? s_nclip_last_precise_sign : native; -#ifndef PSX_NO_DEBUG_TOOLS if (!s_gte_replay_sandbox && s_speculative_depth == 0) { if (GteNclipSiteStat *e = nclip_find(s_nclip_site, pc, &GteNclipSiteStat::pc, @@ -1379,9 +1378,6 @@ extern "C" int32_t gte_nclip_exact_sign(int32_t native_mac0, uint32_t pc) { e->last_frame = (uint32_t)s_frame_count; } } -#else - (void)pc; -#endif return sign; } extern "C" int gte_nclip_native_wide_sign(int32_t native_mac0, int* sign) { @@ -1491,7 +1487,6 @@ void gte_nclip(GTEState* gte, uint32_t instr) { const bool disagree = (cross > 0 && out <= 0) || (cross < 0 && out >= 0); if (disagree) s_nclip_disagreements++; -#ifndef PSX_NO_DEBUG_TOOLS /* Last guest store before this NCLIP: codegen stamps it on every * store, so it lands inside the emitter that issued the NCLIP (the * function stamp is not maintained for static code). */ @@ -1507,7 +1502,6 @@ void gte_nclip(GTEState* gte, uint32_t instr) { e->saturated++; e->last_frame = (uint32_t)s_frame_count; } -#endif } else if (gpu_ws_precise_nclip_enabled() && !s_gte_replay_sandbox && s_speculative_depth == 0) { s_nclip_fallbacks++; diff --git a/runtime/src/pgxp.cpp b/runtime/src/pgxp.cpp index 33ed86e7..09e42ab7 100644 --- a/runtime/src/pgxp.cpp +++ b/runtime/src/pgxp.cpp @@ -1182,51 +1182,10 @@ static int alu_scalar(uint32_t instr, uint32_t result, uint32_t s1, uint32_t s2, static void alu_halves(uint32_t instr, uint32_t result, uint32_t s1, uint32_t s2); -/* Keep the memory-only fast path out of each generated instruction body. - * GCC LTO otherwise partially inlines/specializes it across the large title, - * increasing the hot code footprint instead of reducing instruction work. */ -extern "C" -#if defined(PSX_NO_DEBUG_TOOLS) && defined(__GNUC__) && !defined(__clang__) -__attribute__((noinline, noclone)) -#elif defined(PSX_NO_DEBUG_TOOLS) && defined(__clang__) -__attribute__((noinline)) -#elif defined(PSX_NO_DEBUG_TOOLS) && defined(_MSC_VER) -__declspec(noinline) -#endif -void psx_pgxp_alu(struct CPUState *cpu, uint32_t instr, +extern "C" void psx_pgxp_alu(struct CPUState *cpu, uint32_t instr, uint32_t result, uint32_t s1, uint32_t s2) { (void)cpu; if (!g_pgxp_active) return; -#ifdef PSX_NO_DEBUG_TOOLS - if (!s_cpu_mode) { - /* In memory-only mode these opcodes can only discard precision. - * An already-untracked destination needs no value/zero writes: every - * consumer requires live flags, and later tracking overwrites the - * complete shadow. Keep MOVE, bitwise repacking and LUI on the full - * path: they can carry/create exact halves even in memory-only mode. */ - const uint32_t op = f_op(instr); - uint32_t target = f_rt(instr); - bool clears = ((op == 0x08 || op == 0x09) && f_simm(instr) != 0) || - op == 0x0A || op == 0x0B; - if (op == 0) { - const uint32_t fn = f_funct(instr); - target = f_rd(instr); - clears = fn == 0 || fn == 2 || fn == 3 || fn == 4 || fn == 6 || fn == 7 || - fn == 0x10 || fn == 0x12 || fn == 0x2A || fn == 0x2B || - ((fn == 0x20 || fn == 0x21) && f_rs(instr) && f_rt(instr)) || - ((fn == 0x22 || fn == 0x23) && f_rt(instr)); - if (fn == 0x11 || fn == 0x13) { - target = fn == 0x11 ? PGXP_REG_HI : PGXP_REG_LO; - clears = true; - } - } - if (clears) { - if (target && s_gpr[target].gen == s_gen && s_gpr[target].flags) - pv_reset(&s_gpr[target], result); - return; - } - } -#endif int dst = -1; double v = 0.0; const int has = s_cpu_mode && alu_scalar(instr, result, s1, s2, &dst, &v);