phase9: merge B 0x80057B84 — 399 regions / 390 distinct bodies

B's family-target scan paid off a 3rd time: 0x80057B84 = the family's 4th
member, matched on the 2nd attempt with two levers — (1) branch-vs-
branchless discriminator (how many distinct values are selected decides
the spelling), (2) the mask must be INLINED not held in a local (here the
repeated expression is correct and the local is the mistake — mirror
image of the usual named-locals lever). Two negatives recorded
(0x800179E0 guard polarity, 0x800C1E54 dead local). Gate MATCH whole-
binary SHA-1 e173426c157384ebf1b6caf8c6fea18a85a14af9.
This commit is contained in:
Christopher Williams
2026-09-24 02:44:59 -04:00
parent 1d3a307ea8
commit 21f5fa6695
2 changed files with 58 additions and 0 deletions
+1
View File
@@ -157,6 +157,7 @@
0x800579A0 0x800579F0 src/func_800579A0.c
0x800579F0 0x80057A40 src/func_800579F0.c
0x80057AE0 0x80057B30 src/func_80057AE0.c
0x80057B84 0x80057BE8 src/func_80057B84.c
0x80057C30 0x80057C80 src/func_80057C30.c
0x80057DFC 0x80057E04 src/func_80057DFC.c
0x80058230 0x80058288 src/func_80058230.c
1 # Code-region registry: one C region per matched function.
157 0x800579A0
158 0x800579F0
159 0x80057AE0
160 0x80057B84
161 0x80057C30
162 0x80057DFC
163 0x80058230
+57
View File
@@ -0,0 +1,57 @@
/* func_80057B84 — 0x80057B84..0x80057BE8 (100 bytes).
*
* Fourth member of the 0x80057xxx argument-block family, and the one that differs
* structurally from its three matched siblings.
*
* Original words:
* 27BDFFD0 addiu sp,sp,-48
* 30A300FF andi v1,a1,0xff
* 0003102B sltu v0,zero,v1
* 00021023 negu v0,v0
* 93A80040 lbu t0,64(sp) the FIFTH incoming parameter
* 00C24824 and t1,a2,v0 t1 = a2 & mask (a2 or 0)
* 10600003 beqz v1,0x80057BAC
* AFBF0028 _sw ra,40(sp) (delay slot)
* 08015EEC j 0x80057BB0
* AFA70010 _sw a3,16(sp) (delay slot) outgoing arg 5 = a3
* AFA00010 sw zero,16(sp) <- 0x80057BAC, outgoing arg 5 = 0
* 30A200FF andi v0,a1,0xff
* 24050012 li a1,18
* 2406FFFF li a2,-1
* 01203821 move a3,t1
* AFA00014 sw zero,20(sp) outgoing arg 6 = 0
* AFA00018 sw zero,24(sp) outgoing arg 7 = 0
* AFA0001C sw zero,28(sp) outgoing arg 8 = 0
* AFA20020 sw v0,32(sp) outgoing arg 9 = narrowed a1
* 0C015D99 jal 0x80057664
* AFA80024 _sw t0,36(sp) (delay slot) outgoing arg 10 = the fifth parameter
*
* **THE BRANCH IS THE TELL, AND IT DISTINGUISHES THIS ROW FROM ITS SIBLINGS.** The three
* matched members select between `a0` and zero, which cc1 compiles **branchlessly** with
* `sltu`+`negu`+`and`. Here **two different values** are selected — outgoing arg 4 is `a2`
* or zero and outgoing arg 5 is `a3` or zero — so the same mask is built for arg 4 while
* arg 5 needs a real `beqz`/`j` pair. So the family contains both spellings, and which one a
* row uses is decided by *how many distinct values are selected*, not by the author's style:
* one value → branchless, two values → one branch. That is a cheap discriminator for the
* remaining rows in this family.
*
* The mask is still built with `sltu`+`negu` (the 0-or-−1 trick) and `negu` appears once
* more, consistent with the toolchain evidence this family has been accumulating.
*
* The callee's ten arguments are: the routine's `a0`, the selector 18, −1, `a2 or 0`,
* `a3 or 0`, three zeros, then the narrowed `a1` and the fifth parameter on the stack.
*
* LIMITS: the selector 18, the mask 0xff and the frame layout are read from the bytes. The
* fifth parameter is `unsigned char` by the single `lbu`. As in the siblings, the outgoing
* argument area is directly visible — six words at 16–36(sp) with `ra` at 40 — so the
* ten-argument model is checkable by arithmetic rather than inferred.
*/
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_80057B84(int a0, int a1, int a2, int a3, unsigned char a4)
{
func_80057664(a0, 18, -1, (a1 & 0xff) ? a2 : 0, (a1 & 0xff) ? a3 : 0, 0, 0, 0,
a1 & 0xff, a4);
}