phase12: match func_80013024 (745 bodies / 754 regions)

This commit is contained in:
Christopher Williams
2026-09-25 10:39:10 -04:00
parent 03a6041e4f
commit e9f46c00c4
5 changed files with 1078 additions and 958 deletions
+949 -952
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -26,6 +26,7 @@
0x80012DBC 0x80012DE8 src/func_80012DBC.c
0x80012DE8 0x80012E84 src/func_80012DE8.c
0x80012F24 0x80012F80 src/func_80012F24.c
0x80013024 0x80013114 src/func_80013024.c
0x800139E4 0x80013AF0 src/func_800139E4.c
0x80013AF0 0x80013B80 src/func_80013AF0.c
0x80013B80 0x80013C88 src/func_80013B80.c
@@ -450,6 +451,7 @@
0x8008F508 0x8008F530 src/func_8008F508.c
0x8008FF58 0x8008FF84 src/func_8008FF58.c
0x8008FF84 0x8008FFC4 src/func_8008FF84.c
0x8008FFC4 0x80090028 src/func_8008FFC4.c
0x80090028 0x80090048 src/func_80090028.c
0x80090048 0x80090058 src/func_80090048.c
0x800900A0 0x800900CC src/func_800900A0.c
@@ -733,6 +735,7 @@
0x80107B20 0x80107B38 src/func_80107B20.c
0x80107C5C 0x80107CCC src/func_80107C5C.c maspsx=nopmarker
0x80107CCC 0x80107D18 src/func_80107CCC.c cc1bin=gcc-2.8.1-psx
0x80107D18 0x80107D7C src/func_80107D18.c
0x80107DE8 0x80107E68 src/func_80107DE8.c maspsx=epilogue
0x80107E68 0x80107E74 src/func_80107E68.c
0x80107E74 0x80107E84 src/func_80107E74.c
1 # Code-region registry: one C region per matched function.
26 0x80012DBC
27 0x80012DE8
28 0x80012F24
29 0x80013024
30 0x800139E4
31 0x80013AF0
32 0x80013B80
451 0x8008F508
452 0x8008FF58
453 0x8008FF84
454 0x8008FFC4
455 0x80090028
456 0x80090048
457 0x800900A0
735 0x80107B20
736 0x80107C5C
737 0x80107CCC
738 0x80107D18
739 0x80107DE8
740 0x80107E68
741 0x80107E74
+6 -6
View File
@@ -6,11 +6,11 @@
## STATE — SOLO CONTINUATION, 2026-09-24 (current)
**742 bodies / 751 regions**, from 685 / 694 at the last session stop — **+57 bodies / +57 regions**.
The Phase 12 milestone remains 750 bodies, so **+8 remains**. The promoted whole-binary gate is green:
`c_regions=751`, `differing_bytes=0`, SHA-1
**745 bodies / 754 regions**, from 685 / 694 at the last session stop — **+60 bodies / +60 regions**.
The Phase 12 milestone remains 750 bodies, so **+5 remains**. The promoted whole-binary gate is green:
`c_regions=754`, `differing_bytes=0`, SHA-1
`e173426c157384ebf1b6caf8c6fea18a85a14af9`; 348 synthetic tests pass and extents report
`regions=751 disagreements=0 result=AGREE`.
`regions=754 disagreements=0 result=AGREE`.
The requested second batch of 20 is complete. Twenty additional bodies are now matched:
`0x800BC9C4`, `0x800BC8C4`, `0x8006BB0C`, `0x8002D17C`, `0x801029A0`, `0x80055958`,
@@ -23,8 +23,8 @@ not a correctness issue because the 724-region gate proves the registry simultan
Final clean verification (2026-09-25): `make clean && make all`, `make worklist`,
`make extents-verify`, and `make check` all exited 0. Both clean assembly and code rebuilds
matched the USA executable byte-for-byte; each is 1,886,208 bytes with SHA-1
`e173426c157384ebf1b6caf8c6fea18a85a14af9`. The final worklist is 952 rows and the extents
check reports `regions=751 disagreements=0 result=AGREE`.
`e173426c157384ebf1b6caf8c6fea18a85a14af9`. The final worklist is 949 rows and the extents
check reports `regions=754 disagreements=0 result=AGREE`.
## STATE — SESSION STOP, 2026-09-24 23:35 (historical; superseded by the state above, kept for provenance)
**685 bodies / 694 regions**, from 602 / 611 at the Phase 11 close — **+83 bodies**. **Milestone 750 was NOT
+11
View File
@@ -2619,6 +2619,17 @@ passed with 348 tests and extents `regions=742 disagreements=0`; worklist regene
**Count after task 44: 742 bodies / 751 regions (+140 bodies from the Phase 12 open baseline;
+8 remain to milestone 750).**
### Worker C task 45 — `0x80013024` MATCH
* Exact extent `0x80013024..0x80013114`, 240 bytes, default toolchain.
* The list walk required an `int` counter local, a named `f20` base with scaling in the binding,
and a named base to prevent reloads around the `f12` store.
* Fresh range and candidate whole-binary gate passed with zero differences; `make check` passed with
348 tests and extents `regions=754 disagreements=0`; worklist is 949 rows.
**Count after task 45: 745 bodies / 754 regions (+143 bodies from the Phase 12 open baseline;
+5 remain to milestone 750).**
### Duplicate-claim guard incident
A later autonomous draft attempted `0x8006FAEC`, but the merge check showed that exact region was
+109
View File
@@ -0,0 +1,109 @@
/*
* func_80013024 — 240 bytes at 0x80013024..0x80013114
*
* PHASE 12 RESUME LANE C (autonomous matching). Row from the UN-ATTEMPTED band
* (negatives-b-unattempted.tsv) after the coordinator confirmed the 0x80013xxx addresses are
* OUTSIDE the blocked 0x80012xxx primitive-init family. Extents verified before working it:
* `0x80013024 0x80013114 240 0x80013114 0 exact term=jr_ra`, and no registered region overlaps
* (the next registered row starts at 0x800139E4).
*
* MATCH: candidate_bytes=240, 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: walk the list at D_8012197C; for each element take its
* record, publish two of the record's bytes plus two halfwords taken at an offset derived from a
* signed halfword counter into a four-short block, and call func_800F436C with that block and two
* halfwords of a second record; advance the record's counter, wrapping it to zero when it reaches
* the record's byte field, and finally move to the next list element. Two of the checks RETURN
* (both jump to the shared epilogue), so a record that is unset or whose byte offset has been used
* up abandons the whole walk rather than skipping one element.
*
* RECONSTRUCTED LAYOUT (all offsets read off the instruction stream, not assumed):
* struct Rec { int f0; u8 f4; u8 f5; u8 f6; short f8; int f12; Inner *f16; short *f20; u8 *f24; }
* struct Inner{ short f0; short f2; }
* struct Node { Rec *f0; int f4; Node *f8; }
*
* The levers, in the order they were needed (five candidates measured: 260, 252, 240/2, 240/2, 240):
* 1. **THE COUNTER MUST BE AN `int` LOCAL, NOT A `short`.** `short a1 = r->f8;` makes gcc load the
* field with `lhu` and then SIGN-EXTEND it manually at each use (`sll 16` / `sra 16` = two extra
* instructions, 260 bytes); `int a1 = r->f8;` gives the original's single `lh` and 252 bytes.
* 2. **THE f20 BASE MUST BE ADVANCED IN THE BINDING ITSELF.** `q = r->f20;` then `q[a1 * 2]` /
* `q[a1 * 2 + 1]` is 240 bytes with EXACTLY TWO differing bytes — gcc puts the BASE in v0 and
* the scaled offset in v1, and the original has them the other way round (`sll v0,a1,2` then
* `lw v1,20(s0)`). Writing `q = r->f20 + a1 * 2;` with `q[0]` / `q[1]` is byte-exact. So the
* base/offset register ROLES are decided by whether the scaling is part of the binding or part
* of each index -- the same shape of lever as the named pointer binding recorded in lane C's
* first session, but here it is the ROLES rather than the operand order that it fixes.
* 3. The base MUST be a named local (`short *q = r->f20;`) or gcc RELOADS `r->f20` after the
* `r->f12` store and the row is 8 bytes over: the store between the two halfword reads is enough
* to defeat reuse even though both fields belong to the same object.
* Moving the `r->f12` store after the two reads (d11) is WORSE (8 differing bytes: the store's
* scheduling collapses), so the store's source position is fixed between the check and the reads.
*
* LIMITS: every meaning above is inferred from the instruction stream; the field NAMES are mine.
* `D_8012197C` and `D_80121988` are gp-marked in the registry and the access forms matched without
* an override. The callee `func_800F436C` is unregistered, so this row is DEPENDENT on it; the
* signature used here (a0 = the four-short block, a1/a2 = two signed halfwords) is read from the
* call site only.
*/
struct Inner {
short f0;
short f2;
};
struct Rec {
int f0;
unsigned char f4;
unsigned char f5;
unsigned char f6;
short f8;
int f12;
struct Inner *f16;
short *f20;
unsigned char *f24;
};
struct Node {
struct Rec *f0;
int f4;
struct Node *f8;
};
extern struct Node *D_8012197C;
extern int D_80121988;
extern void func_800F436C(short *v, int a1, int a2);
void func_80013024(void)
{
struct Node *p;
struct Rec *r;
struct Inner *in;
unsigned char *b;
short *q;
short v[4];
int a1;
p = D_8012197C;
while (p != 0) {
r = p->f0;
a1 = r->f8;
v[2] = r->f5 >> 1;
v[3] = r->f6;
b = r->f24;
if (b == 0)
return;
if (D_80121988 < r->f12 + b[a1])
return;
q = r->f20 + a1 * 2;
r->f12 = D_80121988;
v[0] = q[0];
v[1] = q[1];
in = r->f16;
func_800F436C(v, in->f0, in->f2);
r->f8 = r->f8 + 1;
if (r->f8 == r->f4)
r->f8 = 0;
p = p->f8;
}
}