phase11: merge 58 — worker E's 0x80027D88 -> 598 bodies / 607 regions, TWO to the milestone

This commit is contained in:
Christopher Williams
2026-09-24 11:30:55 -04:00
parent 7a93946795
commit eeaaf5b059
2 changed files with 72 additions and 0 deletions
+1
View File
@@ -104,6 +104,7 @@
0x800276B0 0x800276D4 src/func_800276B0.c
0x80027C44 0x80027CA0 src/func_80027C44.c
0x80027CA0 0x80027D00 src/func_80027CA0.c
0x80027D88 0x80027E1C src/func_80027D88.c
0x80027E1C 0x80027ECC src/func_80027E1C.c
0x80028150 0x800281A4 src/func_80028150.c
0x800281A4 0x800281E4 src/func_800281A4.c
1 # Code-region registry: one C region per matched function.
104 0x800276B0
105 0x80027C44
106 0x80027CA0
107 0x80027D88
108 0x80027E1C
109 0x80028150
110 0x800281A4
+71
View File
@@ -0,0 +1,71 @@
/*
* func_80027D88 — 148 bytes at 0x80027D88..0x80027E1C
*
* Take the component-wise absolute difference of two 3-int vectors, keep the LARGEST, and store
* `largest + ((middle + smallest) >> 2)` through the third pointer. Returns 0.
* **First spelling, default toolchain.**
*
* lw a3,0(a0) / lw v0,0(a1) x = a0[0] - a1[0] ...
* subu v1,a3,v0
* bgez v1,SKIP / nop
* subu v1,v0,a3 ... and if (x < 0) x = a1[0] - a0[0];
* (the same pair for element 1 and for element 2, into t0 and a3)
* slt v0,v1,t0 / beqz SKIP / move v0,v1 / move v1,t0 / move t0,v0
* if (x < y) { t = x; x = y; y = t; }
* slt v0,v1,a3 / beqz SKIP / nop / move v0,v1 / move v1,a3 / move a3,v0
* if (x < z) { t = x; x = z; z = t; }
* addu v0,t0,a3 / sra v0,v0,2 / addu v0,v1,v0
* *a2 = x + ((y + z) >> 2);
* sw v0,0(a2) / jr ra / move v0,zero
*
* TWO COOKBOOK LEVERS DECIDE THIS ROW, AND BOTH ARE THE "OBVIOUS" SPELLING'S OPPOSITE:
*
* 1. **THE ABSOLUTE VALUE IS A SWAPPED SUBTRACTION, NOT A NEGATION.** The emitted second
* operation is `subu v1,v0,a3` -- a subtraction with the operands exchanged -- not `negu`.
* Writing `if (x < 0) x = -x;` emits `negu` and does not match; writing
* `if (x < 0) x = a1[0] - a0[0];` does, because the two operands are still in registers from
* the first subtraction and the recomputation is CSE'd away. This is cookbook 101's lever, and
* it is worth stating again because a `negu` here is the single most natural thing to write.
* 2. **THE `>> 2` MUST BE A SHIFT, NOT A DIVISION.** The emitted rounding is the BARE
* `sra v0,v0,2` with no sign bias. `(y + z) / 4` makes cc1 emit the `addiu ...,3` bias
* (cookbook 97: a power-of-two division is not a shift), so the source has `>> 2`. The values
* happen to be non-negative, but cc1 cannot know that after a conditional, so the absence of
* the bias is the evidence.
*
* The partition keeps the largest in the FIRST slot: the two compares are `x < y` and `x < z`,
* performed in that order, and the swaps are the three-move form (`move v0,v1 / move v1,t0 /
* move t0,v0`) exactly as emitted.
*
* LIMITS: this is a leaf with no frame and no call, so the instruction SET is the only structure
* available -- the three pointers are typed `int *` because every access is a full word, the two
* source vectors are the first and second parameters and the destination the third, and the
* `>> 2` scaling is read off the shift. The purpose (a distance or error metric, most plausibly) is
* a hypothesis from the shape, not evidence. The return value is always 0.
*/
int func_80027D88(int *a0, int *a1, int *a2)
{
int x, y, z, t;
x = a0[0] - a1[0];
if (x < 0) x = a1[0] - a0[0];
y = a0[1] - a1[1];
if (y < 0) y = a1[1] - a0[1];
z = a0[2] - a1[2];
if (z < 0) z = a1[2] - a0[2];
if (x < y) {
t = x;
x = y;
y = t;
}
if (x < z) {
t = x;
x = z;
z = t;
}
*a2 = x + ((y + z) >> 2);
return 0;
}