phase9: merge B 3 (selectors 9/12/13) — 407 regions / 398 distinct bodies

B 9-for-9 across the family batches. 0x80057B30 has TWO incoming stack
params; the family-set lever's scope limit sharpened: stable positions
(selector->arg2, sentinel->arg3, a1->arg9, extra->arg10) + per-row
positions elsewhere — the map proves once for the STANDARD form only, and
B corrected its own earlier 'map proves once' framing (belongs in the
cookbook with the lever). Two more 100-byte callers (0x800578EC,
0x800577E8) in flight for margin. Gate MATCH whole-binary SHA-1
e173426c157384ebf1b6caf8c6fea18a85a14af9.
This commit is contained in:
Christopher Williams
2026-09-24 02:53:15 -04:00
parent f8f26b2cf9
commit d0c655c869
4 changed files with 107 additions and 0 deletions
+3
View File
@@ -155,9 +155,12 @@
0x80057798 0x800577E8 src/func_80057798.c
0x8005784C 0x8005789C src/func_8005784C.c
0x8005789C 0x800578EC src/func_8005789C.c
0x80057950 0x800579A0 src/func_80057950.c
0x800579A0 0x800579F0 src/func_800579A0.c
0x800579F0 0x80057A40 src/func_800579F0.c
0x80057A40 0x80057A90 src/func_80057A40.c
0x80057AE0 0x80057B30 src/func_80057AE0.c
0x80057B30 0x80057B84 src/func_80057B30.c
0x80057B84 0x80057BE8 src/func_80057B84.c
0x80057BE8 0x80057C30 src/func_80057BE8.c
0x80057C30 0x80057C80 src/func_80057C30.c
1 # Code-region registry: one C region per matched function.
155 0x80057798
156 0x8005784C
157 0x8005789C
158 0x80057950
159 0x800579A0
160 0x800579F0
161 0x80057A40
162 0x80057AE0
163 0x80057B30
164 0x80057B84
165 0x80057BE8
166 0x80057C30
+27
View File
@@ -0,0 +1,27 @@
/* func_80057950 — eighth/ninth member of the 0x80057xxx argument-block family (selector 9).
*
* Structurally identical to the already matched members: a 48-byte frame whose six words at
* 16-36(sp) are the outgoing argument area, a branchless 0-or--1 mask built with sltu+negu so
* that exactly ONE value is conditionally selected, the narrowed second argument placed in
* outgoing arg 9 and the other narrowed argument in arg 10, and the selector in the second
* register argument.
*
* Because the branchless form is present, the family's discriminator says exactly one distinct
* value is selected here — as against 0x80057B84, which selects two and needs a real branch.
*
* LIMITS: the selector 9, the mask 0xff and the frame layout are read from the bytes; what
* the selector selects is not observable from this body. That it IS a selector follows from the
* family's byte-identical siblings differing only in this constant — now several such pairs.
* The callee is named for its address.
*/
void func_80057664(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
int a8, int a9);
void func_80057950(int a0, int a1, int a2)
{
int narrowed1 = a1 & 0xff;
int narrowed2 = a2 & 0xff;
func_80057664(a0, 9, -1, narrowed1 ? a0 : 0, 0, 0, 0, 0, narrowed1, narrowed2);
}
+27
View File
@@ -0,0 +1,27 @@
/* func_80057A40 — eighth/ninth member of the 0x80057xxx argument-block family (selector 12).
*
* Structurally identical to the already matched members: a 48-byte frame whose six words at
* 16-36(sp) are the outgoing argument area, a branchless 0-or--1 mask built with sltu+negu so
* that exactly ONE value is conditionally selected, the narrowed second argument placed in
* outgoing arg 9 and the other narrowed argument in arg 10, and the selector in the second
* register argument.
*
* Because the branchless form is present, the family's discriminator says exactly one distinct
* value is selected here — as against 0x80057B84, which selects two and needs a real branch.
*
* LIMITS: the selector 12, the mask 0xff and the frame layout are read from the bytes; what
* the selector selects is not observable from this body. That it IS a selector follows from the
* family's byte-identical siblings differing only in this constant — now several such pairs.
* The callee is named for its address.
*/
void func_80057664(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
int a8, int a9);
void func_80057A40(int a0, int a1, int a2)
{
int narrowed1 = a1 & 0xff;
int narrowed2 = a2 & 0xff;
func_80057664(a0, 12, -1, narrowed1 ? a0 : 0, 0, 0, 0, 0, narrowed1, narrowed2);
}
+50
View File
@@ -0,0 +1,50 @@
/* func_80057B30 — 0x80057B30..0x80057B84 (84 bytes). Tenth member of the 0x80057xxx family
* (selector 13), and a variant whose REGISTER argument positions differ from the standard form.
*
* Original words:
* 27BDFFD0 addiu sp,sp,-48
* 8FA20040 lw v0,64(sp) fifth incoming parameter (a WORD)
* 93A30044 lbu v1,68(sp) sixth incoming parameter (a BYTE)
* 30A500FF andi a1,a1,0xff
* AFA50020 sw a1,32(sp) outgoing arg 9 = narrowed a1
* 0005282B sltu a1,zero,a1
* 00052823 negu a1,a1
* AFA70014 sw a3,20(sp) outgoing arg 6 = a3
* 00C53824 and a3,a2,a1 outgoing arg 4 = a2 & mask
* 2405000D li a1,13 the selector
* 2406FFFF li a2,-1
* AFBF0028 sw ra,40(sp)
* AFA00010 sw zero,16(sp) outgoing arg 5 = 0
* AFA00018 sw zero,24(sp) outgoing arg 7 = 0
* AFA2001C sw v0,28(sp) outgoing arg 8 = the fifth parameter
* 0C015D99 jal 0x80057664
* AFA30024 _sw v1,36(sp) (delay slot) outgoing arg 10 = the sixth parameter
*
* Two incoming stack parameters, one a word and one an unsigned byte, and a masked argument
* whose **value is `a2` rather than `a0`** — so this member forwards a different source into
* arg 4 than the standard form does, while keeping the narrowed `a1` at arg 9 and the extra
* parameter at arg 10.
*
* The argument map therefore has **stable** positions (narrowed `a1` -> arg 9, the extra
* parameter -> arg 10, the selector -> arg 2, the sentinel -> arg 3) and **per-row** positions
* for everything else. That is the scope limit on the family-set lever, and it is why each
* member's register arguments are read rather than assumed even though the derivation method
* transfers.
*
* The `lw`/`lbu` pair at 64 and 68(sp) are the fifth and sixth incoming arguments, read before
* anything else — the frame is 48 bytes so the incoming area begins at 64(sp).
*
* LIMITS: the selector 13, the mask 0xff, the displacements and the frame layout are read from
* the bytes. The sixth parameter is `unsigned char` by the single `lbu`; the fifth is a word by
* `lw`. Nothing establishes what the selector selects.
*/
void func_80057664(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
int a8, int a9);
void func_80057B30(int a0, int a1, int a2, int a3, int a4, unsigned char a5)
{
int narrowed1 = a1 & 0xff;
func_80057664(a0, 13, -1, narrowed1 ? a2 : 0, 0, a3, 0, a4, narrowed1, a5);
}