From a22d5646f64f45f7699d7d0afd80ad91b584cf25 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:26:02 -0600 Subject: [PATCH] =?UTF-8?q?docs(cookbook):=20=C2=A7374/=C2=A7375=20?= =?UTF-8?q?=E2=80=94=20two=20more=20bounds=20on=20the=20register-pin=20lev?= =?UTF-8?q?er?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §374 a register __asm__($30) reservation is NOT honoured by move_movables under pressure, and the corruption is SILENT (the build succeeds) -- audit the raw objdump register uses before trusting a pinned build that compiles. §375 an $a0-$a3 pin used LATE relocates an EARLIER outgoing-call use of that same register ~26 slots early, identically across three structural variants; argument pins are not local the way $s pins are. With §368 and §373 these now form a usable four-way rule for when a pin helps, when it fights the allocator, when it is ignored entirely, and when it acts at a distance. --- docs/cookbook-index.md | 10 ++++++++-- docs/matching-cookbook.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/cookbook-index.md b/docs/cookbook-index.md index 9c27c19198..e8b58475f0 100644 --- a/docs/cookbook-index.md +++ b/docs/cookbook-index.md @@ -2,7 +2,7 @@ > **Generated by `tools/cookbook_index.py` — do not hand-edit** (R33). Regenerate after adding a cookbook section. > -> `docs/matching-cookbook.md` is ~716 KB / 1028 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. +> `docs/matching-cookbook.md` is ~716 KB / 1030 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. **How to use:** name what you SEE in the diff (a stolen delay slot, an extra `la`, a swapped register pair, a `conflicting types` error), find that symptom below, read those sections first. If nothing fits, THEN grind — and add a section when you win. @@ -185,7 +185,7 @@ - **§3-2.** — A REGISTER PIN THAT DELETES A sched2 ANTI-DEPENDENCE L31997 - **§3-3.** — HARD FACT FOR THE SCHEDULING MAP — an `asm` ALWAYS has priority 1 L32010 -### register allocation & pins (125) +### register allocation & pins (127) - **§10** — Closing the regalloc/scheduling hard tail by hand (LZSS, Phase 7 session F — the full close) L854 - **Residual** — A — commutative `|`/`&`/`+` result lands in the wrong source-operand register L875 @@ -312,6 +312,8 @@ - **§368** — ★★★ — THE **RELOAD-REMAT CONSTANT**: REACH A REGISTER NO PIN CAN REACH (P31 S68; ov_SC03_105/func_80187A30, 339 ins, fable escalation closed 8 → 0 in ONE edit) L31792 - **§373** — ★★★ — THE **DEAD-RESET CSE-BREAKER**, THE PIN THAT BREAKS A sched2 ANTI-DEP, AND WHY AN `asm` CAN NEVER RAISE PRIORITY (P31 S68; byte-proven ov_SC06_010/func_8017E764, 438 ins, fable escalation closed 8 → 0) L31977 - **§3-2.** — A REGISTER PIN THAT DELETES A sched2 ANTI-DEPENDENCE L31997 +- **§374** — A `register … __asm__("$30")` RESERVATION IS **NOT HONOURED** BY `move_movables` (P31 S68; main/func_80015608, 86 ins) L32026 +- **§375** — AN `$a0`-`$a3` PIN USED LATE RELOCATES AN **EARLIER** OUTGOING-CALL USE OF THAT REGISTER (P31 S68; main/func_8005F0C8, 88 ins) L32042 ### CSE / redundancy / rematerialization (43) @@ -2621,6 +2623,8 @@ - **§3-2.** — A REGISTER PIN THAT DELETES A sched2 ANTI-DEPENDENCE L31997 - **§3-3.** — HARD FACT FOR THE SCHEDULING MAP — an `asm` ALWAYS has priority 1 L32010 - **CROSS-REFERENCE** — TO §370 — checked and found INAPPLICABLE here, which is the point L32018 +- **§374** — A `register … __asm__("$30")` RESERVATION IS **NOT HONOURED** BY `move_movables` (P31 S68; main/func_80015608, 86 ins) L32026 +- **§375** — AN `$a0`-`$a3` PIN USED LATE RELOCATES AN **EARLIER** OUTGOING-CALL USE OF THAT REGISTER (P31 S68; main/func_8005F0C8, 88 ins) L32042 --- @@ -3661,3 +3665,5 @@ Notes routinely quote that as a section id. This table resolves it. Grep bait: ` | L31997 | §3-2. | A REGISTER PIN THAT DELETES A sched2 ANTI-DEPENDENCE | | L32010 | §3-3. | HARD FACT FOR THE SCHEDULING MAP — an `asm` ALWAYS has priority 1 | | L32018 | CROSS-REFERENCE | TO §370 — checked and found INAPPLICABLE here, which is the point | +| L32026 | §374 | A `register … __asm__("$30")` RESERVATION IS **NOT HONOURED** BY `move_movables` (P31 S68; | +| L32042 | §375 | AN `$a0`-`$a3` PIN USED LATE RELOCATES AN **EARLIER** OUTGOING-CALL USE OF THAT REGISTER ( | diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index 9aec548090..53e406aaa7 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -32022,3 +32022,32 @@ cause was the birthing-boost → local-alloc → anti-dep chain above — and th §370's claim is unchanged and still narrow: it applies to *simultaneously-ready same-priority leaves*. The habit is the transferable part: check whether a recorded bound actually covers your case before concluding the residual is unreachable. + +## §374 — A `register … __asm__("$30")` RESERVATION IS **NOT HONOURED** BY `move_movables` (P31 S68; main/func_80015608, 86 ins) + +Under ~9-way register pressure at -O2, gcc-2.7.2 **free-registers something into `$30`/`$fp` AFTER +the pin's own assignment**, silently corrupting whichever variable loses that fight (observed as +y / flags / size / tag / mode2 across configurations). Reproducible. `move_movables`' invariant-hoist +register SELECTION does not consult local register-asm reservations. + +**THE CORRUPTION IS SILENT** — the build succeeds. Audit the raw objdump register uses by hand before +trusting a pinned build that "compiles fine". + +**This is the fourth bound on the pin lever, and together they are a usable rule:** +* **§368** — a pin FIGHTS local-alloc when you want a different ALLOCATION (measured worse than none) +* **§373** — a pin WORKS to break a false sched2 ANTI-DEPENDENCE +* **§374** — a pin on `$30`/`$fp` is NOT HONOURED at all against `move_movables` under pressure +* **§375** — a pin on `$a0`-`$a3` has NON-LOCAL effects, backwards, through earlier calls + +## §375 — AN `$a0`-`$a3` PIN USED LATE RELOCATES AN **EARLIER** OUTGOING-CALL USE OF THAT REGISTER (P31 S68; main/func_8005F0C8, 88 ins) + +The loop body is oracle-proven byte-exact once the base is fenced and `p` is pinned to `$4`. But that +pin **hoists the earlier `func_8005C2C8` argument copy ~26 slots early**, identically across three +structural variants — block scope and declaration order make no difference. + +**The rule:** a hard-register pin on an ARGUMENT register used LATE relocates any EARLIER outgoing-call +use of that same register to the earliest legal point. Argument-register pins are not local the way +`$s`-register pins are; they reach backwards past unrelated calls. + +(The other residual on that function is §188's epilogue and is toolchain-unfixable — it is now in the +walls ledger. See the playbook §1b: check `wall_sweep` BEFORE escalating anything.)