mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-28 02:56:36 -04:00
feat(timing): ruler #2 foundation — cycle micro-benchmark test ROM + universal block observe
Ruler #2 (the in-tree cycle-model integration-test ecosystem): - tools/cycle_testrom/gen_testrom.py: hand-encoded MIPS PS-X EXE of cycle- isolation loops (baseline/alu/load/load2/div/div_spaced/mult). Each loop top is a block leader, so a cyc_watch single-anchor Δ = one iteration; baseline subtraction isolates each component (overhead + fetch cancel). Encoding validated by a clean recompile (divu -> gpr[10]/gpr[11], etc.). - game.toml/seeds.txt/README.md; .gitignore for the regenerable EXE/json/generated. Universal per-block-leader observe: - Added debug_server_cyc_observe at every block leader in the GAME emitter (code_generator.cpp) to match the BIOS emitter, so ANY recompiled code (game, BIOS, overlay) is anchorable on both backends — not just function entries. #ifndef PSX_NO_DEBUG_TOOLS so prod = zero overhead. Regression-checked: regen Tomba 2 + rebuild, FMV still streams (i_stat 0x8D), no visual regression. Builds clean. Remaining for ruler #2: native test-runtime delivery (boot->entry handoff) + Beetle .exe sideload + the per-component compare harness (see README TODO). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1179,6 +1179,16 @@ std::string CodeGenerator::translate_basic_block(
|
||||
// Block label
|
||||
ss << fmt::format("block_{:08X}:\n", block.start_addr);
|
||||
|
||||
// Per-block-leader cycle observe (cyc_watch ruler — universal with the BIOS
|
||||
// emitter). Sampled at the block leader BEFORE any cycle is charged, matching
|
||||
// Beetle's before-instruction sample and the cycle_compare.py anchor
|
||||
// semantics, so ANY block-leader PC is anchorable on both backends (not just
|
||||
// function entries). Debug-only: prod (PSX_NO_DEBUG_TOOLS) emits nothing.
|
||||
ss << "#ifndef PSX_NO_DEBUG_TOOLS\n";
|
||||
ss << config_.indent
|
||||
<< fmt::format("debug_server_cyc_observe(0x{:08X}u);\n", block.start_addr);
|
||||
ss << "#endif\n";
|
||||
|
||||
// Cycle-budgeted precise event slicing (PRECISE_IRQ_SLICE.md). At the block
|
||||
// leader — before any cycle is charged or the body runs — divert to the
|
||||
// per-instruction interpreter when an interrupt could be taken inside this
|
||||
@@ -2322,6 +2332,9 @@ std::string CodeGenerator::generate_file(
|
||||
// This provides CPUState, GTE/trap declarations, and call_by_address().
|
||||
ss << "#include \"psx_runtime.h\"\n\n";
|
||||
ss << "extern void debug_server_log_call_entry(uint32_t func_addr);\n";
|
||||
ss << "#ifndef PSX_NO_DEBUG_TOOLS\n";
|
||||
ss << "extern void debug_server_cyc_observe(uint32_t block_leader_phys);\n";
|
||||
ss << "#endif\n";
|
||||
ss << "extern void psx_ws_sprite_tag(CPUState* cpu); /* widescreen prim tag (gpu.c) */\n";
|
||||
ss << "extern int psx_ws_x_margin(void); /* widescreen cull-margin term (gpu.c) */\n";
|
||||
ss << "extern int psx_ws_cull_sltiu(uint32_t sx, uint32_t imm); /* ws auto screen-x cull (gpu.c) */\n";
|
||||
|
||||
Reference in New Issue
Block a user