feat(phase-32): T4b (10) — main: func_80011380 (192 ins, boot -O0) BANKED byte-identical 143dbb89 via gate_main — the §474 "PROVED C-level floor" falls: a proved TREE wall is not an RTL wall — (D_80074784 * 2 + 1) * 2 - 2 keeps MULT(PLUS(MULT(i,2),1),2) past fold and the expander's distributive law rebuilds the nested multiply (Fable agent)

- pinned since S76/S79 as PROVED (§474: fold-const.c:882 split_tree merges MULT(MULT(i,2),2) in every C spelling; the two escapes
  each cost one instruction — stupid.c adjacency / expand_decl use-brackets); 20 spellings + statement-expression + register
  temp forms measured; the S83 hand pass measured four block-scoped forms at 193/131
- the mechanism (dumps + source): split_tree only decomposes MULT/PLUS/MINUS and never distributes MULT over PLUS, so
  MULT(PLUS(MULT(i,2),1),2) survives fold; expr.c:5368's EXPAND_SUM distributive law returns (plus (mult (mult X 2) 2) 2);
  both_summands (expr.c:5248) + plus_constant cancel the +2 against the -2 into the bare symbol; memory_address -> force_operand
  expands the two expand_mult copy;sll pairs adjacent (expmed.c:2227/2244) with no note or variable, so stupid.c's born+2
  rule 2-colours v1/a0 exactly as the target and expand_binop's late copy_to_mode_reg(sym) gives la $a0 / addu / lbu 0()
- ruled out from source: a hard-reg pin + shift outer form (191, LENGTH-DRIFT — a REG index makes (plus sym reg) a legitimate
  MIPS address so la/addu vanish: the target's la;addu;lbu shape REQUIRES the index to reach memory_address as a MULT rtx),
  COMPOUND_EXPR shield (fold distributes), SAVE_EXPR via ?:, COND shields, builtin pseudo-constants, pin+MULT
- draft .run/P32/t5x/fable/func_80011380.c; report .run/P32/t5x/reports/func_80011380.md; coordinator rtu_match MATCH 192/192
  in src/boot.c (--o0); gate_main slate_11380: BANKED, 143dbb89 BYTE-IDENTICAL; all 15 jal callees + data-symbol counts equal
- main open 3 -> 2 (func_80032A74 pinned NEAR 1; func_80039308 NEAR 4)
This commit is contained in:
Drew T
2026-09-05 23:21:54 -06:00
parent 395333f233
commit 35fa116741
+87 -1
View File
@@ -725,7 +725,93 @@ s32 func_80011350(void) {
return D_80074784;
}
INCLUDE_ASM("asm/nonmatchings/boot", func_80011380);
extern u8 D_800AF630[];
extern s32 D_80074784;
extern s32 D_8007478C;
extern u16 D_800B99E8;
extern s32 D_800629D4[];
extern u8 D_800629D6[];
extern u16 D_800629E8[];
extern u8 D_800D3A68[];
extern s32 D_800AE6A8;
extern void func_800295D4(void);
extern void func_80029664(void);
extern void func_80011DCC(void);
extern void func_80011E24(void);
extern void func_8005C4CC(s32);
extern void func_8002D4C8(s32, s32);
extern void func_80011B7C(s32);
extern void func_800118AC(void);
extern void func_80011EB4(void);
extern void func_800CEDFC(void);
extern s32 func_80014CAC(s32, s32);
extern void func_80011DA0(void);
extern void func_800D1724(s32);
/* main:func_80011380 (-O0, boot.c) -- the cookbook §474 "PROVED C-level floor" row, cracked (T5x Fable agent).
*
* The target's D_800629D6 index is TWO chained anonymous x2 expansions: lw;copy;sll;copy;sll (expand_mult's
* copy_to_mode_reg + shift, expmed.c:2227/2244, twice, adjacent). §474 proved no TREE can carry MULT(MULT(i,2),2):
* fold-const.c:882 split_tree merges it, and every escape (stmt-expr note, register decl (use) brackets) costs a suid.
* The escape §474 did not consider is that the nested MULT need not exist at TREE level at all. In the EXPAND_SUM
* (address) route, expr.c:5368 "Apply distributive law if OP0 is x+c" rewrites (x + c) * k with x ALREADY a (mult ..)
* rtx into (plus (mult (mult X 2) 2) c*k) -- a nested MULT built AFTER fold, which fold never sees; fold has no
* MULT-over-PLUS distribution, so `(i*2 + 1) * 2` survives as MULT(PLUS(MULT(i,2),1),2). The spurious +2 is cancelled
* by the `- 2` on the index: both_summands (expr.c:5248) + simplify_binary_operation/plus_constant fold sym-2+2 into
* the BARE symbol, so the address is (plus (mult (mult X 2) 2) sym) -> force_operand expands the two multiplies
* back-to-back and expand_binop's copy_to_mode_reg(sym) gives the target's `la $a0; addu $v1,$v1,$a0; lbu $a0,0($v1)`.
* No note, no variable: stupid.c's born+2 rule 2-colours the chain $v1/$a0 exactly as the target. Verified: match_one
* MATCH 192/192 and rtu_match MATCH in src/boot.c (--o0). Semantics: (i*2+1)*2-2 == i*4. */
void func_80011380(void) {
typedef struct {
u8 pad00[0x16];
u8 unk16;
} Unk;
register u8 *p = D_800AF630;
Unk *q = (Unk *)&D_800AE6A8;
switch (*(u16 *)(p + 0xA3B4)) {
case 0:
D_800B99E8 = 0;
func_800295D4();
if (D_80074784 >= 5) {
D_80074784 = 0;
}
*(u16 *)(p + 0xA3D8) = D_800629D4[D_80074784];
*(u16 *)(p + 0xA3DA) = (u16)D_800629D4[D_80074784] & 0xF000;
q->unk16 = D_800629D6[(D_80074784 * 2 + 1) * 2 - 2];
D_8007478C = D_800629E8[D_80074784];
if (D_80074784 == 0) {
func_80029664();
}
func_80011DCC();
func_80011E24();
func_8005C4CC(1);
*(p + 0xA434) = 1;
*(p + 0xA3E0) = 0;
++D_80074784;
func_8002D4C8(0x28, 0);
func_80011B7C(0);
func_800118AC();
break;
case 1:
if (*(p + 0xA3E0) != 0) {
func_80011EB4();
}
func_800CEDFC();
if ((s16)(++D_800B99E8) > D_8007478C ||
((s16)func_80014CAC(0, 0x840) != 0 && *(p + 0xA3E0) != 0)) {
func_80011DA0();
func_800D1724((s32)D_800D3A68);
func_800118AC();
}
break;
case 2:
func_800CEDFC();
break;
}
}
extern u8 D_800AF630[];
extern void func_8002D4C8(s32, s32);