Repository navigation
feat(src): six Joba functions in C, notes for the near misses - #394
Merged
Veradictus merged 16 commits intoNov 2, 2026
Merged
Conversation
Joba's projectile update, 1,144 bytes at its one USA place, from the retained near miss. Two control-flow corrections and two source shapes close it: - A hit with a true predicate only removes the object: retail's branch skips func_L00_003294F0, which belongs to the burst path. - A projectile that has stopped moving in frames 25-33 returns without expiring. - Each arm writes out its own hit tail; jump2 cross-jumps them after allocation, which keeps the object in $s2 and the impact load in the branch slot. - func_002C2210's last two arguments are declared float-then-int (same $t2/$f14 registers, an interleaving other callers already use), putting the $t2 zero in the delay slot. - The distance call is func_00282E80, not func_00282E48. Built -O2 -G8 -g in its own unit. The nonmatching copy is retired. Validation: - tools/check.py: 1 of 1 USA place; absent from the PAL catalogue; US2 not checked (no US2 dump here). - tools/build.py level 11 --strict: OK, zero C fallbacks. - python3 -m unittest discover -s tests: 339 tests passed. - tests/check_repository.py passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
Twenty-odd source shapes and per-file options for the two flag scans, none closer than the retained body; the second scan's pointer copy points at loop strength reduction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
…ctor declaration Record that a void func_002B60B0 declaration closes all seven rows, and why it is not used, for a maintainer to rule on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
The retained near miss was 896/896 bytes with the state pointer and the child loop's -1 sentinel in each other's saved registers. Writing the eight-child loop as a plain index loop over the state words, rather than a walking pointer with a down-counter, gives the sentinel $s4 and the state $s3 as in retail. Built -O2 -G8 in its own unit; the nonmatching copy is retired. Validation: - tools/check.py: 1 of 1 USA place. - tools/build.py level 11 --strict: OK, zero C fallbacks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
The retained near miss was four bytes short: its upper random bound, read as a bare one-word symbol, was moved into a call's delay slot and became a $gp load. The bounds are one two-float block at D_L11_001B2388; reading the upper as the block's second word (an existing `_block` sda alias pattern) gives the two-instruction absolute load that stays before the call, and the lower keeps its $gp view. Forming the linked moby's pointer before reading its state byte fixes the predicate's registers. Built with the default -O2 -G0 profile in its own unit; the nonmatching copy is retired. Validation: - tools/check.py: 1 of 1 USA place. - tools/build.py level 11 --strict: OK, zero C fallbacks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
…indings Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
…hed in src/ Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
ByteMatch progress reportSCES_516.07
No function changes. SCUS_972.68_v2
No function changes. SCUS_972.68
No function changes. Commit 910165a · Ratchet & Clank: Going Commando on ByteMatch |
Second attempt: the state-flag movn and counter store now match; the retained body is 436/436 bytes with 14 rows left in the final call's argument setup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
Three changes over the retained near miss. The state flag takes the switch variable only once the frame count reaches 0x79 (`flag` stays 0 otherwise), which gives retail's movn; the count is incremented in place and re-read, so the store is unmasked and the compare masked. The effect table is declared as the sda incomplete array most callers already use, so its address is one macro load among the argument moves and the 0x810001 stack argument takes a2 as in retail (found with the allocation dump: the split lui was being hoisted). The three helpers it called undeclared now have their usual prototypes. Built -O2 -G8 in its own unit; the nonmatching copy is retired. Validation: - tools/check.py: 1 of 1 USA place. - tools/build.py level 11 --strict: OK, zero C fallbacks. - tests/check_repository.py passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
Joba's rope solver, 628 bytes at its one USA place, from the retained near miss. The direction flag and pass count carry next-state values set in each arm and copied back at the end of each pass, which reproduces retail's $a1/$v1 values with stores after each definition and reloads before the shared copy and the pass test (the allocation dump showed a single pseudo crossing 14 calls could never be caller-saved). The lengths are indexed by the loop counter, `length` is block-local and `next` is formed after the floor clamp. Built -O2 -G0 -g in its own unit (-g supplies the line-label nop before div.s); the nonmatching copy is retired. Validation: - tools/check.py: 1 of 1 USA place. - tools/build.py level 11 --strict: OK, zero C fallbacks. - tests/check_repository.py passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
The flag scans index flags with a block-local j = next-1. Kept as a separate variable, the front end does not fold flags+(next-1) into (flags+next)-1, so loop.c strength-reduces the address giv into a pointer register, giving retail's cursor, pre-loop test and copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
Update the retained draft with the sibling MenuRecord and SDATA table shapes and record why the selection loop is strength-reduced (rerun loop pass hoists the table la), the -fno-rerun-loop-opt measurement (904 bytes, loop matches) and the remaining label-copy and entry-allocation differences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Six Joba (level 11) functions matched from their retained near misses, plus measured notes for the ones that stay assembly.
Matched
func_L11_00434580func_L00_003294F0), and a stopped projectile in frames 25-33 returns without expiring. Each arm writes out its own hit tail, which jump2 cross-jumps after allocation (object stays in$s2).func_002C2210's last two parameters are declared float-then-int (same$t2/$f14; other callers already use that interleaving). The distance call isfunc_00282E80, notfunc_00282E48.func_L11_00472E10$s4/$s3.func_L11_00461308D_L11_001B2388: the upper is read asD_L11_001B2388_block[1](existing_blocksda alias pattern), a two-instruction absolute load that stays out of the call's delay slot; the lower keeps its$gpview. Forming the linked moby's pointer before reading its state byte fixes the predicate's registers.func_L11_003DCEB0movn; the count is incremented in place and re-read (unmasked store, masked compare). The effect table uses thechar D_L11_001A8F20[] __attribute__((sda))declaration most callers already have, so its address is one macro load and the0x810001stack argument takes$a2(diagnosed from the allocation dump). Prototypes added for three helpers it called undeclared.func_L11_00437FD0$a1/$v1values with stores after each definition and reloads before the shared copy and the pass test (the allocation dump showed a single pseudo crossing 14 calls could never be caller-saved). The lengths are indexed by the loop counter,lengthis block-local andnextis formed after the floor clamp.-O2 -G0 -gin its own unit (-gsupplies the line-label nop beforediv.s).func_L11_00438880while (next < 13) { int j = next - 1; if (!flags[j]) break; next++; }. Written asflags[next-1], the front end folds the address to(flags+next)-1and loop.c finds the address giv not worth reducing (0 vs 7in the loop dump); the separatejkeeps thenext-1giv, so the summed benefit makes loop.c strength-reduce it into retail's pointer cursor, including the pre-loop test through the computed address and the copy into the cursor.Each lives in its own unit; the
nonmatching/copies are retired, and the two functions that had port-only C innonmatching/functional.tsvlose those rows and files (as in 588f8f0).Notes only (still assembly)
func_L11_00452450: all 956 bytes match iffunc_002B60B0is declaredvoidin this caller. Not used, because the callee returns its pointer and COMPILER-NOTES forbids an invented void return; most existing callers insrc/already declare it void. A maintainer ruling would settle it.func_L11_00443D78: negative result appended to its notes (inline conversions do not serialize).func_L11_00443940: improved body and findings in its notes. With theMenuRecord/SDATAtable shapes from the matched sibling and-fno-rerun-loop-opt, the selection loop matches retail; 20 bytes remain, mainly retail keeping each label pointer in its own register before the four draw calls.Validation
tools/check.py: each matched function 1 of 1 USA v1.01 place. PAL's catalogue has none of them; US2 not checked (no US2 dump on this machine).tools/build.py all --strict: 28 programs OK, zero C fallbacks (e.g.11_joba: OK: 2363208 loaded bytes equal).python3 -m unittest discover -s tests: 339 tests OK.tests/check_repository.py: repository checks passed.masterbefore measuring. Progress report not regenerated.🤖 Generated with Claude Code
https://claude.ai/code/session_017f7s8MnhdrdEynhYhxkLs6