mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-01 15:43:06 -04:00
docs(cookbook): §374/§375 — two more bounds on the register-pin lever
§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.
This commit is contained in:
@@ -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 <sub>L31997</sub>
|
||||
- **§3-3.** — HARD FACT FOR THE SCHEDULING MAP — an `asm` ALWAYS has priority 1 <sub>L32010</sub>
|
||||
|
||||
### 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) <sub>L854</sub>
|
||||
- **Residual** — A — commutative `|`/`&`/`+` result lands in the wrong source-operand register <sub>L875</sub>
|
||||
@@ -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) <sub>L31792</sub>
|
||||
- **§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) <sub>L31977</sub>
|
||||
- **§3-2.** — A REGISTER PIN THAT DELETES A sched2 ANTI-DEPENDENCE <sub>L31997</sub>
|
||||
- **§374** — A `register … __asm__("$30")` RESERVATION IS **NOT HONOURED** BY `move_movables` (P31 S68; main/func_80015608, 86 ins) <sub>L32026</sub>
|
||||
- **§375** — AN `$a0`-`$a3` PIN USED LATE RELOCATES AN **EARLIER** OUTGOING-CALL USE OF THAT REGISTER (P31 S68; main/func_8005F0C8, 88 ins) <sub>L32042</sub>
|
||||
|
||||
### CSE / redundancy / rematerialization (43)
|
||||
|
||||
@@ -2621,6 +2623,8 @@
|
||||
- **§3-2.** — A REGISTER PIN THAT DELETES A sched2 ANTI-DEPENDENCE <sub>L31997</sub>
|
||||
- **§3-3.** — HARD FACT FOR THE SCHEDULING MAP — an `asm` ALWAYS has priority 1 <sub>L32010</sub>
|
||||
- **CROSS-REFERENCE** — TO §370 — checked and found INAPPLICABLE here, which is the point <sub>L32018</sub>
|
||||
- **§374** — A `register … __asm__("$30")` RESERVATION IS **NOT HONOURED** BY `move_movables` (P31 S68; main/func_80015608, 86 ins) <sub>L32026</sub>
|
||||
- **§375** — AN `$a0`-`$a3` PIN USED LATE RELOCATES AN **EARLIER** OUTGOING-CALL USE OF THAT REGISTER (P31 S68; main/func_8005F0C8, 88 ins) <sub>L32042</sub>
|
||||
|
||||
|
||||
---
|
||||
@@ -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 ( |
|
||||
|
||||
@@ -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.)
|
||||
|
||||
Reference in New Issue
Block a user