docs(phase-29): func_801463A0 driven to standalone MATCH; one named blocker left (§H antidote)

- 3 falsified hypotheses, then MATCH (101 ins) with direct-symbol scalar decls. The length gap was
  the target re-materializing "lui $at,%hi(sym)" per scalar store while array/struct forms let gcc
  CSE the address into a register (1-ins stores) -> mine was exactly one instruction short.
- Remaining blocker NAMED: the TU's canonical decl is "extern u8 D_80126BE0[]" INSIDE a DEFINE_func_*
  macro body (engine_core.h:19813), so the matching u16 form gives conflicting types in the real TU
  (real cc1, via rtu_match --stderr-out).
- demacroize would clear it but banks x1 (+101 ins) and forfeits x138 — a trap, not a win. The right
  exit is the §H CSE address-fold antidote (balanced if/else diamond, zero asm) so the canonical u8[]
  decl stays and the bank propagates x138 (+13,938 ins). Both draft forms preserved.
This commit is contained in:
Drew T
2026-07-24 20:39:46 -06:00
parent 8940347855
commit 3d26cef9ad
2 changed files with 92 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
// @class: struct
// @stuck: none — MATCH (101 ins). Keys: 8-byte BE0->BE8 unaligned copy via char[8] struct (align 1 -> lwl/lwr/swl/swr); three sh to separate BE0/BE2/BE4 globals; D_80126B78 is s32* loaded once into $s0 at top; three short assigns MUST precede the D_80126B9C read-modify-write so the B9C store schedules last.
#include "common.h"
typedef struct { char _b[8]; } M8_801463A0; /* size 8, align 1 -> unaligned lwl/lwr copy */
extern void func_8014C6F4(void *);
extern void func_80155150(void *);
extern void func_801470C0(s32);
extern void func_80147478(s32);
extern void func_80147118(s32);
extern void func_8014BDE8(s32);
extern short func_801508F8(s32);
extern void func_8014B5B0(s32*);
extern void func_80161D88(void *);
extern s32 D_80126B58;
extern s32 *D_80126B78;
extern u16 D_80126B5E;
extern u16 D_80126B62;
extern u16 D_80126B66;
extern u16 D_80126C90;
extern u16 D_80126C92;
extern u16 D_80126C94;
extern s32 D_80126B9C;
extern s32 D_80126BA0;
extern u16 D_80126BE0;
extern u16 D_80126BE8;
extern u16 D_80126BE2;
extern u16 D_80126BE4;
extern short D_80126C9E;
void func_801463A0(void) {
int iVar1;
short sVar2;
iVar1 = (int)D_80126B78;
func_8014C6F4(&D_80126B58);
func_80155150(&D_80126B58);
((void (*)(void *))func_801470C0)(&D_80126B58);
((void (*)(void *))func_80147478)(&D_80126B58);
((void (*)(void *))func_80147118)(&D_80126B58);
if (iVar1 != 0) {
sVar2 = D_80126B5E + D_80126C90;
*(short *)(iVar1 + 8) = sVar2;
*(int *)(iVar1 + 0x48) = (int)sVar2;
sVar2 = D_80126B62 + D_80126C92;
*(short *)(iVar1 + 0xA) = sVar2;
*(int *)(iVar1 + 0x4C) = (int)sVar2;
sVar2 = D_80126B66 + D_80126C94;
*(short *)(iVar1 + 0xC) = sVar2;
*(unsigned short *)(iVar1 + 0x2C) = *(unsigned short *)(iVar1 + 0x2C) | 0x11;
*(int *)(iVar1 + 0x50) = (int)sVar2;
}
((void (*)(void *))func_8014BDE8)(&D_80126B58);
*(M8_801463A0 *)&D_80126BE8 = *(M8_801463A0 *)&D_80126BE0;
D_80126BE0 = D_80126B5E;
D_80126BE2 = D_80126B62;
D_80126BE4 = D_80126B66;
D_80126BA0 = D_80126B9C;
D_80126B9C = D_80126B9C & 0x3fffffff;
((void (*)(void *))func_801508F8)(&D_80126B58);
D_80126C9E = 0;
((void (*)(void *))func_8014B5B0)(&D_80126B58);
func_80161D88(&D_80126B58);
}
+26
View File
@@ -2875,3 +2875,29 @@ conditional) · main-EXE/B9 + GLM/B6 + resident's 14 walls (P30) · behemoths B7
correct inline `lwl/lwr` shape. **Residual: 100 vs 101 ins, 36 mismatched — register assignment
(`$a3/$a1` vs the target's `$a1/$a0`) plus one folded instruction.** That is a NORMAL near-miss now,
permuter-shaped, not a link failure. Fixed draft preserved: `.run/giants/s17_func_801463A0_symfix.c`.
- **🔎 2026-07-24 (SESSION-17) — `func_801463A0` driven from "gate rejects, cause unknown" to a
MASKED-MATCH with ONE named blocker left. Not banked; the remaining step is a documented §H antidote.**
Three byte-measured iterations, each falsifying the previous hypothesis:
| variant | decls | result |
|---|---|---|
| original | `_s` aliases (undefined symbols) | rtu MATCH, gate reject — **the symbol set was missing `D_80126BE8`** |
| struct-typed `&sym` | `extern M8 D_80126BE0;` | 100 vs 101 ins, 36 mismatched |
| array-decay + cast-at-use | `extern u8 D_80126BE0[];` | 100 vs 101, 36 — **identical**, so decay was not the lever |
| **direct-symbol scalar** | `extern u16 D_80126BE0;` | **MATCH (101 ins)** ✅ |
**WHY the length differed (byte-read at idx 76–81):** the target **re-materializes `lui $at,%hi(sym)`
at every scalar store** (2 ins each); the array/struct forms let gcc CSE the address into `$a3` once
and store in 1 — so my drafts were exactly one instruction short. The direct-symbol form restores the
per-store materialization.
**THE REMAINING BLOCKER, named:** in the REAL TU `D_80126BE0`'s canonical decl is
`extern u8 D_80126BE0[];` — and it lives **inside a `DEFINE_func_*` macro body** in
`engine_core.h:19813`. So the `u16` form that MATCHES standalone gives `conflicting types for
D_80126BE0` in the TU (real cc1, via `rtu_match --stderr-out`).
**⇒ Two exits, and the cheap one is a trap:** `demacroize` would clear it but banks **×1** (+101 ins,
~0.001pp) and forfeits the ×138 — **not worth it** for this function. The right exit is the
**§H CSE address-fold antidote** (`gcc-2.7.2-map/cse_expr.md` §H): a **balanced if/else diamond**
whose label is barrier-preceded makes cse start a FRESH table, killing the fold with **zero asm**, so
the canonical `u8[]` decl can stay and the bank propagates **×138 (+13,938 ins)**. That is the next
move on it — deliberate, function-specific work, not a guess.
Preserved: `.run/giants/s17_func_801463A0_match101.c` (the standalone-MATCH form) +
`s17_func_801463A0_symfix.c` (the symbol-corrected form).