Skip to content

fix(recomp): start VCALLMSR from CMSAR0 instead of indexing vi[] - #268

Open
drakolordx7 wants to merge 1 commit into
ran-j:mainfrom
drakolordx7:fix/vcallmsr-register-index
Open

drakolordx7 wants to merge 1 commit into
ran-j:mainfrom
drakolordx7:fix/vcallmsr-register-index

Conversation

@drakolordx7

Copy link
Copy Markdown

Fixes #262.

VCALLMSR was generated as ctx->vi[27] & 0x1FF, but vi[] has 16 entries (uint16_t vi[16]). 27 is the CMSAR0 control-register number, so the read went past the array and never saw the value CTC2 stored in ctx->vu0_cmsar0. The generator now reads ctx->vu0_cmsar0.

Games need their generated code regenerated to pick this up. A new code generator test fails without the change; ps2x_tests 437/437.

Made by drakolord and assisted with Claude Code.

VCALLMSR was generated as

    uint16_t instr_index = ctx->vi[27] & 0x1FF;

but vi[] only holds the 16 VU0 integer registers (uint16_t vi[16] in
R5900Context). "27" is the VU0 control register number of CMSAR0 (the
$vi27 that CTC2 writes, VU0_CR_CMSAR0), so the generated code read 22
bytes past the end of the array, into neighbouring context fields, and
never saw the value the game had stored with CTC2. The CTC2 side already
stores it in ctx->vu0_cmsar0.

Read ctx->vu0_cmsar0 instead; the instruction has no register operand.
Generated code has to be regenerated to pick the fix up.

A game that calls VCALLMSR from a helper (CTC2 $vi27, then VCALLMSR) hit
this; it had been worked around in the runtime. This fixes it at the source,
as also described in issue ran-j#262. The new code generator test fails without
the change.

Made by drakolord and assisted with Claude Code.
Scotho added a commit to Scotho/socom-unzipped that referenced this pull request Oct 3, 2026
…] (upstream PS2Recomp #268)

VCALLMSR was generated as ctx->vi[27] & 0x1FF on a uint16_t vi[16]: 27 is the CMSAR0 control-register number,
so the read went past the array and never saw the value CTC2 stores in ctx->vu0_cmsar0 (our CTC2/CFC2 use that
field too). The generator now reads ctx->vu0_cmsar0. Ported from upstream PS2Recomp PR #268 by drako
(drakolordx7), the fix and its test as written there.

Upstream: ran-j/PS2Recomp#268, fixing ran-j/PS2Recomp#262
(open, not merged on 2026-10-03; no merge commit; ported from its head commit
a0f89eb3d4ffa70a4695fa89cc444bf4743a845b). Same licence (GPL-3.0).
The issue's reporter later noted the register file really has 32 VI slots (16..31 the control registers) and
proposed vi[32] instead; that wider change is not taken here. SOCOM II's generated code emits no VCALLMSR (no
vu0StartMicroProgram in recomp/output), so codegen is unchanged for the game; it takes effect at the next recomp.
LATER row 83; research/85 section 4.

Co-authored-by: drako <98249188+drakolordx7@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recompiler: vcallmsr reads ctx->vi[27], out of bounds on uint16_t vi[16], instead of ctx->vu0_cmsar0

1 participant