phase9: merge B 0x80013D04 + coordinator wrappers — 339 regions / 330 bodies; reconcile report negatives

B's alignment-1 find closed 0x80013D04 first-attempt (lwl/lwr on provably
aligned addresses = declared-type alignment, not real alignment; Quad4
struct model). New symbol D_801219F4 (gp-relative address taken without
lui). Coordinator wrappers 0x800F8FC0/0x800A5CC8 (pass-through + constant-arg
delay-slot). Report negatives reconciled into the tracked index (0x800F9134,
0x80094370 now excluded by regenerated worklist). Gate MATCH whole-binary
SHA-1 e173426c157384ebf1b6caf8c6fea18a85a14af9.
This commit is contained in:
Christopher Williams
2026-09-24 01:31:26 -04:00
parent 0bbedfdd53
commit 3ea7e13a99
7 changed files with 1579 additions and 1461 deletions
+1456 -1461
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -104,3 +104,5 @@
0x80065494 80 near-match popcount scheduling (base in beqz delay slot)
0x80012A48 80 near-match primitive-init scheduler-bound family
0x8003A5F4 80 near-match alloc+layout (j-to-done second guard; worker-C residual confirmed by coordinator)
0x800F9134 - near-match -
0x80094370 84 near-match triple-deref copy loop (dest = *(*(a0+0xc)+0x160)+0x160; 1 coordinator attempt 100B)
1 # Syphon Filter 3 (USA) open negatives index.
104 0x80065494
105 0x80012A48
106 0x8003A5F4
107 0x800F9134
108 0x80094370
+3
View File
@@ -18,6 +18,7 @@
0x80012D8C 0x80012DBC src/func_80012D8C.c
0x80012DBC 0x80012DE8 src/func_80012DBC.c
0x80013C88 0x80013C90 src/func_80013C88.c
0x80013D04 0x80013D44 src/func_80013D04.c
0x800160E8 0x80016110 src/func_800160E8.c
0x80016110 0x80016120 src/func_80016110.c
0x80016120 0x80016158 src/func_80016120.c
@@ -214,6 +215,7 @@
0x8009F0E8 0x8009F120 src/func_8009F0E8.c
0x800A2F20 0x800A2F44 src/func_800A2F20.c
0x800A45E0 0x800A466C src/func_8009E8D0.c
0x800A5CC8 0x800A5CEC src/func_800A5CC8.c
0x800A6268 0x800A6294 src/func_800A6268.c
0x800A648C 0x800A64C8 src/func_800A648C.c
0x800A74BC 0x800A74D0 src/func_800A74BC.c
@@ -277,6 +279,7 @@
0x800F8F5C 0x800F8F7C src/func_800F8F5C.c
0x800F8F7C 0x800F8F9C src/func_800F8F7C.c
0x800F8F9C 0x800F8FC0 src/func_800F8F9C.c
0x800F8FC0 0x800F8FE0 src/func_800F8FC0.c
0x800F8FE4 0x800F8FF8 src/func_800F8FE4.c maspsx=off
0x800F8FF8 0x800F9008 src/func_800F8FF8.c
0x800F9344 0x800F9380 src/func_800F9344.c
1 # Code-region registry: one C region per matched function.
18 0x80012D8C
19 0x80012DBC
20 0x80013C88
21 0x80013D04
22 0x800160E8
23 0x80016110
24 0x80016120
215 0x8009F0E8
216 0x800A2F20
217 0x800A45E0
218 0x800A5CC8
219 0x800A6268
220 0x800A648C
221 0x800A74BC
279 0x800F8F5C
280 0x800F8F7C
281 0x800F8F9C
282 0x800F8FC0
283 0x800F8FE4
284 0x800F8FF8
285 0x800F9344
+1
View File
@@ -34,6 +34,7 @@ D_801219D0 0x801219D0 gp
D_801219D8 0x801219D8 gp
D_801219E0 0x801219E0 gp
D_801219F0 0x801219F0 gp
D_801219F4 0x801219F4 gp
D_80121A08 0x80121A08 gp
D_80121A0C 0x80121A0C gp
D_80121A10 0x80121A10 gp
1 # Symbol registry: absolute addresses for cross-references used by C regions.
34 D_801219D8
35 D_801219E0
36 D_801219F0
37 D_801219F4
38 D_80121A08
39 D_80121A0C
40 D_80121A10
+63
View File
@@ -0,0 +1,63 @@
/* func_80013D04 — 0x80013D04..0x80013D44 (64 bytes).
*
* Original words:
* 27BDFFE0 addiu sp,sp,-32
* AFBF0018 sw ra,24(sp)
* 00A03021 move a2,a1 third argument = the routine's own second
* 278500BC addiu a1,gp,188 a1 = &D_801219F4 (gp + 0xBC)
* 88A20003 lwl v0,3(a1)
* 98A20000 lwr v0,0(a1) unaligned 4-byte read of the global
* ABA20013 swl v0,19(sp)
* BBA20010 swr v0,16(sp) unaligned 4-byte write to the local
* 27A40010 addiu a0,sp,16 a0 = &local
* 0C004EE0 jal 0x80013B80
* 24050001 _li a1,1 (delay slot)
* 8FBF0018 lw ra,24(sp)
* 27BD0020 addiu sp,sp,32
* 03E00008 jr ra
* 00000000 nop
*
* Copies a 4-byte value out of a global into a stack local and passes the local's
* address to a second routine, with the constant 1 and the routine's own second
* parameter supplied alongside.
*
* THE UNALIGNED ACCESS IS A TYPE ARTEFACT, NOT AN ALIGNMENT FACT. Both addresses
* are in fact 4-byte aligned — `gp` is 0x80121938 so `gp + 0xBC` is 0x801219F4
* (…F4), and the local at 0x10(sp) is aligned too. Yet cc1 emits `lwl`/`lwr` for
* the read and `swl`/`swr` for the write, which it only does for a type whose
* alignment is **1** — a `char[4]` member or a packed struct. So the copy is a
* struct assignment of an alignment-1 4-byte type, and that is what is modelled
* here. Writing it as an `int` assignment would emit a plain `lw`/`sw` and differ.
*
* `move a2,a1` is the pass-through idiom again: the routine's own second parameter
* becomes the callee's third, and the first parameter is discarded entirely (it is
* overwritten by the local's address without ever being read).
*
* The address is taken gp-relatively (`addiu a1,gp,188` with no `lui`), so the
* symbol is within ±32K of `gp` and needs a **`gp` marker row** in the registry;
* it is requested in `.run/p9/w-b/symbols-request.tsv`. Without the marker the
* address would be materialised absolutely and the region could not match.
*
* LIMITS: the displacement 0xBC and the frame layout are read from the bytes. That
* the 4-byte type is alignment-1 follows from the lwl/lwr pair, not from any size
* or content evidence — a `struct { char b[4]; }` is a reconstruction of the
* *alignment* the compiler assumed and not of the original's declaration. The
* callee is named for its address; whether it returns anything is invisible here
* because the result is not used, so the signature written is `void`.
*/
typedef struct {
char b[4]; /* alignment 1 — the reason for the lwl/lwr pair */
} Quad4;
extern Quad4 D_801219F4;
void func_80013B80(Quad4 *local, int one, int arg);
void func_80013D04(int unused, int arg)
{
Quad4 local;
local = D_801219F4;
func_80013B80(&local, 1, arg);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* func_800A5CC8 — 36 bytes at 0x800A5CC8..0x800A5CEC
*
* A one-call frame wrapper: reads a signed 16-bit field out of the argument and
* passes it, with a constant, to a callee. The `li a1,1` lands in the `jal` delay
* slot.
*
* The observed instructions are:
* addiu sp,sp,-24
* sw ra,16(sp)
* lh a0,2(a0) ; *(short *)(p + 2) <- SIGNED 16-bit
* jal 0x800A5C1C
* li a1,1 ; second argument = 1 (delay slot)
* lw ra,16(sp)
* addiu sp,sp,24
* jr ra
* nop
*
* LIMITS: the field offset (2) and the constant (1) are hypotheses read from the
* instruction shape; what the callee does is not established here and is not
* guessed. The `lh` shows the field is signed 16-bit. Only the compiled bytes are
* evidence.
*/
void func_800A5CC8(char *p) {
func_800A5C1C(*(short *)(p + 2), 1);
}
+27
View File
@@ -0,0 +1,27 @@
/* func_800F8FC0 — 0x800F8FC0..0x800F8FE0 (32 bytes).
*
* Calls func_80106ED4 with no arguments; unvalued wrapper (jr slot nop).
*
* Original words:
* 0x27BDFFE8 addiu sp,sp,-24
* 0xAFBF0010 sw ra,16(sp)
* 0x0C041BB5 jal func_80106ED4
* 0x00000000 nop
* 0x8FBF0010 lw ra,16(sp)
* 0x27BD0018 addiu sp,sp,24
* 0x03E00008 jr ra
* 0x00000000 nop
*
* A plain forwarding wrapper; the jr slot is a nop because nothing is
* materialised (worker B's unvalued-epilogue tell).
*
* LIMITS: no callee semantics are known or guessed. Only the compiled
* bytes are evidence.
*/
void func_80106ED4(void);
void func_800F8FC0(void)
{
func_80106ED4();
}