diff --git a/docs/MATCHING_COOKBOOK.md b/docs/MATCHING_COOKBOOK.md index 4aada27..6c8bea2 100644 --- a/docs/MATCHING_COOKBOOK.md +++ b/docs/MATCHING_COOKBOOK.md @@ -1035,6 +1035,36 @@ maspsx, and that fix worked *only* because maspsx is open source and patchable; redistributed. **Use ASPSX as a read-only diagnostic ORACLE to characterise the behaviour, then carry that behaviour as tracked code.** +**PHASE 12 ADDENDUM — `maspsx=moves` IS A THIRD OPTION, AND IT CLOSES A SUB-CASE.** The entry above +concludes the two halves "cannot be combined" and that one post-pass closes both classes. **Worker B +found a mode that combines them for a specific sub-case, and it is measured on a merged row rather +than argued:** + +`0x8010AA28` (112 B) was classed "maspsx mutual exclusion" with the recorded measurements +`maspsx=off -> 2 differing bytes` and `maspsx on -> 124 bytes, three unfilled delay slots` — the same +exclusion seen from its two sides. **`maspsx=moves` satisfies both at once, first spelling:** + +| mode | result | why | +|---|---|---| +| default (maspsx on) | 124 B | maspsx emits its own unconditional `nop` after every jump whose slot cc1 left empty, so the argument set-ups cc1 placed before the `jal`s never reach the slots (three unfilled, +12) | +| `maspsx=off` | right LENGTH, 2 B wrong | GNU `as` reorder mode performs the fills, but `as` expands cc1's `move` macro as **`or`** (funct 0x25) where the original has **`addu`** (0x21) | +| **`maspsx=moves`** | **112 B / 0 differing** | the `move`→`addu` rewrite ONLY, no nop insertion — so GNU `as` stays in reorder mode and fills the `jal` slots exactly as ASPSX did | + +**This is the first region known to be closed by `maspsx=moves`.** The mode was recorded as +shipped-but-unproven; it is now proven for **the sub-case where the missing instruction is an +ARGUMENT SET-UP that belongs in the `jal` slot** — here `move a3,zero` (the 4th argument of a +4-argument call) plus `move a0,v0` forwarding a result. In that sub-case the mode *is* the post-pass. + +**CHEAP RULE, and the reason this addendum exists: for any row where `maspsx=off` gives the right +LENGTH with a handful of wrong bytes that look like `move` vs `or`, try `--maspsx-moves` BEFORE +spending more spellings.** The cost is one harness run. + +**Candidate to re-test, named rather than left implicit:** `0x800FA5D8`, this entry's own row. Its +`maspsx=off` run is the same signature (correct length, all four fills present, all four `move` copies +broken to `or`), so it is the natural next test. **Not generalised past the evidence:** the sub-case is +argued from one row, and the entry's conclusion that the *rare-epilogue* half still needs a post-pass +is untouched — `0x800FA5D8` needs all four fills back, which is a different missing-instruction shape. + ### 62. Fail fast on an invalid region row A worker placed the source md5 in a claim row's 4th column. `sf3_merge` passed it through as a region