phase9: absorption batch 2 — 310 regions / 301 distinct bodies

Both worker-A-flagged high-value GTE rows closed by the coordinator:
0x80101C2C (nCLIP 0x480012 via lwc2/swc2/cfc2 asm, IR1-3 store + LZCR)
and 0x80102FA4 (mfc2 IR1/IR2 halfword stores + IR3 swc2 + LZCR). Added
gte_ldTRX/gte_ldTRY/gte_ldTRZ ($5-$7, translation block) to gtemac.h.
Gate MATCH whole-binary SHA-1 e173426c157384ebf1b6caf8c6fea18a85a14af9.

Bounded negatives recorded: 0x800F3BB4 (global-ra-save guard — CRT/library
asm pattern not reachable from C), 0x800B34A4/0x800A6658 (alloc-tiebreak),
0x800C3514 (alloc+layout), 0x800518BC (return-merge), 0x800F7930
(record-builder alloc), 0x800690E4 (loop-rotation), 0x80012A98
(scheduler-bound family).
This commit is contained in:
Christopher Williams
2026-09-24 00:57:11 -04:00
parent 345f5ecce6
commit f8cdae42fd
4 changed files with 101 additions and 1 deletions
+2
View File
@@ -272,10 +272,12 @@
0x8010097C 0x80100998 src/func_8010097C.c
0x80101244 0x8010128C src/func_80101244.c
0x80101838 0x80101878 src/func_80101838.c
0x80101C2C 0x80101C54 src/func_80101C2C.c
0x80101CAC 0x80101CDC src/func_80101CAC.c
0x801027CC 0x801027F8 src/func_801027CC.c
0x80102B10 0x80102B2C src/func_80102B10.c maspsx=off
0x80102B30 0x80102B5C src/func_80102B30.c maspsx=off
0x80102FA4 0x80102FD4 src/func_80102FA4.c
0x80102FD4 0x80102FE0 src/func_80102FD4.c
0x80103A94 0x80103AA0 src/func_80103A94.c
0x80103B54 0x80103B60 src/func_80103B54.c
1 # Code-region registry: one C region per matched function.
272 0x8010097C
273 0x80101244
274 0x80101838
275 0x80101C2C
276 0x80101CAC
277 0x801027CC
278 0x80102B10
279 0x80102B30
280 0x80102FA4
281 0x80102FD4
282 0x80103A94
283 0x80103B54
+4 -1
View File
@@ -77,7 +77,10 @@
#define gte_ldRT3RT21(v) __asm__ volatile ("ctc2 %0,$1" : : "r"(v))
#define gte_ldRT22RT23(v) __asm__ volatile ("ctc2 %0,$2" : : "r"(v))
#define gte_ldRT31RT32(v) __asm__ volatile ("ctc2 %0,$3" : : "r"(v))
#define gte_ldRT33(v) __asm__ volatile ("ctc2 %0,$4" : : "r"(v))
#define gte_ldRT33(v) __asm__ volatile ("ctc2 %0,$4" : : "r"(v))
#define gte_ldTRX(v) __asm__ volatile ("ctc2 %0,$5" : : "r"(v))
#define gte_ldTRY(v) __asm__ volatile ("ctc2 %0,$6" : : "r"(v))
#define gte_ldTRZ(v) __asm__ volatile ("ctc2 %0,$7" : : "r"(v))
/* Rotation/light source and colour-matrix control words.
* The executable's control-register numbering is the standard map shifted
+45
View File
@@ -0,0 +1,45 @@
/* func_80101C2C — 0x80101C2C..0x80101C54 (40 bytes).
*
* GTE clip primitive (nCLIP, command 0x480012): loads the first two vector
* triples from a0 via lwc2, runs the clip, stores the IR1..IR3 result and
* returns LZCS as the function value.
*
* Original words:
* 0xC8800000 lwc2 $0,0(a0) ; VXY0 = a0[0]
* 0xC8810004 lwc2 $1,4(a0) ; VZ0 = a0[1]
* 0x00000000 nop
* 0x4A480012 c2 0x480012 ; nCLIP
* 0xE8B90000 swc2 $25,0(a1) ; IR1 -> a1[0]
* 0xE8BA0004 swc2 $26,4(a1) ; IR2 -> a1[1]
* 0xE8BB0008 swc2 $27,8(a1) ; IR3 -> a1[2]
* 0x4842F800 cfc2 v0,$31 ; v0 = LZCR
* 0x03E00008 jr ra
* 0xACC20000 sw v0,0(a2) ; a2[0] = LZCR (jr slot)
*
* The COP2 command and the lwc2/swc2/cfc2 operations cannot be named in C;
* they are stated as single __asm__ volatile statements per the Phase 8
* convention (coprocessor instructions accepted, documented per file, the
* integer logic and memory addressing left to cc1). The data registers $0/$1
* are VXY0/VZ0 and $25/$26/$27 are IR1/IR2/IR3 under the standard data map;
* $31 is LZCR (the count of the clip's sign bits).
*
* LIMITS: the "clip primitive" reading is the standard GTE semantic of
* command 0x480012; the param names are hypotheses. Only the compiled bytes
* are evidence.
*/
void func_80101C2C(const int *a0, int *a1, int *a2)
{
__asm__ volatile ("lwc2 $0,0(%0)" : : "r"(a0));
__asm__ volatile ("lwc2 $1,4(%0)" : : "r"(a0));
__asm__ volatile ("nop");
__asm__ volatile ("c2 0x480012");
__asm__ volatile ("swc2 $25,0(%0)" : : "r"(a1));
__asm__ volatile ("swc2 $26,4(%0)" : : "r"(a1));
__asm__ volatile ("swc2 $27,8(%0)" : : "r"(a1));
{
register int v __asm__("$2");
__asm__ volatile ("cfc2 %0,$31" : "=r"(v));
a2[0] = v;
}
}
+50
View File
@@ -0,0 +1,50 @@
/* func_80102FA4 — 0x80102FA4..0x80102FD4 (48 bytes).
*
* GTE operation (command 0x480012): loads VXY0/VZ0 from a0, runs the op,
* reads the SZ/MAC result regs, stores IR3 as a word and the two mfc2
* results as halfwords, and returns LZCR.
*
* Original words:
* 0xC8800000 lwc2 $0,0(a0) ; VXY0 = a0[0]
* 0xC8810004 lwc2 $1,4(a0) ; VZ0 = a0[1]
* 0x00000000 nop
* 0x4A480012 c2 0x480012
* 0x48024800 mfc2 v0,$9 ; v0 = IR1
* 0x48035000 mfc2 v1,$10 ; v1 = IR2
* 0xE8AB0004 swc2 $11,4(a1) ; IR3 -> a1[1]
* 0xA4A20000 sh v0,0(a1) ; a1[0] = (short)IR1
* 0xA4A30002 sh v1,2(a1) ; a1[1] = (short)IR2
* 0x4842F800 cfc2 v0,$31 ; v0 = LZCR
* 0x03E00008 jr ra
* 0xACC20000 sw v0,0(a2) ; a2[0] = LZCR (jr slot)
*
* The gtemac.h data-register map: $9/$10 = IR1/IR2, $11 = IR3 (the
* standard data register numbering this executable's data space follows
* unshifted). Per the Phase 8 convention the COP2 and data-register
* operations are single __asm__ statements; the halfword stores and the
* LZCR result come from C referencing the register-bound values.
*
* LIMITS: the op's semantic name is unstated (0x480012); the meaning of the
* three IR values is a hypothesis. Only the compiled bytes are evidence.
*/
void func_80102FA4(const int *a0, short *a1, int *a2)
{
register int v0 __asm__("$2");
register int v1 __asm__("$3");
__asm__ volatile ("lwc2 $0,0(%0)" : : "r"(a0));
__asm__ volatile ("lwc2 $1,4(%0)" : : "r"(a0));
__asm__ volatile ("nop");
__asm__ volatile ("c2 0x480012");
__asm__ volatile ("mfc2 %0,$9" : "=r"(v0));
__asm__ volatile ("mfc2 %0,$10" : "=r"(v1));
__asm__ volatile ("swc2 $11,4(%0)" : : "r"(a1));
a1[0] = (short)v0;
a1[1] = (short)v1;
{
register int v __asm__("$2");
__asm__ volatile ("cfc2 %0,$31" : "=r"(v));
a2[0] = v;
}
}