phase12: match func_800379E0 (739 bodies / 748 regions)

This commit is contained in:
Christopher Williams
2026-09-25 10:12:31 -04:00
parent 0f8e71e27d
commit 3532ee80d9
5 changed files with 101 additions and 7 deletions
+2 -2
View File
@@ -959,7 +959,7 @@
952 0x801007E0 0x80100808 40 fallthrough 3 frame 1 - 1
#
# listed=952
# excluded_already_registered=744
# excluded_already_registered=746
# excluded_bad_extent_start=8
# excluded_degenerate_body=252
# excluded_delay_slot_start=5
@@ -968,6 +968,6 @@
# excluded_low_confidence_grade=90
# excluded_named_exclusion=9
# excluded_no_extent=0
# excluded_recorded_negative=84
# excluded_recorded_negative=82
# excluded_restores_unsaved=11
# excluded_trapping_arith=48
1 # Syphon Filter 3 (USA) match worklist.
959 952
960 #
961 # listed=952
962 # excluded_already_registered=744 # excluded_already_registered=746
963 # excluded_bad_extent_start=8
964 # excluded_degenerate_body=252
965 # excluded_delay_slot_start=5
968 # excluded_low_confidence_grade=90
969 # excluded_named_exclusion=9
970 # excluded_no_extent=0
971 # excluded_recorded_negative=84 # excluded_recorded_negative=82
972 # excluded_restores_unsaved=11
973 # excluded_trapping_arith=48
+2
View File
@@ -214,6 +214,7 @@
0x8003768C 0x800376CC src/func_8003768C.c
0x800376CC 0x80037770 src/func_800376CC.c
0x80037984 0x800379E0 src/func_80037984.c
0x800379E0 0x80037A40 src/func_800379E0.c
0x80038788 0x80038790 src/func_80038788.c
0x80038790 0x8003879C src/func_80038790.c
0x80038D48 0x80038DD8 src/func_80038D48.c
@@ -239,6 +240,7 @@
0x80042D64 0x80042D88 src/func_80042D64.c
0x80042D88 0x80042DD4 src/func_80042D88.c
0x80042DD4 0x80042E10 src/func_80042DD4.c
0x80042E10 0x80042E68 src/func_80042E10.c
0x80043D8C 0x80043DC4 src/func_80043D8C.c
0x80044F58 0x80044FA4 src/func_80044F58.c gp=-D_80121BFC
0x800450C4 0x80045110 src/func_800450C4.c gp=-D_80121BFC
1 # Code-region registry: one C region per matched function.
214 0x8003768C
215 0x800376CC
216 0x80037984
217 0x800379E0
218 0x80038788
219 0x80038790
220 0x80038D48
240 0x80042D64
241 0x80042D88
242 0x80042DD4
243 0x80042E10
244 0x80043D8C
245 0x80044F58
246 0x800450C4
+5 -5
View File
@@ -6,11 +6,11 @@
## STATE — SOLO CONTINUATION, 2026-09-24 (current)
**737 bodies / 746 regions**, from 685 / 694 at the last session stop — **+52 bodies / +52 regions**.
The Phase 12 milestone remains 750 bodies, so **+13 remains**. The promoted whole-binary gate is green:
`c_regions=746`, `differing_bytes=0`, SHA-1
**739 bodies / 748 regions**, from 685 / 694 at the last session stop — **+54 bodies / +54 regions**.
The Phase 12 milestone remains 750 bodies, so **+11 remains**. The promoted whole-binary gate is green:
`c_regions=748`, `differing_bytes=0`, SHA-1
`e173426c157384ebf1b6caf8c6fea18a85a14af9`; 348 synthetic tests pass and extents report
`regions=746 disagreements=0 result=AGREE`.
`regions=748 disagreements=0 result=AGREE`.
The requested second batch of 20 is complete. Twenty additional bodies are now matched:
`0x800BC9C4`, `0x800BC8C4`, `0x8006BB0C`, `0x8002D17C`, `0x801029A0`, `0x80055958`,
@@ -24,7 +24,7 @@ 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=746 disagreements=0 result=AGREE`.
check reports `regions=748 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
+12
View File
@@ -2576,6 +2576,18 @@ passed with 348 tests and extents `regions=742 disagreements=0`; worklist regene
**Count after task 40: 737 bodies / 746 regions (+135 bodies from the Phase 12 open baseline;
+13 remain to milestone 750).**
### Worker C task 41 — `0x800379E0` MATCH
* Exact extent `0x800379E0..0x80037A40`, 96 bytes, default toolchain.
* The declaration order fixes callee-saved register allocation (pointer before counter), while the
statement order fixes initialization (counter before pointer); the single hoisted `*a0` read is
required in the preheader.
* Fresh range and candidate whole-binary gate passed with zero differences; `make check` passed with
348 tests and extents `regions=748 disagreements=0`; worklist remains 952 rows.
**Count after task 41: 739 bodies / 748 regions (+137 bodies from the Phase 12 open baseline;
+11 remain to milestone 750).**
### Duplicate-claim guard incident
A later autonomous draft attempted `0x8006FAEC`, but the merge check showed that exact region was
+80
View File
@@ -0,0 +1,80 @@
/*
* func_800379E0 — 96 bytes at 0x800379E0..0x80037A40
*
* PHASE 12 RESUME LANE C (autonomous matching). Row from the UN-ATTEMPTED band
* (negatives-d-unattempted.tsv) filtered through config/function_extents.tsv
* (size 96 grade exact term=jr_ra). NOT previously in the ledger.
*
* MATCH: candidate_bytes=96, 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: read one word through the caller's pointer ONCE, then hand
* it to func_800129C8 thirteen times, walking a 32-byte-strided table whose first entry is
* 0x8012D1C0. The word is read once and kept in a callee-saved register across all thirteen calls,
* which is why the load sits in the loop's PREHEADER and not in the body.
*
* Original words (24):
* 27BDFFE0 addiu sp,sp,-32
* AFB10014 sw s1,20(sp)
* 00008821 move s1,zero i = 0 <- the COUNTER takes s1
* AFB00010 sw s0,16(sp)
* 3C108013 lui s0,0x8013
* 2610D1C0 addiu s0,s0,-11840 p = 0x8012D1C0 <- the POINTER takes s0
* AFBF001C sw ra,28(sp)
* AFB20018 sw s2,24(sp)
* 8C920000 lw s2,0(a0) v = *a0 <- PREHEADER, once
* 00000000 nop
* $L: 02402021 move a0,s2
* 0C004A72 jal 0x800129C8
* 02002821 move a1,s0 (delay slot) the 2nd argument
* 26310001 addiu s1,s1,1 i++
* 2A22000D slti v0,s1,13
* 1440FFF9 bnez v0,0x80037a04
* 26100020 addiu s0,s0,32 (delay slot) p += 32
* 8FBF001C lw ra,28(sp)
* 8FB20018 lw s2,24(sp)
* 8FB10014 lw s1,20(sp)
* 8FB00010 lw s0,16(sp)
* 27BD0020 addiu sp,sp,32
* 03E00008 jr ra
* 00000000 nop
*
* THE LEVER: THE DECLARATION ORDER DECIDES WHICH CALLEE-SAVED REGISTER EACH VARIABLE GETS.
* The behaviour is correct with `int i; char *p = …; int v = *a0;` but the ALLOCATION is the
* mirror image: the counter lands in s0 and the pointer in s1, so the tail's argument move is
* `move a1,s1`, 20 bytes differ and the frame's save order is wrong. **Declaring the POINTER
* BEFORE the counter while keeping the INITIALISATION order (`i = 0;` then `p = …;`) is exact**:
* char *p; int i; int v = *a0; then i = 0; p = D_8012D1C0;
* gives `move s1,zero` for the counter first, `s0` for the pointer, and the original's save order
* (s1, s0, ra, s2) and the original's `move a1,s0`. So two independent orders are in play: the
* DECLARATION order fixes the callee-saved REGISTER, and the STATEMENT order fixes the emitted
* initialisation sequence -- and they can disagree (declaration: p first; statements: i first).
*
* A SECOND, SMALLER LEVER: the dereference must be HOISTED into a local. Writing `func_800129C8(*a0, p)`
* inside the loop makes gcc save the PARAMETER (a0) in a callee-saved register instead and emits the
* load in the body, which changes the frame's save set and 39 bytes; `int v = *a0;` before the loop
* puts the load in the preheader into s2, exactly as the original.
*
* LIMITS: the table at 0x8012D1C0 is modelled as a byte pointer advanced by 32 with no evidence for
* a record type or for what the call does with it; the count 13 is literal in the original. The
* callee `func_800129C8` is REGISTERED (src/func_800129C8.c) and is called with (int, char *) here;
* if that source declares a different signature the two files disagree, but they are separate
* translation units and this call site is exact.
*/
extern void func_800129C8(int a0, char *a1);
extern char D_8012D1C0[];
void func_800379E0(int *a0)
{
char *p;
int i;
int v = *a0;
i = 0;
p = D_8012D1C0;
for (; i < 13; i++) {
func_800129C8(v, p);
p += 32;
}
}