From ecbe17ad1d8c2fc4883f69e970a26b96ff817fe3 Mon Sep 17 00:00:00 2001 From: Christopher Williams Date: Thu, 24 Sep 2026 11:12:17 -0400 Subject: [PATCH] =?UTF-8?q?phase11:=20merge=2052=20+=20cookbook=20163-165?= =?UTF-8?q?=20=E2=80=94=20589=20bodies=20/=20598=20regions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Worker E's 0x80107DE8 (128 B, maspsx=epilogue) and 0x8007D5FC (132 B, DEFAULT toolchain). 163: a recurring epilogue-list class WITH A SHAPE TELL -- correct length, identical instruction multiset, and the residual is where cc1's reorg put the EPILOGUE LOADS relative to the last gp-relative read-modify-write block. The original's epilogue loads FILL the global load's delay slot; cc1 emits a #nop instead. Tell: the row's last statement is a gp-relative read-modify-write immediately before the epilogue. NOT a spelling problem -- worker E probed the maspsx mode split and the nop is a cc1 #nop, not maspsx, so no option changes it. Classify it: post-pass territory. 164: a register residual can be ARGUMENT EVIDENCE -- when the only residual is a value in an argument register and there is no argument setup at the jal, try passing it as that argument. 165: finding 147 confirmed a second time -- 0x8007D5FC is on the epilogue list but cc1 fills its own slot, so the token is a no-op and the row is claimed with '-'. The list was selected on the ORIGINAL's tail; the token must be decided from the CANDIDATE's. --- docs/MATCHING_COOKBOOK.md | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/MATCHING_COOKBOOK.md b/docs/MATCHING_COOKBOOK.md index 4dad6a8..92bad37 100644 --- a/docs/MATCHING_COOKBOOK.md +++ b/docs/MATCHING_COOKBOOK.md @@ -2648,3 +2648,51 @@ a non-prototype declaration:** The row also confirmed **157** a fourth time (the first call passes only `a1`/`a2`, keeping its own live `a0`), and added: **a shift count can be a global read straight into the argument register, with the shift scheduled into the preceding call's delay slot.** + +### 163. A recurring epilogue-list class with a SHAPE TELL — classify it, do not spell it (worker E) + +Worker E hit this twice in a row on the 110-row epilogue list (`0x801000A0`, `0x801001C4`): +**correct length, instruction multiset otherwise IDENTICAL, and the residual is where cc1's reorg put +the EPILOGUE LOADS relative to the last gp-relative read-modify-write block.** + + original: sw v0,2112(gp) / lw v0,2116(gp) / lw ra,20(sp) / lw s0,16(sp) / or v0,v0,a0 / sw v0,2116(gp) / jr ra + candidate: sw v0,2112(gp) / lw v0,2116(gp) / NOP / or v0,v0,a0 / sw v0,2116(gp) / lw ra / lw s0 / jr ra + +**The original's two epilogue loads FILL the global load's delay slot**; cc1 emits an explicit `#nop` +instead and leaves the epilogue loads at the end. It presents as **4 bytes LENGTH-MISMATCH** (one nop). + +**SHAPE TELL FOR DISPATCH:** the row's last statement is a **gp-relative read-modify-write (`|=` / `&=`) +immediately before the epilogue**, and the original interleaves the epilogue loads into it. + +**IT IS NOT A SPELLING PROBLEM AND MASPSX MODE CANNOT FIX IT.** Worker E probed the mode split +(findings 94/121): `--no-maspsx` = 148, `--no-maspsx --fill-epilogue` = 148, +`--fill-epilogue --no-jump-slot-nop` = 140. **The nop is a cc1 `#nop`, not maspsx**, so no maspsx +option changes this fill. + +> **If a worker on the epilogue list sees "4 bytes LONG with the correct instruction multiset", +> CLASSIFY IT** — it is this class, the same FILL family as 40/94/117/121, i.e. **post-pass territory, +> not source shape.** Named untried lever: finding 51's `volatile` on the gp globals. + +**And the list is NOT homogeneous:** `0x800F421C` is a third epilogue-list row whose residual is a +**prologue schedule** instead (31 B). + +### 164. A register residual can be ARGUMENT EVIDENCE, not a tie-break (worker E) + +Worker E's `0x80107DE8`: the only difference was `cur` in **`a0`** (original) versus **`v1`** (candidate). +**`a0` is the first argument register and there was NO argument setup at the `jal`** — so `cur` is being +passed as that argument. `func_80107C5C(cur)` is byte-exact where `func_80107C5C()` leaves 4 bytes. + +> **When the ONLY residual is a value sitting in an ARGUMENT register, try passing it as that +> argument** — it is evidence about the call's arguments, not an allocator tie-break. + +Also on that row: `node = node[1];` must come **before** the two comparisons — the intervening +redefinition is what stops cc1 propagating `cur` back into `node`'s register (finding 72, new instance). + +### 165. Finding 147 confirmed a second time — and a row where the token is a NO-OP (worker E) + +Worker E's `0x8007D5FC` is **on the epilogue list** but cc1 fills its own slot: **the default +toolchain matches at 132 B and `--fill-epilogue` is a no-op (132/0 both ways).** So it is claimed with +`-`, not with the token. + +**Second independent confirmation of finding 147:** the epilogue list was selected on the **original's** +tail, and the token must be decided per row from the **candidate's** tail.