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:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user