mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 10:19:47 -04:00
Fix overlay autocompile: missing cull-widen ABI symbols; PGXP hooks swallowed by #endif
Two bugs that together kept every mod-patched text page interpreted forever (the WipEout 3 framerate mod's 74 divergent pages -> ~0.5M interpreted block dispatches/sec in play): - The [[widescreen.cull.widen]] emitter writes psx_ws_cull_slt_widen / psx_ws_cull_slti_lower at configured sites, including in overlay-resident code, but the overlay dispatch preamble never defined them: every shard containing a widen site failed to link (undefined reference) and the autocompile pipeline reported compile-error for the whole region. Mirror both helpers into the preamble following the documented self-contained, byte-identical convention. - append_pgxp_hooks joins the hook onto the translated statement with a space; the block-cycles MULT/DIV/MFLO/MFHI translations end in `#endif`, and the preprocessor discards tokens after #endif (the "extra tokens" warning class) - so those hooks silently never ran. Give the hook its own line when the translation ends in a directive. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,13 @@ inline int16_t get_imm16(uint32_t i) { return (int16_t)(i & 0xFFFF); }
|
||||
* return early above translate_instruction's main dispatch and are likewise
|
||||
* unhooked (they are cull compares, not vertex moves; validation covers). */
|
||||
void append_pgxp_hooks(uint32_t instr, std::string& code) {
|
||||
/* A translation ending in a preprocessor directive (the block-cycles
|
||||
* muldiv wrappers end in `#endif`) would swallow an appended hook: the
|
||||
* preprocessor discards tokens after #endif (the "extra tokens at end of
|
||||
* #endif" warning class), so the MULT/DIV/MFLO/MFHI hooks silently never
|
||||
* ran. Give the hook its own line. */
|
||||
if (code.size() >= 6 && code.compare(code.size() - 6, 6, "#endif") == 0)
|
||||
code += "\n ";
|
||||
const uint32_t opcode = (instr >> 26) & 0x3F;
|
||||
const uint32_t rs = get_rs(instr);
|
||||
const uint32_t rt = get_rt(instr);
|
||||
|
||||
@@ -211,6 +211,23 @@ int psx_ws_cull_vxrange(uint32_t x, uint32_t imm) {
|
||||
return (((x + (uint32_t)margin) & 0xFFFFu) <
|
||||
(bound + 2u * (uint32_t)margin)) ? 1 : 0;
|
||||
}
|
||||
/* [[widescreen.cull.widen]] SLT-family helpers. The emitter writes these at
|
||||
* explicitly configured cull sites, INCLUDING in overlay-resident code, so
|
||||
* the DLL must define them or the shard fails to link (undefined reference ->
|
||||
* no native shard -> that mod-patched page runs interpreted forever). Same
|
||||
* contract as the funnel helpers above: self-contained on psx_ws_x_margin(),
|
||||
* identity at margin 0 (4:3), MUST stay byte-for-byte identical to the gpu.c
|
||||
* implementations. */
|
||||
int psx_ws_cull_slti_lower(uint32_t sx, uint32_t imm) {
|
||||
int32_t bound = (int32_t)(int16_t)(uint16_t)imm;
|
||||
return ((int32_t)sx < bound - psx_ws_x_margin()) ? 1 : 0;
|
||||
}
|
||||
int psx_ws_cull_slt_widen(uint32_t rs, uint32_t rt, int bound_is_rt) {
|
||||
const int32_t m = psx_ws_x_margin();
|
||||
const int32_t a = (int32_t)rs, b = (int32_t)rt;
|
||||
return bound_is_rt ? ((a < b + m) ? 1 : 0)
|
||||
: ((a + m < b) ? 1 : 0);
|
||||
}
|
||||
void psx_ws_sprite_tag(CPUState *cpu) {
|
||||
if (g_cbs.ws_sprite_tag) g_cbs.ws_sprite_tag(cpu);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user