diff --git a/config/wave_exclude.txt b/config/wave_exclude.txt index 0f213ad6a..6f8e3a9b2 100644 --- a/config/wave_exclude.txt +++ b/config/wave_exclude.txt @@ -45,5 +45,5 @@ ov_SC03_105:func_801834A4 # WALL: loop.c movable ordering, closeness 6 (S71) ov_SC03_105:func_8018624C # CARVE-BLOCKED: ov_SC03_105_jr_8017C8D0 owns >1 raw jtbl span — needs a split ov_SC03_105:func_801867D0 # CARVE-BLOCKED: ov_SC03_105_jr_8017C8D0 owns >1 raw jtbl span — needs a split ov_SC06_022:func_8017DF28 # WALL: expand_block_move copy_addr_to_reg pseudo + cse reuse, closeness 2 (S71) -main:func_8002B0B4 # WALL: §179-C no epilogue — every exit is a raw j/jr into labels inside SaveLoadRoutine's body, so gcc-2.7.2 (no sibcall/tail-merge pass) always synthesizes an epilogue the target lacks. src/800_b.c states this above the stub; an S73 agent spent 70k tokens re-deriving it and returned the stub verbatim. -main:SaveLoadRoutine # WALL: §296/§434 frame check — SaveLoadRoutine (1139 ins) and func_8002B0B4 (76) are ONE 0x40 frame split across two symbols. func_8002B0B4's jtbl_80072E44 points at SaveLoadRoutine AND at labels inside its body (.L8002B1AC/.L8002BEA4/.L8002B1C4); SaveLoadRoutine has no prologue and owns the epilogue lw $ra,0x38($sp)/lw $s3..$s0/addiu $sp,0x40. Byte-verified S73. Neither is a callable C function — the fix is a RESEGMENTATION merging them, not a draft. +main:func_8002B0B4 # WALL: §179-C/§434 — no epilogue; every exit is a raw j/jr into labels inside SaveLoadRoutine, with which it shares one 0x40 frame. Same route as its twin: the §265 pair transcription, not a per-function draft. Excluded from DRAWS only. +main:SaveLoadRoutine # WALL: §296/§434 — SaveLoadRoutine (1139) and func_8002B0B4 (76) are ONE 0x40 frame across two symbols. NOT unmatchable: the §265 verbatim-asm lane transcribes SaveLoadRoutine BYTE-IDENTICAL (measured S73); it fails the whole-binary gate only because substituting one alone moves 3,989 bytes across 262 symbols of the shared frame. Route = transcribe/resegment the PAIR TOGETHER (§265), not a per-function draft. Excluded from DRAWS only. diff --git a/docs/cookbook-index.md b/docs/cookbook-index.md index 6ba15faec..bf2c983f8 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 / 1102 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 / 1103 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. @@ -193,7 +193,7 @@ - **§3-B.** — THE SCHEDULER DIALS (the dominant residual family this wave) L33108 - **§424** — ★★★ — EQUAL-PRIORITY STORES COME OUT **REVERSED**: sched1's LUID tie picks the LAST statement first (P31 S71; byte-proven `ov_SC07_006/func_801890FC`, 387 ins) L33807 - **§428** — ★★★ — A ZERO-BYTE CROSS-JUMP BARRIER: ADVANCE THE POINTER INSIDE EACH SWITCH ARM (P31 S72; `main/func_80026D64`, 218 ins, MATCH in 2 compiles) L33954 -- **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34040 +- **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34073 ### register allocation & pins (131) @@ -376,7 +376,7 @@ - **§3-1.** — DEAD-RESET CSE-BREAKER — the zero-footprint replacement for a §195-I asm re-tie L31979 - **§385** — ★★★ — THE **SCHED2 PRIORITY-DONOR ASM**: closing the "hoisted-invariant vs IV-init preheader swap" class (P31 S69; byte-proven main/func_80038A58, 347 ins, fable escalation 2 → 0) L32309 - **§417** — ★★★ — A REGISTER PIN CAN BLOCK `jump.c`'s SELECT COLLAPSE, AND UNPINNING THEN EXPOSES A `cse` SKIP-BLOCKS MERGE (P31 S71; byte-proven `ov_SC03_013/func_8017E6F4`, 182 ins) L33605 -- **§432** — ★★★ — DEFEAT cse's MERGE OF TWO IDENTICAL MASKS BY SPELLING ONE AS A SHIFT PAIR (P31 S72/S73; `main/func_8002DC68`, MATCH 198/198) L34184 +- **§432** — ★★★ — DEFEAT cse's MERGE OF TWO IDENTICAL MASKS BY SPELLING ONE AS A SHIFT PAIR (P31 S72/S73; `main/func_8002DC68`, MATCH 198/198) L34217 ### loops & induction variables (48) @@ -427,7 +427,7 @@ - **§386** — ★★★ — A BYTE LOAD ON THE **BIV** BASE WAS BORN IN THE COMBINE PASS: SPELL IT AS A SHIFT-MASK, NEVER A DEREF (P31 S69; byte-proven main/func_80020598, 292 ins, escalation 1 → 0) L32335 - **§393** — ★★ — THE **BIRTHING BOOST**: A SINGLE-SET LOCAL IS SCHEDULED LAST; GIVE IT A SECOND SET (P31 S69; byte-proven ov_SC02_017/func_8017FCFC) L32543 - **§418** — ★★★ — TWO LOOP-STRUCTURE LEVERS: MAKE THE SECOND INDEX A GIV, AND KEEP A TABLE ADDRESS UNFOLDED (P31 S71; byte-proven `ov_SC04_016/func_8017DF8C`, 184 ins, 32 → 0 in seven compiles) L33632 -- **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34040 +- **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34073 ### structs, block moves & memcpy (88) @@ -797,8 +797,8 @@ - **§412** — ★★★ — §323 CARVE BLOCKER 2 WAS A REGEX THAT COULD NOT SEE PAST `__attribute__` (P31 S71) L33424 - **§426** — ★★★ — main's SWITCH FUNCTIONS WERE NEVER A CODEGEN WALL: ONE RODATA CARVE HAD BEEN MISSING SINCE PHASE 7 (P31 S72; 3 of the 11 "PROVEN gate-rejects" banked byte-identical in 14 s) L33855 - **§428** — ★★★ — A ZERO-BYTE CROSS-JUMP BARRIER: ADVANCE THE POINTER INSIDE EACH SWITCH ARM (P31 S72; `main/func_80026D64`, 218 ins, MATCH in 2 compiles) L33954 -- **§431** — ★★★ — SPLITTING A 27,000-LINE TU AT ITS ORIGINAL BOUNDARIES: THE JTBL SPANS TELL YOU WHERE, AND THE COMPILER TELLS YOU WHAT CROSSES (P31 S72; `src/800.c` -> `800.c`/`800_b.c`/`800_c.c`, byte-identical with nothing banked) L34089 -- **§433** — ★★★ — ON A SWITCH FUNCTION, CASE SOURCE ORDER IS THE DOMINANT RESIDUAL — AND `match_one` IS BLIND TO IT (P31 S73; 4 of 5 consecutive main MATCHes) L34152 +- **§431** — ★★★ — SPLITTING A 27,000-LINE TU AT ITS ORIGINAL BOUNDARIES: THE JTBL SPANS TELL YOU WHERE, AND THE COMPILER TELLS YOU WHAT CROSSES (P31 S72; `src/800.c` -> `800.c`/`800_b.c`/`800_c.c`, byte-identical with nothing banked) L34122 +- **§433** — ★★★ — ON A SWITCH FUNCTION, CASE SOURCE ORDER IS THE DOMINANT RESIDUAL — AND `match_one` IS BLIND TO IT (P31 S73; 4 of 5 consecutive main MATCHes) L34185 ### optimisation level (-O0/-O2) (22) @@ -1029,7 +1029,7 @@ - **§3-D.** — INTEGRATION IS STILL THE BOTTLENECK, AND THE TU IS THE AUTHORITY L33140 - **§415** — ★★ — A FILE-SCOPE DECL MAKES gcc-2.7.2 MERGE THE TU'S LATER *BLOCK-SCOPE* EXTERNS INTO IT (P31 S71; byte-proven `ov_SC04_011/func_80180B24`, 215 ins) L33547 - **§423** — ★★★ — "MATCH IN ISOLATION + GATE REJECTS + CAUSE NOT DETERMINED" ⇒ GREP THE TU FOR A FILE-SCOPE TYPEDEF THE DRAFT ALSO CARRIES (P31 S71; byte-proven `ov_SC03_092/func_8017FA74`) L33780 -- **§431** — ★★★ — SPLITTING A 27,000-LINE TU AT ITS ORIGINAL BOUNDARIES: THE JTBL SPANS TELL YOU WHERE, AND THE COMPILER TELLS YOU WHAT CROSSES (P31 S72; `src/800.c` -> `800.c`/`800_b.c`/`800_c.c`, byte-identical with nothing banked) L34089 +- **§431** — ★★★ — SPLITTING A 27,000-LINE TU AT ITS ORIGINAL BOUNDARIES: THE JTBL SPANS TELL YOU WHERE, AND THE COMPILER TELLS YOU WHAT CROSSES (P31 S72; `src/800.c` -> `800.c`/`800_b.c`/`800_c.c`, byte-identical with nothing banked) L34122 ### build graph, splat & the harness (195) @@ -1364,9 +1364,9 @@ - **§408** — ★★★ — §406 REFUTED AS A SWEEP: THE SHAPE IS THE FAMILY, THE DISAGREEMENT IS THE DEFECT (P31 S71; 0 MATCH / 14 applied, 0 / 210) L33209 - **§411** — ★★★ — THE PACK MUST CARRY THAT FUNCTION'S OWN HISTORY (P31 S71; measured 38/39 vs 124/131) L33386 - **§428a** — ★★★ — TWO RESIDUALS THAT MOVE IN OPPOSITE DIRECTIONS UNDER EVERY LEVER USUALLY SHARE ONE CAUSE (P31 S72; `main/func_8001B0D4`, NEAR/53 -> MATCH; **my first answer here was WRONG and is kept below as the refutation**) L33992 -- **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34040 +- **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34073 -### (unbucketed — title matched no symptom vocabulary) (326) +### (unbucketed — title matched no symptom vocabulary) (327) - **§3-How** — to use this L30 - **§1** — Idiom catalog (asm pattern → C that produces it) L39 @@ -1693,7 +1693,8 @@ - **§3-The** — nine laws this wave produced L33288 - **§413** — ★★★ — DIFFICULTY IS THE RESIDUAL CLASS, NOT `nins` — ROUTE THE MODEL TIER OFF HISTORY (P31 S71, Drew) L33473 - **§416** — ★★ — FOUR LEVERS FROM THE S71 OVERNIGHT LANE, none of which the cookbook held (P31 S71) L33572 -- **§434** — ★★★ — TWO SYMBOLS, ONE FRAME: RUN THE FRAME CHECK BEFORE DRAFTING ANYTHING LARGE (P31 S73; `main/SaveLoadRoutine` + `func_8002B0B4`, byte-verified) L34226 +- **§429** — ★★★ — EVERY HELD POINTER NEEDS ITS OWN LOCAL, AND A NEGATIVE-DISPLACEMENT BYTE STORE NEEDS ONE OF ITS OWN (P31 S72; `main/CdReadStateMachine`, MATCH 385/385) L34040 +- **§434** — ★★★ — TWO SYMBOLS, ONE FRAME: RUN THE FRAME CHECK BEFORE DRAFTING ANYTHING LARGE (P31 S73; `main/SaveLoadRoutine` + `func_8002B0B4`, byte-verified) L34259 ## All sections, in order @@ -2795,11 +2796,12 @@ - **§427** — ★★ — A HASH IS A CORRECTNESS ORACLE WITH ZERO DIAGNOSTIC CONTENT; PRESERVE THE RED ARTIFACT BEFORE ANYTHING REBUILDS OVER IT (P31 S72) L33935 - **§428** — ★★★ — A ZERO-BYTE CROSS-JUMP BARRIER: ADVANCE THE POINTER INSIDE EACH SWITCH ARM (P31 S72; `main/func_80026D64`, 218 ins, MATCH in 2 compiles) L33954 - **§428a** — ★★★ — TWO RESIDUALS THAT MOVE IN OPPOSITE DIRECTIONS UNDER EVERY LEVER USUALLY SHARE ONE CAUSE (P31 S72; `main/func_8001B0D4`, NEAR/53 -> MATCH; **my first answer here was WRONG and is kept below as the refutation**) L33992 -- **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34040 -- **§431** — ★★★ — SPLITTING A 27,000-LINE TU AT ITS ORIGINAL BOUNDARIES: THE JTBL SPANS TELL YOU WHERE, AND THE COMPILER TELLS YOU WHAT CROSSES (P31 S72; `src/800.c` -> `800.c`/`800_b.c`/`800_c.c`, byte-identical with nothing banked) L34089 -- **§433** — ★★★ — ON A SWITCH FUNCTION, CASE SOURCE ORDER IS THE DOMINANT RESIDUAL — AND `match_one` IS BLIND TO IT (P31 S73; 4 of 5 consecutive main MATCHes) L34152 -- **§432** — ★★★ — DEFEAT cse's MERGE OF TWO IDENTICAL MASKS BY SPELLING ONE AS A SHIFT PAIR (P31 S72/S73; `main/func_8002DC68`, MATCH 198/198) L34184 -- **§434** — ★★★ — TWO SYMBOLS, ONE FRAME: RUN THE FRAME CHECK BEFORE DRAFTING ANYTHING LARGE (P31 S73; `main/SaveLoadRoutine` + `func_8002B0B4`, byte-verified) L34226 +- **§429** — ★★★ — EVERY HELD POINTER NEEDS ITS OWN LOCAL, AND A NEGATIVE-DISPLACEMENT BYTE STORE NEEDS ONE OF ITS OWN (P31 S72; `main/CdReadStateMachine`, MATCH 385/385) L34040 +- **§430** — ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) L34073 +- **§431** — ★★★ — SPLITTING A 27,000-LINE TU AT ITS ORIGINAL BOUNDARIES: THE JTBL SPANS TELL YOU WHERE, AND THE COMPILER TELLS YOU WHAT CROSSES (P31 S72; `src/800.c` -> `800.c`/`800_b.c`/`800_c.c`, byte-identical with nothing banked) L34122 +- **§433** — ★★★ — ON A SWITCH FUNCTION, CASE SOURCE ORDER IS THE DOMINANT RESIDUAL — AND `match_one` IS BLIND TO IT (P31 S73; 4 of 5 consecutive main MATCHes) L34185 +- **§432** — ★★★ — DEFEAT cse's MERGE OF TWO IDENTICAL MASKS BY SPELLING ONE AS A SHIFT PAIR (P31 S72/S73; `main/func_8002DC68`, MATCH 198/198) L34217 +- **§434** — ★★★ — TWO SYMBOLS, ONE FRAME: RUN THE FRAME CHECK BEFORE DRAFTING ANYTHING LARGE (P31 S73; `main/SaveLoadRoutine` + `func_8002B0B4`, byte-verified) L34259 --- @@ -3909,8 +3911,9 @@ Notes routinely quote that as a section id. This table resolves it. Grep bait: ` | L33935 | §427 | ★★ — A HASH IS A CORRECTNESS ORACLE WITH ZERO DIAGNOSTIC CONTENT; PRESERVE THE RED ARTIFAC | | L33954 | §428 | ★★★ — A ZERO-BYTE CROSS-JUMP BARRIER: ADVANCE THE POINTER INSIDE EACH SWITCH ARM (P31 S72; | | L33992 | §428a | ★★★ — TWO RESIDUALS THAT MOVE IN OPPOSITE DIRECTIONS UNDER EVERY LEVER USUALLY SHARE ONE C | -| L34040 | §430 | ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this | -| L34089 | §431 | ★★★ — SPLITTING A 27,000-LINE TU AT ITS ORIGINAL BOUNDARIES: THE JTBL SPANS TELL YOU WHERE | -| L34152 | §433 | ★★★ — ON A SWITCH FUNCTION, CASE SOURCE ORDER IS THE DOMINANT RESIDUAL — AND `match_one` I | -| L34184 | §432 | ★★★ — DEFEAT cse's MERGE OF TWO IDENTICAL MASKS BY SPELLING ONE AS A SHIFT PAIR (P31 S72/S | -| L34226 | §434 | ★★★ — TWO SYMBOLS, ONE FRAME: RUN THE FRAME CHECK BEFORE DRAFTING ANYTHING LARGE (P31 S73; | +| L34040 | §429 | ★★★ — EVERY HELD POINTER NEEDS ITS OWN LOCAL, AND A NEGATIVE-DISPLACEMENT BYTE STORE NEEDS | +| L34073 | §430 | ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this | +| L34122 | §431 | ★★★ — SPLITTING A 27,000-LINE TU AT ITS ORIGINAL BOUNDARIES: THE JTBL SPANS TELL YOU WHERE | +| L34185 | §433 | ★★★ — ON A SWITCH FUNCTION, CASE SOURCE ORDER IS THE DOMINANT RESIDUAL — AND `match_one` I | +| L34217 | §432 | ★★★ — DEFEAT cse's MERGE OF TWO IDENTICAL MASKS BY SPELLING ONE AS A SHIFT PAIR (P31 S72/S | +| L34259 | §434 | ★★★ — TWO SYMBOLS, ONE FRAME: RUN THE FRAME CHECK BEFORE DRAFTING ANYTHING LARGE (P31 S73; | diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index b7abf715d..eac317c5c 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -34037,6 +34037,39 @@ blocks the cross-jump over-merge. **Verification (§405-A):** all 3 jump tables and 20 relocs byte-verified past `match_one`'s masking before the MATCH was reported. +## §429 ★★★ — EVERY HELD POINTER NEEDS ITS OWN LOCAL, AND A NEGATIVE-DISPLACEMENT BYTE STORE NEEDS ONE OF ITS OWN (P31 S72; `main/CdReadStateMachine`, MATCH 385/385) + +Two laws from one function, both about the SAME root: gcc-2.7.2 canonicalises `(mem (reg))` back to a +symbol whenever the pseudo has a single reachable set, so *reusing* a pointer local silently changes +the addressing mode of everything downstream. + +**1. A NEGATIVE-DISPLACEMENT BYTE STORE RE-FOLDS UNLESS IT HAS ITS OWN POINTER.** Writing +`p[-0x10] = v` (or `*(u8 *)(p - 0x10) = v`) where `p` is a symbol-derived pointer lets `alias.c` +re-fold the address to `lui %hi(sym - 0x10)` — the wrong instruction pair. Give it a local of its +own: + +```c +u8 *q = p - 0x10; /* q is SET ONCE and used once: the reg survives as a reg */ +*q = v; +``` + +**2. EVERY HELD POINTER NEEDS A *DISTINCT* LOCAL.** A pseudo with MULTIPLE sets defeats the +`(mem (reg)) -> symbol` canonicalisation for every use, and the resulting reg-form load costs a +**load-delay nop** the target does not have. If you are carrying two or three pointers through a +state machine, that is two or three separate locals — never one reused cursor. This is the same +mechanism as §421 (a `la $tN`+`addiu` pair is RELOAD scratch) read from the source side: what you +spell as reuse, the allocator spells as a multi-set qty. + +**3. THE FRAME DIAL AND THE MERGE-END PIN (both already known, confirmed here).** The §333 frame dial +(an unused `s32 pad[2]` to move the frame size to `0x28`) and explicit labels on the merged tails — +`setStateNine:` / `resetState:` — were the other two levers. **gcc's own `cross_jump` picks the OTHER +end of a merge than you expect**; naming both tails pins which one survives, which is the cheap +alternative to §5a's fence and complements §428's UID barrier. + +**Verification standard this function met (§405-A):** MATCH is `.text`-only, so the agent checked the +**reloc-symbol sequence 180/180** and the **11-entry jump table in case order** before reporting. +That is the bar for any switch function. + ## §430 ★★★ — A GOTO INTO A LOOP IS FINE; HAND-HOIST THE CONSTANTS IT COSTS YOU (P31 S73 — **this section previously said the OPPOSITE and was wrong; the refutation is kept below**) **WHAT I WROTE FIRST, FROM A NEAR (S72).** A NEAR agent on `main/CdReadSectorReadyCB` reported that @@ -34256,6 +34289,17 @@ was drawn and an agent spent 134k tokens and 41 tool calls to reach the same con whole frame as a single function. Until someone does that, both belong on the exclude list, and main's honest matchable frontier is 1,215 instructions smaller than the stub count suggests. -**A caution on agent citations (R14).** The agent that reached this conclusion cited "§265, the -file-scope verbatim-asm lane". §265 is inside §6, per-module optimization mixing — it says nothing -of the kind. The conclusion was right and the citation was invented; check both. +**CORRECTION — MY ACCUSATION WAS THE FALSE CLAIM (S73).** This section originally ended by saying +the agent "invented" its citation of §265, "the file-scope verbatim-asm lane". **§265 exists and says +exactly that**: *"THE VERBATIM-ASM BANK LANE: A FUNCTION NO -O2 C CAN EVER MATCH BANKS AS A RAW +`__asm__` BODY"*, with four named byte-banked precedents (`func_800D0440`, `func_800CBA44`, +`func_80185810`, `src/800b2.c`). I had run `cookbook_index.py --resolve 265`, which resolves a LINE +number, not a section number, and believed the answer without opening §265. The agent was right on +every point; I published the opposite in this cookbook, in a commit message, and to Drew. + +**AND THE VERDICT ITSELF NEEDED NARROWING.** Gated, the §265 transcription of `SaveLoadRoutine` comes +back **BYTE-IDENTICAL for the function itself** — the lane works. It still fails the whole-binary gate +because the substitution moves 3,989 bytes across 262 other symbols: the shared frame. So the true +statement is **"neither symbol can bank SEPARATELY"**, not "neither can bank". The open route is to +transcribe/resegment the PAIR together, and §265 is the lane for it — not a wall to be excluded and +forgotten. \ No newline at end of file