diff --git a/config/regions.tsv b/config/regions.tsv index bea4544..10bf42b 100644 --- a/config/regions.tsv +++ b/config/regions.tsv @@ -153,8 +153,10 @@ 0x80057524 0x80057564 src/func_80057524.c 0x80057748 0x80057798 src/func_80057748.c 0x80057798 0x800577E8 src/func_80057798.c +0x800577E8 0x8005784C src/func_800577E8.c 0x8005784C 0x8005789C src/func_8005784C.c 0x8005789C 0x800578EC src/func_8005789C.c +0x800578EC 0x80057950 src/func_800578EC.c 0x80057950 0x800579A0 src/func_80057950.c 0x800579A0 0x800579F0 src/func_800579A0.c 0x800579F0 0x80057A40 src/func_800579F0.c diff --git a/src/func_800577E8.c b/src/func_800577E8.c new file mode 100644 index 0000000..1f72e20 --- /dev/null +++ b/src/func_800577E8.c @@ -0,0 +1,55 @@ +/* func_800577E8 — member of the 0x80057xxx argument-block family (selector 2), partition c. + * + * Original words (the family's two-selected-value variant): + * 27BDFFD0 addiu sp,sp,-48 + * AFBF0028 sw ra,40(sp) + * 30A300FF andi v1,a1,0xff + * 0003102B sltu v0,zero,v1 + * 00021023 negu v0,v0 + * 10600003 beqz v1, + * xxxxxxxx _and t0,a0,v0 (delay slot) + * 08015E45 j + * xxxxxxxx _sw a2,16(sp) (delay slot) outgoing arg 5 + * 10600003 sw zero,16(sp) <- skip + * ... + * 30A200FF andi v0,a1,0xff + * AFA20020 sw v0,32(sp) outgoing arg 9 = narrowed a1 + * 30E200FF andi v0,a3,0xff + * 24050002 li a1,2 the selector + * 2406FFFF li a2,-1 + * 01003821 move a3,t0 outgoing arg 4 + * 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 + * 0C015D99 jal 0x80057664 + * AFA20024 _sw v0,36(sp) (delay slot) outgoing arg 10 = narrowed a3 + * + * **This is the family's TWO-selected-value form, and the branch confirms the discriminator.** + * Siblings that select a single value against zero compile branchlessly with sltu+negu+and; this + * one selects **two** — outgoing arg 4 is a0 and arg 5 is a2, each against zero under + * the same mask — so cc1 emits a real beqz/j pair. The mask itself is still built with sltu+negu, + * and `negu` appears once more, consistent with the family's accumulating toolchain evidence. + * + * Note the outgoing arg 5 is written **inside the branch pair** (once with the value, once as + * zero), so the two-selected-value shape costs a branch rather than a mask per argument. + * + * Stable family positions hold here: selector -> arg 2, sentinel -> arg 3, narrowed a1 -> arg 9. + * This row additionally narrows **a3** into arg 10, where the standard form puts a second narrowed + * parameter or an incoming stack parameter — so arg 10 is a stable *position* with a per-row + * *source*. + * + * LIMITS: the selector 2, 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. The callee is named for its + * address and the ten-argument map is derived from the frame arithmetic, which is checkable + * because the outgoing area is the six words at 16-36(sp) with ra at 40. + */ + +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_800577E8(int a0, int a1, int a2, int a3) +{ + func_80057664(a0, 2, -1, (a1 & 0xff) ? a0 : 0, (a1 & 0xff) ? a2 : 0, 0, 0, + 0, a1 & 0xff, a3 & 0xff); +} diff --git a/src/func_800578EC.c b/src/func_800578EC.c new file mode 100644 index 0000000..66e5cd7 --- /dev/null +++ b/src/func_800578EC.c @@ -0,0 +1,55 @@ +/* func_800578EC — member of the 0x80057xxx argument-block family (selector 7), partition a. + * + * Original words (the family's two-selected-value variant): + * 27BDFFD0 addiu sp,sp,-48 + * AFBF0028 sw ra,40(sp) + * 30A300FF andi v1,a1,0xff + * 0003102B sltu v0,zero,v1 + * 00021023 negu v0,v0 + * 10600003 beqz v1, + * xxxxxxxx _and t0,a2,v0 (delay slot) + * 08015E45 j + * xxxxxxxx _sw a0,16(sp) (delay slot) outgoing arg 5 + * 10600003 sw zero,16(sp) <- skip + * ... + * 30A200FF andi v0,a1,0xff + * AFA20020 sw v0,32(sp) outgoing arg 9 = narrowed a1 + * 30E200FF andi v0,a3,0xff + * 24050007 li a1,7 the selector + * 2406FFFF li a2,-1 + * 01003821 move a3,t0 outgoing arg 4 + * 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 + * 0C015D99 jal 0x80057664 + * AFA20024 _sw v0,36(sp) (delay slot) outgoing arg 10 = narrowed a3 + * + * **This is the family's TWO-selected-value form, and the branch confirms the discriminator.** + * Siblings that select a single value against zero compile branchlessly with sltu+negu+and; this + * one selects **two** — outgoing arg 4 is a2 and arg 5 is a0, each against zero under + * the same mask — so cc1 emits a real beqz/j pair. The mask itself is still built with sltu+negu, + * and `negu` appears once more, consistent with the family's accumulating toolchain evidence. + * + * Note the outgoing arg 5 is written **inside the branch pair** (once with the value, once as + * zero), so the two-selected-value shape costs a branch rather than a mask per argument. + * + * Stable family positions hold here: selector -> arg 2, sentinel -> arg 3, narrowed a1 -> arg 9. + * This row additionally narrows **a3** into arg 10, where the standard form puts a second narrowed + * parameter or an incoming stack parameter — so arg 10 is a stable *position* with a per-row + * *source*. + * + * LIMITS: the selector 7, 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. The callee is named for its + * address and the ten-argument map is derived from the frame arithmetic, which is checkable + * because the outgoing area is the six words at 16-36(sp) with ra at 40. + */ + +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_800578EC(int a0, int a1, int a2, int a3) +{ + func_80057664(a0, 7, -1, (a1 & 0xff) ? a2 : 0, (a1 & 0xff) ? a0 : 0, 0, 0, + 0, a1 & 0xff, a3 & 0xff); +}