phase12: track verified func_80042E10 source
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* func_80042E10 — 88 bytes at 0x80042E10..0x80042E68
|
||||
*
|
||||
* PHASE 12 RESUME LANE C (autonomous matching). Row from the UN-ATTEMPTED band
|
||||
* (negatives-d-unattempted.tsv) filtered through config/function_extents.tsv
|
||||
* (size 88 grade exact term=jr_ra). NOT previously in the ledger.
|
||||
*
|
||||
* MATCH: candidate_bytes=88, differing_bytes=0, result=MATCH, exit 0 on the DEFAULT toolchain
|
||||
* (tools/old-gcc/gcc-2.7.2-psx/cc1). No region overrides.
|
||||
*
|
||||
* Hypothesis, not a claim about meaning: `a2` is a BIT count; `n = a2 >> 5` is the word index at
|
||||
* which the range ends. Walk words `n` down to `0` of two same-sized arrays and count how many
|
||||
* satisfy `(x & y) == y`; report whether ALL `n + 1` of them do. Used with `n` = the last word the
|
||||
* two bit maps share, this is a "is every remaining bit of x present in y" test.
|
||||
*
|
||||
* Original words (22):
|
||||
* 00063143 sra a2,a2,0x5 n = a2 >> 5
|
||||
* 00C03821 move a3,a2 i = n
|
||||
* 00004021 move t0,zero count = 0
|
||||
* 2409FFFF li t1,-1 ---- the end value lives in a REGISTER ----
|
||||
* 00061080 sll v0,a2,0x2
|
||||
* 00A22821 addu a1,v0,a1 a1 += n * 4
|
||||
* 00A22021 addu a0,v0,a0 a0 += n * 4
|
||||
* $L: 8C820000 lw v0,0(a0)
|
||||
* 8CA30000 lw v1,0(a1)
|
||||
* 00000000 nop
|
||||
* 00431024 and v0,v0,v1
|
||||
* 14430002 bne v0,v1,0x80042e48 if ((x & y) != y) skip the count
|
||||
* 00000000 nop
|
||||
* 25080001 addiu t0,t0,1 count++
|
||||
* 24A5FFFC addiu a1,a1,-4
|
||||
* 24E7FFFF addiu a3,a3,-1 i-- <-- INSIDE the loop body
|
||||
* 14E9FFF6 bne a3,t1,0x80042e2c <-- tested AFTER the decrement, against t1
|
||||
* 2484FFFC addiu a0,a0,-4 (delay slot)
|
||||
* 24C20001 addiu v0,a2,1 n + 1
|
||||
* 01021026 xor v0,t0,v0
|
||||
* 03E00008 jr ra
|
||||
* 2C420001 sltiu v0,v0,1 (count ^ (n + 1)) < 1 == count == n + 1
|
||||
*
|
||||
* THE LEVER: THE LOOP MUST BE A DO-WHILE WHOSE DECREMENT IS IN THE CONDITION, COUNTING DOWN TO -1.
|
||||
* The natural `for (i = n; i >= 0; i--)` spelling is 88 bytes with 16 differing bytes: it emits
|
||||
* `bltz a3,<exit>` and NEVER materialises -1, because gcc tests `i >= 0` with a register-immediate
|
||||
* branch. Writing
|
||||
* i = n; count = 0;
|
||||
* do { ... body ...; i--; } while (i != -1);
|
||||
* makes gcc hoist `li t1,-1` BEFORE the loop and test `bne a3,t1` after the decrement, which is
|
||||
* the original's form byte-for-byte. (The `for (i = n; i != -1; i--)` spelling is NOT equivalent
|
||||
* here: it is 96 bytes, because a for-loop's test is placed at the top.) **The `li <reg>,-1` +
|
||||
* `bne` pair is therefore a fingerprint of a do-while countdown to -1, not of a `!= -1` condition
|
||||
* written in any loop form** -- the same fingerprint appears in 0x800A86B4, where the natural `i >= 0`
|
||||
* spelling also emits `bgez` and one induction variable instead of the original's two pointers.
|
||||
* SECOND, SMALLER: the statement order matters -- `i = n;` must precede `count = 0;` for the
|
||||
* prologue (`sra` / `move a3,a2` / `move t0,zero` / `li t1,-1`) to line up.
|
||||
*
|
||||
* LIMITS: `a2` is treated as a bit count (`>> 5`) because only that makes the `* 4` byte scaling
|
||||
* consistent, and the two arrays are assumed to be bit maps of the same size; neither is
|
||||
* independently evidenced. The `==` is compiled to `(a ^ b) < 1` (gcc's equality idiom for this
|
||||
* shape), which is why the source's `count == n + 1` does not appear as a `beq`.
|
||||
*/
|
||||
|
||||
int func_80042E10(int a0, int a1, int a2)
|
||||
{
|
||||
int n = a2 >> 5;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
i = n;
|
||||
count = 0;
|
||||
do {
|
||||
if ((*(int *)(a0 + i * 4) & *(int *)(a1 + i * 4)) == *(int *)(a1 + i * 4))
|
||||
count++;
|
||||
i--;
|
||||
} while (i != -1);
|
||||
return count == n + 1;
|
||||
}
|
||||
Reference in New Issue
Block a user