diff --git a/.gitignore b/.gitignore index 790dcb497..8a6f2fbd8 100644 --- a/.gitignore +++ b/.gitignore @@ -489,6 +489,12 @@ unsloth_compiled_cache/ /.run/P36/delever/includers_cache.json !/.run/P36/delever/*.jsonl !/.run/P36/delever/*.txt +!/.run/P36/gte/ +/.run/P36/gte/* +!/.run/P36/gte/*.json +!/.run/P36/gte/*.log +!/.run/P36/gte/*.txt +/.run/P36/gte/inventory.json !/.run/P36/permuter/ /.run/P36/permuter/* !/.run/P36/permuter/*.log diff --git a/.run/P36/baseline/r22_t5_header.log b/.run/P36/baseline/r22_t5_header.log new file mode 100644 index 000000000..84faccb94 --- /dev/null +++ b/.run/P36/baseline/r22_t5_header.log @@ -0,0 +1,476 @@ +clean: removed build/, expected/, and the regenerated splat tree (asm/, assets/, undefined_*_auto.txt). +disc-extract: up to date — extracted/retail/ matches the committed manifest (sha1 e5c6019249dec3c71bb2cf40658a78439dddb037) +splat 0.41.0 (powered by spimdisasm 1.41.0) + 0%| | 0/1096 [00:00= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { s32 x = (s16)L.sxy[0]; s32 ax; ax = x; if (x < 0) { ax = -x; } ax = ((0xF0 - ax) * 0x7F) / 0xF0; __asm__(\"\" : \"=r\"(ax) : \"0\"(ax)); x = (x + 0xF0) / 0x1E; if (x == 0x10) { x = 0xF; } x = x << 8; { s32 flg = 0x3000; func_8002D4C8(sndid, ((ax | flg) | x) & 0xFFFF); } }": 7, + "L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); { register void *r4 __asm__(\"$4\"); r4 = &D_800AF648; func_8004914C(r4); } { register void *r4 __asm__(\"$4\"); r4 = &D_800AF648; func_800491AC(r4); } RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); if (L.flag >= 0 && (u32)((L.sxy[0] + 0x9F) & 0xFFFF) < 0x13F && (u32)((L.sxy[1] + 0x77) & 0xFFFF) < 0xEF) { s32 vol = ((s16)L.sxy[0] * 0x80 + 0x5000) / 320; if (vol < 0) { vol = 0; } if (vol >= 0x80) { vol = 0x7F; } func_8002D4C8(sndid, (vol | 0x2000) & 0xFFFF); }": 2 + }, + "uses": 22, + "files": [ + "src/ov_SC06_008/ov_SC06_008_jr_8017C294.c", + "src/ov_SC06_010/ov_SC06_010_jr_8017A4AC.c", + "src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c", + "src/ov_SC06_022/ov_SC06_022_jr_80184A28.c", + "src/ov_SC06_024/ov_SC06_024_jr_80186F00.c", + "src/ov_SC06_030/ov_SC06_030_jr_8017C8D0.c", + "src/ov_SC06_032/ov_SC06_032_jr_80182890.c", + "src/ov_SC06_033/ov_SC06_033_jr_8017C24C.c" + ] + }, + "COPY_TO_FAAC": { + "kind": "barrier", + "texts": { + "do { SubFAAC *d = (dp); d->f8 = s0->f6; d->fA = s0->fA; d->fC = s0->fE; d->f10 = s0->f20->f10; d->f12 = s0->f20->f12 + (add); d->f14 = s0->f20->f14; if (s0->f20->f4 < 0) { d->f4 |= (s32)0x80000000; } else { __asm__ __volatile__(\"\"); d->f4 &= 0x7FFFFFFF; } } while (0)": 1 + }, + "uses": 2, + "files": [ + "src/ov_SC06_010/ov_SC06_010_jr_8017A4AC.c" + ] + }, + "DRAW": { + "kind": "launder", + "texts": { + "mb = (u8 *)&D_800AF630; __asm__(\"\" : \"=r\"(mb) : \"0\"(mb)); func_8004914C(mb + 0x18); __asm__(\"\" : \"=r\"(mb) : \"0\"(mb)); func_800491AC(mb + 0x18); pc = (long *)&pkt[0]; p1 = (long *)&pkt[2]; p2 = (long *)&pkt[4]; p3 = (long *)&pkt[6]; pfl = &flag1; p0 = pc; gte_ldv3(p0, p1, p2); gte_rtpt(); gte_stflg(pfl); __asm__ __volatile__(\"\" :: \"r\"(pfl)); gte_stsxy3(p0, p1, p2); gte_ldv0(p3); gte_rtps(); gte_stflg(&flag2); flag1 |= flag2; gte_stsxy(p3); gte_avsz4(); gte_stotz(&otz); oz = otz; *(s16 *)((u8 *)pkt + 4) = (s16)oz; if (oz > 0 && flag1 >= 0 && !((u32)&D_800AE610 < (u32)(*(s32 *)((u8 *)&D_800A651C + (*(u16 *)&D_800B9A02) * 0x14) + oz * 4))) { func_80017254(pc); }": 3 + }, + "uses": 9, + "files": [ + "src/ov_SC06_018/ov_SC06_018_jr_80187AEC.c", + "src/ov_SC06_032/ov_SC06_032_jr_80182890.c", + "src/ov_SC06_033/ov_SC06_033_jr_80186574.c" + ] + }, + "XFER": { + "kind": "launder", + "texts": { + "src = *(s32 *)(arg0 + SRCOFF); func_8012B2CC(src); mp = D_801D11F8; __asm__ __volatile__(\"\" : \"=r\"(mp) : \"0\"(mp)); ((void (*)(s32, void *, void *))func_8012F14C)(*(s32 *)(src + 0x20) + 0x34, mp, sp10); dst = *(s32 *)(arg0 + DSTOFF); *(u16 *)(dst + 6) = sp10[0]; *(u16 *)(dst + 0xA) = sp10[1]; *(u16 *)(dst + 0xE) = sp10[2]; *(u16 *)(*(s32 *)(dst + 0x20) + 0x10) = *(u16 *)(dst + 0xFC) + *(u16 *)(*(s32 *)(src + 0x20) + 0x10); *(u16 *)(*(s32 *)(dst + 0x20) + 0x12) = *(u16 *)(dst + 0xFE) + *(u16 *)(*(s32 *)(src + 0x20) + 0x12);": 2 + }, + "uses": 12, + "files": [ + "src/ov_SC06_018/ov_SC06_018_jr_8019059C.c", + "src/ov_SC06_018/ov_SC06_018_jr_80191C50.c" + ] + }, + "XFERLAST": { + "kind": "launder", + "texts": { + "src = *(s32 *)(arg0 + SRCOFF); func_8012B2CC(src); mp = D_801D11F8; __asm__ __volatile__(\"\" : \"=r\"(mp) : \"0\"(mp)); ((void (*)(s32, void *, void *))func_8012F14C)(*(s32 *)(src + 0x20) + 0x34, mp, sp10); *(u16 *)(arg0 + 6) = sp10[0]; *(u16 *)(arg0 + 0xA) = sp10[1]; *(u16 *)(arg0 + 0xE) = sp10[2];": 2 + }, + "uses": 6, + "files": [ + "src/ov_SC06_018/ov_SC06_018_jr_8019059C.c", + "src/ov_SC06_018/ov_SC06_018_jr_80191C50.c" + ] + }, + "ec4c_SetRotMatrix": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lw $12, 0( %0 );\" \"lw $13, 4( %0 );\" \"ctc2 $12, $0;\" \"ctc2 $13, $1;\" \"lw $12, 8( %0 );\" \"lw $13, 12( %0 );\" \"lw $14, 16( %0 );\" \"ctc2 $12, $2;\" \"ctc2 $13, $3;\" \"ctc2 $14, $4\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 1 + }, + "uses": 2, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_SetTransMatrix": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lw $12, 20( %0 );\" \"lw $13, 24( %0 );\" \"ctc2 $12, $5;\" \"lw $14, 28( %0 );\" \"ctc2 $13, $6;\" \"ctc2 $14, $7\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 1 + }, + "uses": 2, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_rotcol": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lhu $12, 0( %0 );\" \"lhu $13, 6( %0 );\" \"lhu $14, 12( %0 );\" \"mtc2 $12, $9;\" \"mtc2 $13, $10;\" \"mtc2 $14, $11;\" \"nop;\" \"nop;\" \"mvmva 1, 0, 3, 3, 0;\" \"mfc2 $12, $9;\" \"mfc2 $13, $10;\" \"mfc2 $14, $11;\" \"sh $12, 0( %0 );\" \"sh $13, 6( %0 );\" \"sh $14, 12( %0 )\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\", \"memory\" )": 1 + }, + "uses": 3, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_rottrans": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lhu $13, 4( %0 );\" \"lhu $12, 0( %0 );\" \"sll $13, $13, 16;\" \"or $12, $12, $13;\" \"mtc2 $12, $0;\" \"lwc2 $1, 8( %0 );\" \"nop;\" \"nop;\" \"mvmva 1, 0, 0, 0, 0;\" \"swc2 $25, 0( %0 );\" \"swc2 $26, 4( %0 );\" \"swc2 $27, 8( %0 )\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_ldv3": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lwc2 $0, 0( %0 );\" \"lwc2 $1, 4( %0 );\" \"lwc2 $2, 0( %1 );\" \"lwc2 $3, 4( %1 );\" \"lwc2 $4, 0( %2 );\" \"lwc2 $5, 4( %2 )\" : : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_ldv0": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lwc2 $0, 0( %0 );\" \"lwc2 $1, 4( %0 )\" : : \"r\"( r0 ) )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_rtpt": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ (\"nop;nop;rtpt\")": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_rtps": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ (\"nop;nop;rtps\")": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_avsz4": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ (\"nop;nop;avsz4\")": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_stflg": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"cfc2 $12, $31;\" \"nop;\" \"sw $12, 0( %0 )\" : : \"r\"( r0 ) : \"$12\", \"memory\" )": 1 + }, + "uses": 2, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_stsxy3": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"swc2 $12, 0( %0 );\" \"swc2 $13, 0( %1 );\" \"swc2 $14, 0( %2 )\" : : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_stsxy": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"swc2 $14, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "ec4c_stotz": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"swc2 $7, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c" + ] + }, + "gte_ldclmv": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lhu $12, 0( %0 );\" \"lhu $13, 6( %0 );\" \"lhu $14, 12( %0 );\" \"mtc2 $12, $9;\" \"mtc2 $13, $10;\" \"mtc2 $14, $11\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 2, + "__asm__ volatile ( \"lhu $12, 0( %0 );\" \"lhu $13, 6( %0 );\" \"lhu $14, 12( %0 );\" \"mtc2 $12, $9;\" \"mtc2 $13, $10;\" \"mtc2 $14, $11\" : : \"r\"(r0) : \"$12\", \"$13\", \"$14\" )": 1 + }, + "uses": 12, + "files": [ + "src/ov_SC06_029/ov_SC06_029_jr_8017C954.c", + "src/ov_SC06_029/ov_SC06_029_jr_801867D0.c" + ] + }, + "gte_rtir": { + "kind": "gte", + "texts": { + "__asm__ volatile (\"nop;nop;mvmva 1, 0, 3, 3, 0\")": 3 + }, + "uses": 12, + "files": [ + "src/ov_SC06_029/ov_SC06_029_jr_8017C954.c", + "src/ov_SC06_029/ov_SC06_029_jr_801867D0.c" + ] + }, + "gte_stclmv": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"mfc2 $12, $9;\" \"mfc2 $13, $10;\" \"mfc2 $14, $11;\" \"sh $12, 0( %0 );\" \"sh $13, 6( %0 );\" \"sh $14, 12( %0 )\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\", \"memory\" )": 2, + "__asm__ volatile ( \"mfc2 $12, $9;\" \"mfc2 $13, $10;\" \"mfc2 $14, $11;\" \"sh $12, 0( %0 );\" \"sh $13, 6( %0 );\" \"sh $14, 12( %0 )\" : : \"r\"(r0) : \"$12\", \"$13\", \"$14\", \"memory\" )": 1 + }, + "uses": 12, + "files": [ + "src/ov_SC06_029/ov_SC06_029_jr_8017C954.c", + "src/ov_SC06_029/ov_SC06_029_jr_801867D0.c" + ] + }, + "gte_ldlvnl": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lhu $13, 4( %0 );\" \"lhu $12, 0( %0 );\" \"sll $13, $13, 16;\" \"or $12, $12, $13;\" \"mtc2 $12, $0;\" \"lwc2 $1, 8( %0 )\" : : \"r\"(r0) : \"$12\", \"$13\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_029/ov_SC06_029_jr_801867D0.c" + ] + }, + "LAUNDER_8018A180": { + "kind": "launder", + "texts": { + "({ s32 _m = (s32)(p); __asm__(\"\" : \"=r\"(_m) : \"0\"(_m)); _m; })": 1 + }, + "uses": 5, + "files": [ + "src/ov_SC06_029/ov_SC06_029_jr_801898CC.c" + ] + }, + "gte_ldv0_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lwc2 $0, 0( %0 );\" \"lwc2 $1, 4( %0 )\" : : \"r\"( r0 ) )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_ldv3_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lwc2 $0, 0( %0 );\" \"lwc2 $1, 4( %0 );\" \"lwc2 $2, 0( %1 );\" \"lwc2 $3, 4( %1 );\" \"lwc2 $4, 0( %2 );\" \"lwc2 $5, 4( %2 )\" : : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_rtps_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile (\"nop;nop;rtps\")": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_rtpt_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile (\"nop;nop;rtpt\")": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_avsz4_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile (\"nop;nop;avsz4\")": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_stsxy_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"swc2 $14, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_stsxy3_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"swc2 $12, 0( %0 );\" \"swc2 $13, 0( %1 );\" \"swc2 $14, 0( %2 )\" : : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_stotz_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"swc2 $7, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_stflg_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"cfc2 $12, $31;\" \"nop;\" \"sw $12, 0( %0 )\" : : \"r\"( r0 ) : \"$12\", \"memory\" )": 1 + }, + "uses": 2, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_SetRotMatrix_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lw $12, 0( %0 );\" \"lw $13, 4( %0 );\" \"ctc2 $12, $0;\" \"ctc2 $13, $1;\" \"lw $12, 8( %0 );\" \"lw $13, 12( %0 );\" \"lw $14, 16( %0 );\" \"ctc2 $12, $2;\" \"ctc2 $13, $3;\" \"ctc2 $14, $4\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_SetTransMatrix_80180228": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lw $12, 20( %0 );\" \"lw $13, 24( %0 );\" \"ctc2 $12, $5;\" \"lw $14, 28( %0 );\" \"ctc2 $13, $6;\" \"ctc2 $14, $7\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_SetRotMatrix_80181164": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lw $12, 0( %0 );\" \"lw $13, 4( %0 );\" \"ctc2 $12, $0;\" \"ctc2 $13, $1;\" \"lw $12, 8( %0 );\" \"lw $13, 12( %0 );\" \"lw $14, 16( %0 );\" \"ctc2 $12, $2;\" \"ctc2 $13, $3;\" \"ctc2 $14, $4\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "gte_SetTransMatrix_80181164": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lw $12, 20( %0 );\" \"lw $13, 24( %0 );\" \"ctc2 $12, $5;\" \"lw $14, 28( %0 );\" \"ctc2 $13, $6;\" \"ctc2 $14, $7\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC06_030/ov_SC06_030_jr_8017F65C.c" + ] + }, + "XFER_1919A0": { + "kind": "launder", + "texts": { + "src = *(s32 *)(arg0 + SRCOFF); func_8012B2CC(src); mp = D_801CC7CC; __asm__ __volatile__(\"\" : \"=r\"(mp) : \"0\"(mp)); ((void (*)(s32, void *, void *))func_8012F14C)(*(s32 *)(src + 0x20) + 0x34, mp, sp10); dst = *(s32 *)(arg0 + DSTOFF); *(u16 *)(dst + 6) = sp10[0]; *(u16 *)(dst + 0xA) = sp10[1]; *(u16 *)(dst + 0xE) = sp10[2]; *(u16 *)(*(s32 *)(dst + 0x20) + 0x10) = *(u16 *)(dst + 0xFC) + *(u16 *)(*(s32 *)(src + 0x20) + 0x10); *(u16 *)(*(s32 *)(dst + 0x20) + 0x12) = *(u16 *)(dst + 0xFE) + *(u16 *)(*(s32 *)(src + 0x20) + 0x12);": 1 + }, + "uses": 6, + "files": [ + "src/ov_SC06_032/ov_SC06_032_jr_801919A0.c" + ] + }, + "XFERLAST_1919A0": { + "kind": "launder", + "texts": { + "src = *(s32 *)(arg0 + SRCOFF); func_8012B2CC(src); mp = D_801CC7CC; __asm__ __volatile__(\"\" : \"=r\"(mp) : \"0\"(mp)); ((void (*)(s32, void *, void *))func_8012F14C)(*(s32 *)(src + 0x20) + 0x34, mp, sp10); *(u16 *)(arg0 + 6) = sp10[0]; *(u16 *)(arg0 + 0xA) = sp10[1]; *(u16 *)(arg0 + 0xE) = sp10[2];": 1 + }, + "uses": 3, + "files": [ + "src/ov_SC06_032/ov_SC06_032_jr_801919A0.c" + ] + }, + "F14C": { + "kind": "launder", + "texts": { + "{ s32 _m = (s32)&D_801C8344; __asm__ __volatile__(\"\" : \"=r\"(_m) : \"0\"(_m)); ((void (*)(s32, s32, s32))func_8012F14C)(*(s32 *)((MTXOWNER) + 0x20) + 0x34, _m, (s32)(OUT)); }": 1 + }, + "uses": 0, + "files": [ + "src/ov_SC06_033/ov_SC06_033_jr_8018D98C.c" + ] + }, + "gte_SetRotMatrix_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lw $12, 0( %0 );\" \"lw $13, 4( %0 );\" \"ctc2 $12, $0;\" \"ctc2 $13, $1;\" \"lw $12, 8( %0 );\" \"lw $13, 12( %0 );\" \"lw $14, 16( %0 );\" \"ctc2 $12, $2;\" \"ctc2 $13, $3;\" \"ctc2 $14, $4\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 4 + }, + "uses": 6, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_SetTransMatrix_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lw $12, 20( %0 );\" \"lw $13, 24( %0 );\" \"ctc2 $12, $5;\" \"lw $14, 28( %0 );\" \"ctc2 $13, $6;\" \"ctc2 $14, $7\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 4 + }, + "uses": 6, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_ldclmv_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lhu $12, 0( %0 );\" \"lhu $13, 6( %0 );\" \"lhu $14, 12( %0 );\" \"mtc2 $12, $9;\" \"mtc2 $13, $10;\" \"mtc2 $14, $11\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\" )": 2 + }, + "uses": 6, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_rtir_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"nop;nop;mvmva 1, 0, 3, 3, 0\" )": 2 + }, + "uses": 6, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stclmv_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"mfc2 $12, $9;\" \"mfc2 $13, $10;\" \"mfc2 $14, $11;\" \"sh $12, 0( %0 );\" \"sh $13, 6( %0 );\" \"sh $14, 12( %0 )\" : : \"r\"( r0 ) : \"$12\", \"$13\", \"$14\", \"memory\" )": 2 + }, + "uses": 6, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_ldlv0_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lhu $13, 4( %0 );\" \"lhu $12, 0( %0 );\" \"sll $13, $13, 16;\" \"or $12, $12, $13;\" \"mtc2 $12, $0;\" \"lwc2 $1, 8( %0 )\" : : \"r\"( r0 ) : \"$12\", \"$13\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_rt_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"nop;nop;mvmva 1, 0, 0, 0, 0\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stlvnl_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"swc2 $25, 0( %0 );\" \"swc2 $26, 4( %0 );\" \"swc2 $27, 8( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_ldv3_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lwc2 $0, 0( %0 );\" \"lwc2 $1, 4( %0 );\" \"lwc2 $2, 0( %1 );\" \"lwc2 $3, 4( %1 );\" \"lwc2 $4, 0( %2 );\" \"lwc2 $5, 4( %2 )\" : : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_ldv0_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"lwc2 $0, 0( %0 );\" \"lwc2 $1, 4( %0 )\" : : \"r\"( r0 ) )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_rtpt_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"nop;nop;rtpt\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_rtps_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"nop;nop;rtps\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_avsz4_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"nop;nop;avsz4\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stflg_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"cfc2 $12, $31;\" \"nop;\" \"sw $12, 0( %0 )\" : : \"r\"( r0 ) : \"$12\", \"memory\" )": 2 + }, + "uses": 4, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stsxy3_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"swc2 $12, 0( %0 );\" \"swc2 $13, 0( %1 );\" \"swc2 $14, 0( %2 )\" : : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) : \"memory\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stsxy_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"swc2 $14, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stotz_1": { + "kind": "gte", + "texts": { + "__asm__ __volatile__ ( \"swc2 $7, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 2 + }, + "uses": 2, + "files": [ + "src/ov_SC07_001/ov_SC07_001_jr_8017BEBC.c", + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_ldv0_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lwc2 $0, 0( %0 );\" \"lwc2 $1, 4( %0 )\" : : \"r\"( r0 ) )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_ldv3_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"lwc2 $0, 0( %0 );\" \"lwc2 $1, 4( %0 );\" \"lwc2 $2, 0( %1 );\" \"lwc2 $3, 4( %1 );\" \"lwc2 $4, 0( %2 );\" \"lwc2 $5, 4( %2 )\" : : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) )": 1 + }, + "uses": 2, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_rtps_2": { + "kind": "gte", + "texts": { + "__asm__ volatile (\"nop;nop;rtps\")": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_rtpt_2": { + "kind": "gte", + "texts": { + "__asm__ volatile (\"nop;nop;rtpt\")": 1 + }, + "uses": 2, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_avsz4_2": { + "kind": "gte", + "texts": { + "__asm__ volatile (\"nop;nop;avsz4\")": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stsxy_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"swc2 $14, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stsxy0_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"swc2 $12, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stsxy1_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"swc2 $13, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stsxy3_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"swc2 $12, 0( %0 );\" \"swc2 $13, 0( %1 );\" \"swc2 $14, 0( %2 )\" : : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stotz_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"swc2 $7, 0( %0 )\" : : \"r\"( r0 ) : \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stszotz_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"mfc2 $12, $19;\" \"nop;\" \"sra $12, $12, 2;\" \"sw $12, 0( %0 )\" : : \"r\"( r0 ) : \"$12\", \"memory\" )": 1 + }, + "uses": 1, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "gte_stflg_2": { + "kind": "gte", + "texts": { + "__asm__ volatile ( \"cfc2 $12, $31;\" \"nop;\" \"sw $12, 0( %0 )\" : : \"r\"( r0 ) : \"$12\", \"memory\" )": 1 + }, + "uses": 3, + "files": [ + "src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c" + ] + }, + "ENGINE_SHB": { + "kind": "launder", + "texts": { + "__asm__ __volatile__(\"\" : \"=r\"(x) : \"0\"(x))": 1 + }, + "uses": 0, + "files": [ + "src/shared/engine_prelude.h" + ] + } +} \ No newline at end of file diff --git a/.run/P36/census/lever_census.json b/.run/P36/census/lever_census.json index 630d5d7fc..152c477f1 100644 --- a/.run/P36/census/lever_census.json +++ b/.run/P36/census/lever_census.json @@ -24,13 +24,13 @@ "gte_stsv": 145, "gte_stsxy": 361, "gte_stsxy3": 191, + "gte_stsxy3_f3": 61, "gte_stsxy3c": 94, "gte_stsz3": 123, "gte_stsz4": 126, "gte_stszotz": 113, - "lhu": 70, - "lw": 80, - "lwc2": 435, + "lhu": 66, + "lwc2": 432, "mfc2": 61, "swc2": 449 }, @@ -56,7 +56,9 @@ "asm-body/direct": 13, "barrier/direct": 4576, "barrier/via-macro": 2, - "gte/direct": 1140, + "gte-lever/direct": 49, + "gte-unsigned/direct": 3, + "gte/direct": 1088, "gte/via-macro": 5751, "instruction/direct": 1690, "instruction/via-macro": 22, @@ -89,7 +91,9 @@ "kinds": { "asm-body": 13, "barrier": 4578, - "gte": 6891, + "gte": 6839, + "gte-lever": 49, + "gte-unsigned": 3, "instruction": 1712, "keepalive": 2000, "launder": 4676, @@ -232,18 +236,27 @@ } }, "coverage_ok": true, - "elapsed_s": 39.0, + "elapsed_s": 50.8, "generated": "2026-09-09", - "head": "f087282a3", + "gte_levers": { + "direct": 49, + "marked": 0, + "sites": 49, + "unmarked": 49, + "unsigned": 3, + "via_macro": 0, + "what": "GTE ops whose clobbers exceed the canonical macro's (a scheduling steer): levers for T7, outside the headline number" + }, + "head": "917c68afd", "headers": 3181, "levers_AB": { - "asm": 12979, - "bodies": 12501, - "distinct_bodies": 1728, + "asm": 13028, + "bodies": 12518, + "distinct_bodies": 1745, "marked": 33625, "pins": 20646, - "sites": 33625, - "unmarked": 0, + "sites": 33674, + "unmarked": 49, "what": "register pins + asm statements excluding GTE ops: the classes the phase drives to 0" }, "macro_definitions": { @@ -388,6 +401,17 @@ "count": 0, "sample": [] }, + "per_tu_asm_macro_definitions": { + "by_kind": { + "barrier": 1, + "gte": 9102, + "instruction": 9, + "launder": 428 + }, + "gte_variants": 0, + "total": 9540, + "what": "asm-bearing #define blocks outside the GTE header: 0 at the close (T5 deletes the canonical duplicates, T7 the variants)" + }, "pins": { "bare_name": 25, "init": 2776, diff --git a/.run/P36/census/lever_census.txt b/.run/P36/census/lever_census.txt index 2b3306c2d..777cd500e 100644 --- a/.run/P36/census/lever_census.txt +++ b/.run/P36/census/lever_census.txt @@ -6,24 +6,26 @@ lever_census: 218 binaries · 4,121 TUs + 3,181 headers · coverage OK · unclas coverage attribute raw 76 = live 76 + macro-block 0 + comment/dead 0 class sites in-bodies file-scope bodies distinct TUs marked unmarked kinds A pins 20646 20646 0 10329 1330 2580 20646 0 {'pin': 20646} - B asm 22552 22539 13 9758 1054 2289 13155 9397 {'gte': 6891, 'barrier': 4578, 'launder': 4676, 'instruction': 1712, 'keepalive': 2000, 'asm-body': 13, 'verbatim-body': 2682} + B asm 22552 22539 13 9758 1054 2289 13155 9397 {'gte': 6839, 'barrier': 4578, 'gte-lever': 49, 'gte-unsigned': 3, 'launder': 4676, 'instruction': 1712, 'keepalive': 2000, 'asm-body': 13, 'verbatim-body': 2682} C volatile 1722 1570 152 628 97 612 14 1708 {'decl-body': 58, 'decl-file': 152, 'cast': 1510, 'param': 2} D register 50 50 0 47 47 6 0 50 {'register': 50} E asm-label 7428 1005 6423 737 117 2080 0 7428 {'asm-label': 7428} F builtin 445 445 0 428 27 302 0 445 {'builtin': 445} G attribute 76 1 75 1 1 40 0 76 {'attribute': 76} - UNION A–D: 15,955 bodies · 2,023 distinct (addresses normalized) · 394 multi-copy classes holding 14,326 bodies · by kind {'ov': 15258, 'resident': 12, 'main': 180, 'md': 182, 'shared': 323} - THE PHASE'S NUMBER (pins + asm statements, GTE excluded): 33,625 sites in 12,501 bodies (1,728 distinct) · marked !FAKE 33,625 · UNMARKED 0 + UNION A–D: 15,955 bodies · 2,023 distinct (addresses normalized) · 394 multi-copy classes holding 14,326 bodies · by kind {'ov': 15258, 'shared': 323, 'main': 180, 'md': 182, 'resident': 12} + THE PHASE'S NUMBER (pins + asm statements, GTE excluded): 33,674 sites in 12,518 bodies (1,745 distinct) · marked !FAKE 33,625 · UNMARKED 49 orphan !FAKE markers (no pin/asm site on the line nor below): 0 + GTE levers (clobbers beyond the canonical macro's): 49 sites (0 via a variant macro, 49 direct) · marked 0 · UNMARKED 49 · unsigned GTE statements 3 + per-TU asm macro definitions outside the GTE header: 9,540 {'gte': 9102, 'launder': 428, 'instruction': 9, 'barrier': 1} (GTE variants 0) pins: 20,646 · $0 1,321 · $sp 13 · with initializer 2,776 · volatile-qualified 134 · bare-name 25 · spellings {'__asm__': 20544, 'asm': 102} whole-body asm routines in C shells, manifest PERMANENT (hand asm, NOT levers): 22 routines · 2,682 sites (2,660 private copies + 22 shared headers); asm-bodies NOT permanent (levers): 13 site(s) ['func_8001E378:DECOMPILE-NOW', 'func_80020F34:DECOMPILE-NOW', 'func_800249F0:DECOMPILE-NOW', 'func_80025CBC:DECOMPILE-NOW', 'func_80026514:UNCERTAIN', 'func_800268D0:UNCERTAIN', 'func_80027058:DECOMPILE-NOW', 'func_80027200:DECOMPILE-NOW', 'func_800CBA44:DECOMPILE-NOW', 'func_8017D810:DECOMPILE-NOW', 'func_8017E26C:UNCERTAIN', 'func_80184440:DECOMPILE-NOW', 'func_801A3BCC:DECOMPILE-NOW'] - asm kinds: {'asm-body/direct': 13, 'barrier/direct': 4576, 'barrier/via-macro': 2, 'gte/direct': 1140, 'gte/via-macro': 5751, 'instruction/direct': 1690, 'instruction/via-macro': 22, 'keepalive/direct': 2000, 'launder/direct': 4236, 'launder/via-macro': 440, 'verbatim-body/direct': 2682} + asm kinds: {'asm-body/direct': 13, 'barrier/direct': 4576, 'barrier/via-macro': 2, 'gte/direct': 1088, 'gte/via-macro': 5751, 'gte-lever/direct': 49, 'gte-unsigned/direct': 3, 'instruction/direct': 1690, 'instruction/via-macro': 22, 'keepalive/direct': 2000, 'launder/direct': 4236, 'launder/via-macro': 440, 'verbatim-body/direct': 2682} instruction mnemonics: {'addu': 966, 'move': 406, 'la': 142, 'lh': 134, 'addiu': 22, 'RTP_SND': 22, '.section': 7, 'lui': 4, 'and': 2, 'mult': 1, 'mfhi': 1, 'sll': 1, 'li': 1, 'lw': 1, 'nop': 1, 'srl': 1} - gte mnemonics: {'gte_ldv0': 653, 'swc2': 449, 'lwc2': 435, 'gte_stsxy': 361, 'gte_rtps': 356, 'gte_stflg': 319, 'gte_rtpt': 289, 'gte_stsxy3': 191, 'gte_ldrgb': 162, 'gte_ldv3c': 159, 'gte_rt': 155, 'gte_SetRotMatrix': 150, 'gte_SetTransMatrix': 145, 'gte_stsv': 145, 'gte_stlvnl': 143, 'gte_ldv3': 140, 'gte_ldIR0z': 133, 'gte_ldIRGB': 133, 'gte_dpcl': 133, 'gte_stORGB': 133, 'gte_mvmva0': 131, 'gte_stsz4': 126, 'gte_stsz3': 123, 'gte_stszotz': 113, 'gte_nclip': 96, 'gte_stopz': 96, 'gte_stsxy3c': 94, 'lw': 80, 'lhu': 70, 'mfc2': 61} + gte mnemonics: {'gte_ldv0': 653, 'swc2': 449, 'lwc2': 432, 'gte_stsxy': 361, 'gte_rtps': 356, 'gte_stflg': 319, 'gte_rtpt': 289, 'gte_stsxy3': 191, 'gte_ldrgb': 162, 'gte_ldv3c': 159, 'gte_rt': 155, 'gte_SetRotMatrix': 150, 'gte_SetTransMatrix': 145, 'gte_stsv': 145, 'gte_stlvnl': 143, 'gte_ldv3': 140, 'gte_ldIR0z': 133, 'gte_ldIRGB': 133, 'gte_dpcl': 133, 'gte_stORGB': 133, 'gte_mvmva0': 131, 'gte_stsz4': 126, 'gte_stsz3': 123, 'gte_stszotz': 113, 'gte_nclip': 96, 'gte_stopz': 96, 'gte_stsxy3c': 94, 'lhu': 66, 'mfc2': 61, 'gte_stsxy3_f3': 61} asm-bearing macro definitions: 9,540 (338 names, 32 with >1 text) kinds {'gte': 9102, 'launder': 428, 'instruction': 9, 'barrier': 1} controls (R39): src/800.c func_800226C0 pins got 14 expected 45 N-A src/shared/ov/func_80178004.h pins got 8 expected 26 N-A ov_SC03_006 func_80184034 bare-name pins got 0 expected 3 N-A engine_prelude.h asm sites (a macro definition only) got 0 expected 0 OK - elapsed 39.0 s + elapsed 50.8 s diff --git a/.run/P36/gte/canonical.json b/.run/P36/gte/canonical.json new file mode 100644 index 000000000..9ece75a62 --- /dev/null +++ b/.run/P36/gte/canonical.json @@ -0,0 +1,1328 @@ +{ + "generated": "2026-09-09 05:22", + "canonical": { + "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce48|0|1": { + "name": "gte_SetRotMatrix", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lw $12, 0( %0 );\"\n \"lw $13, 4( %0 );\"\n \"ctc2 $12, $0;\"\n \"ctc2 $13, $1;\"\n \"lw $12, 8( %0 );\"\n \"lw $13, 12( %0 );\"\n \"lw $14, 16( %0 );\"\n \"ctc2 $12, $2;\"\n \"ctc2 $13, $3;\"\n \"ctc2 $14, $4\"\n :\n : \"r\"( r0 )\n : \"$12\", \"$13\", \"$14\" )", + "clob": [ + "$12", + "$13", + "$14" + ], + "defs": 1016, + "files": 244, + "synthesized": false, + "names": { + "gte_SetRotMatrix_139C8": 1, + "gte_SetRotMatrixX": 1, + "SETROT_DA34": 1, + "gte_SetRotMatrix_EA14": 1, + "SRM_8001EFE0": 1, + "SRM_8001F730": 1, + "SRM_80020248": 1, + "SRM_80020598": 1, + "SRM_80020A28": 1, + "gte_SetRotMatrix_21D38": 1, + "SRM221A8": 1, + "SetRot_80023BF0": 1, + "gte_SetRotMatrix": 982, + "SETROT_A": 2, + "gte_SetRotMatrix_E38": 1, + "gte_SetRotMatrix_87E08": 1, + "SRM_80189F30": 1, + "SRM_8018D720": 1, + "SRM_8018E208": 1, + "SRM_8018E8A0": 3, + "gte_SetRotMatrix_801837B0": 4, + "SRM_8018584C": 1, + "SRM_80186334": 1, + "SRM_FC6C": 1, + "SRM_80180838": 1, + "gte_SetRotMatrix_80187EE8": 1, + "SRM_80184958": 1, + "gte_SetRotMatrix_85810": 1, + "SRM_80186B78": 23, + "GTE_SMR": 1, + "ec4c_SetRotMatrix": 1, + "gte_SetRotMatrix_80180228": 1, + "gte_SetRotMatrix_80181164": 1, + "gte_SetRotMatrix_1": 4 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "lw $12, 0( %0 );lw $13, 4( %0 );ctc2 $12, $0;ctc2 $13, $1;lw $12, 8( %0 );lw $13, 12( %0 );lw $14, 16( %0 );ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4" + }, + "14008c8c18008d8c0028cc481c008e8c0030cd480038ce48|0|1": { + "name": "gte_SetTransMatrix", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lw $12, 20( %0 );\"\n \"lw $13, 24( %0 );\"\n \"ctc2 $12, $5;\"\n \"lw $14, 28( %0 );\"\n \"ctc2 $13, $6;\"\n \"ctc2 $14, $7\"\n :\n : \"r\"( r0 )\n : \"$12\", \"$13\", \"$14\" )", + "clob": [ + "$12", + "$13", + "$14" + ], + "defs": 1010, + "files": 243, + "synthesized": false, + "names": { + "gte_SetTransMatrix_EA14": 1, + "STM_8001EFE0": 1, + "STM_80020248": 1, + "STM_80020598": 1, + "STM_80020A28": 1, + "gte_SetTransMatrix_21D38": 1, + "STM221A8": 1, + "SetTrans_80023BF0": 1, + "gte_SetTransMatrix": 978, + "gte_SetTransMatrix_E38": 1, + "gte_SetTransMatrix_87E08": 1, + "STM_80189F30": 1, + "STM_8018D720": 1, + "STM_8018E208": 1, + "STM_8018E8A0": 3, + "gte_SetTransMatrix_801837B0": 4, + "STM_8018584C": 1, + "STM_80186334": 1, + "STM_FC6C": 1, + "STM_80180838": 1, + "gte_SetTransMatrix_80187EE8": 1, + "STM_80184958": 1, + "gte_SetTransMatrix_85810": 1, + "STM_80186B78": 23, + "ec4c_SetTransMatrix": 1, + "gte_SetTransMatrix_80180228": 1, + "gte_SetTransMatrix_80181164": 1, + "gte_SetTransMatrix_1": 4 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "lw $12, 20( %0 );lw $13, 24( %0 );ctc2 $12, $5;lw $14, 28( %0 );ctc2 $13, $6;ctc2 $14, $7" + }, + "000080c8040081c8|0|1": { + "name": "gte_ldv0", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lwc2 $0, 0( %0 );\"\n \"lwc2 $1, 4( %0 )\"\n :\n : \"r\"( r0 ) )", + "clob": [], + "defs": 690, + "files": 307, + "synthesized": false, + "names": { + "gte_ldv0": 839, + "LDV0_8001D8C4": 1, + "LDV0_DA34": 1, + "gte_ldv0_EA14": 1, + "ldv0_8001EFE0": 1, + "LDV0_8001F730": 1, + "gte_ldv0_21D38": 1, + "LDV0221A8": 1, + "LDV": 1, + "LDV_A": 2, + "gte_ldv0_801A8B64": 1, + "gte_ldv0_E38": 1, + "GTE_LDXY_8018209C": 1, + "gte_ldv0_801837B0": 4, + "gte_ldv0_801843D8": 4, + "gte_ldv0_80187EE8": 1, + "gte_ldv0_A60": 1, + "gte_ldv0_85810": 1, + "GTE_LDV0": 1, + "ec4c_ldv0": 1, + "gte_ldv0_80180228": 1, + "gte_ldv0_1": 2, + "gte_ldv0_2": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "lwc2 $0, 0( %0 );lwc2 $1, 4( %0 )" + }, + "00f84c480000000000008cac|0|1": { + "name": "gte_stflg", + "params": "(r0)", + "body": "__asm__ volatile (\n \"cfc2 $12, $31;\"\n \"nop;\"\n \"sw $12, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"$12\", \"memory\" )", + "clob": [ + "$12", + "memory" + ], + "defs": 697, + "files": 309, + "synthesized": false, + "names": { + "gte_stflg": 674, + "gte_stflg_EA14": 1, + "stflg_8001EFE0": 1, + "gte_stflg_21D38": 1, + "STFLG221A8": 1, + "gte_stflg_E38": 1, + "gte_stflg_80181E04": 1, + "GTE_STFLG_8018209C": 1, + "gte_stflg_801837B0": 4, + "gte_stflg_801843D8": 4, + "gte_stflg_80187EE8": 1, + "gte_stflg_A60": 1, + "gte_stflg_85810": 1, + "ec4c_stflg": 1, + "gte_stflg_80180228": 1, + "gte_stflg_1": 2, + "gte_stflg_2": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "cfc2 $12, $31;nop;sw $12, 0( %0 )" + }, + "00000000000000000100184a|0|0": { + "name": "gte_rtps", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;rtps\")", + "clob": [], + "defs": 681, + "files": 299, + "synthesized": false, + "names": { + "gte_rtps": 658, + "gte_rtps_EA14": 1, + "rtps_8001EFE0": 1, + "gte_rtps_21D38": 1, + "RTPS221A8": 1, + "gte_rtps_801A8B64": 1, + "gte_rtps_E38": 1, + "GTE_RTPS_8018209C": 1, + "gte_rtps_801837B0": 4, + "gte_rtps_801843D8": 4, + "gte_rtps_80187EE8": 1, + "gte_rtps_A60": 1, + "gte_rtps_85810": 1, + "ec4c_rtps": 1, + "gte_rtps_80180228": 1, + "gte_rtps_1": 2, + "gte_rtps_2": 1 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;rtps" + }, + "00008ee8|0|1": { + "name": "gte_stsxy", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $14, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 679, + "files": 299, + "synthesized": false, + "names": { + "gte_stsxy": 655, + "gte_stsxy_EA14": 1, + "stsxy_8001EFE0": 1, + "gte_stsxy_21D38": 1, + "STSXY221A8": 1, + "gte_stsxy2": 2, + "gte_stsxy_801A8B64": 1, + "gte_stsxy_E38": 1, + "GTE_STXY_8018209C": 1, + "gte_stsxy_801837B0": 4, + "gte_stsxy_801843D8": 4, + "gte_stsxy_80187EE8": 1, + "gte_stsxy_A60": 1, + "gte_stsxy_85810": 1, + "ec4c_stsxy": 1, + "gte_stsxy_80180228": 1, + "gte_stsxy_1": 2, + "gte_stsxy_2": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $14, 0( %0 )" + }, + "00000000000000001200484a|0|0": { + "name": "gte_rtv0tr", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;mvmva 1, 0, 0, 0, 0\")", + "clob": [], + "defs": 11, + "files": 10, + "synthesized": false, + "names": { + "MVMVA_8001D8C4": 1, + "RT_80020248": 1, + "RT_80020598": 1, + "RT_80020A28": 1, + "gte_rt": 34, + "gte_rt_21D38": 1, + "MVMVA": 1, + "gte_rtv0tr": 139, + "gte_mvmva0": 136, + "gte_rt_85810": 1, + "gte_rt_1": 2 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;mvmva 1, 0, 0, 0, 0" + }, + "000099e804009ae808009be8|0|1": { + "name": "gte_stlvnl", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $25, 0( %0 );\"\n \"swc2 $26, 4( %0 );\"\n \"swc2 $27, 8( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 291, + "files": 283, + "synthesized": false, + "names": { + "STMAC123_8001D8C4": 1, + "STLVNL_8001F730": 1, + "STLVNL_80020248": 1, + "STLVNL_80020598": 1, + "STLVNL_80020A28": 1, + "gte_stlvnl": 282, + "gte_stlvnl_21D38": 1, + "gte_stlvnl_85810": 1, + "gte_stlvnl_1": 2 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $25, 0( %0 );swc2 $26, 4( %0 );swc2 $27, 8( %0 )" + }, + "08008ce80c008de810008ee8|0|1": { + "name": "gte_stsxy3_f3", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $12, 8( %0 );\"\n \"swc2 $13, 12( %0 );\"\n \"swc2 $14, 16( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 250, + "files": 133, + "synthesized": false, + "names": { + "gte_stsxy3_f4": 118, + "gte_stsxy3_f3": 132 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $12, 8( %0 );swc2 $13, 12( %0 );swc2 $14, 16( %0 )" + }, + "00000000000000003000284a|0|0": { + "name": "gte_rtpt", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;rtpt\")", + "clob": [], + "defs": 249, + "files": 163, + "synthesized": false, + "names": { + "gte_rtpt": 228, + "gte_rtpt_EA14": 1, + "rtpt_8001EFE0": 1, + "gte_rtpt_21D38": 1, + "RTPT221A8": 1, + "gte_rtpt_E38": 1, + "gte_rtpt_80181E04": 1, + "gte_rtpt_801837B0": 4, + "gte_rtpt_801843D8": 4, + "gte_rtpt_80187EE8": 1, + "gte_rtpt_85810": 1, + "ec4c_rtpt": 1, + "gte_rtpt_80180228": 1, + "gte_rtpt_1": 2, + "gte_rtpt_2": 1 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;rtpt" + }, + "000080c8040081c80000a2c80400a3c80000c4c80400c5c8|0|3": { + "name": "gte_ldv3", + "params": "(r0, r1, r2)", + "body": "__asm__ volatile (\n \"lwc2 $0, 0( %0 );\"\n \"lwc2 $1, 4( %0 );\"\n \"lwc2 $2, 0( %1 );\"\n \"lwc2 $3, 4( %1 );\"\n \"lwc2 $4, 0( %2 );\"\n \"lwc2 $5, 4( %2 )\"\n :\n : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ) )", + "clob": [], + "defs": 227, + "files": 160, + "synthesized": false, + "names": { + "gte_ldv3": 207, + "ldv3_8001EFE0": 1, + "gte_ldv3_21D38": 1, + "LDV3221A8": 1, + "gte_ldv3_E38": 1, + "gte_ldv3_80181E04": 1, + "gte_ldv3_801837B0": 4, + "gte_ldv3_801843D8": 4, + "gte_ldv3_80187EE8": 1, + "gte_ldv3_85810": 1, + "ec4c_ldv3": 1, + "gte_ldv3_80180228": 1, + "gte_ldv3_1": 2, + "gte_ldv3_2": 1 + }, + "sony": true, + "nin": 3, + "nout": 0, + "tmpl": "lwc2 $0, 0( %0 );lwc2 $1, 4( %0 );lwc2 $2, 0( %1 );lwc2 $3, 4( %1 );lwc2 $4, 0( %2 );lwc2 $5, 4( %2 )" + }, + "00008ce80000ade80000cee8|0|3": { + "name": "gte_stsxy3", + "params": "(r0, r1, r2)", + "body": "__asm__ volatile (\n \"swc2 $12, 0( %0 );\"\n \"swc2 $13, 0( %1 );\"\n \"swc2 $14, 0( %2 )\"\n :\n : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 219, + "files": 159, + "synthesized": false, + "names": { + "gte_stsxy3": 202, + "gte_stsxy3_21D38": 1, + "STSXY3221A8": 1, + "gte_stsxy3_E38": 1, + "gte_stsxy3_801837B0": 4, + "gte_stsxy3_801843D8": 4, + "gte_stsxy3_80187EE8": 1, + "ec4c_stsxy3": 1, + "gte_stsxy3_80180228": 1, + "gte_stsxy3_1": 2, + "gte_stsxy3_2": 1 + }, + "sony": true, + "nin": 3, + "nout": 0, + "tmpl": "swc2 $12, 0( %0 );swc2 $13, 0( %1 );swc2 $14, 0( %2 )" + }, + "00980c480000000083600c0000008cac|0|1": { + "name": "gte_stszotz", + "params": "(r0)", + "body": "__asm__ volatile (\n \"mfc2 $12, $19;\"\n \"nop;\"\n \"sra $12, $12, 2;\"\n \"sw $12, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"$12\", \"memory\" )", + "clob": [ + "$12", + "memory" + ], + "defs": 209, + "files": 146, + "synthesized": false, + "names": { + "gte_stszotz_EA14": 1, + "stszotz_8001EFE0": 1, + "gte_stszotz": 201, + "gte_stszotz_21D38": 1, + "STSZOTZ221A8": 1, + "gte_stotz": 1, + "gte_stszotz_A60": 1, + "gte_stszotz_85810": 1, + "gte_stszotz_2": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "mfc2 $12, $19;nop;sra $12, $12, 2;sw $12, 0( %0 )" + }, + "00000000000000000600404b|0|0": { + "name": "gte_nclip", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;nclip\")", + "clob": [], + "defs": 186, + "files": 142, + "synthesized": false, + "names": { + "gte_nclip": 186 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;nclip" + }, + "000098e8|0|1": { + "name": "gte_stopz", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $24, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 186, + "files": 142, + "synthesized": false, + "names": { + "gte_stopz": 186 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $24, 0( %0 )" + }, + "000091e80000b2e80000d3e8|0|3": { + "name": "gte_stsz3", + "params": "(r0, r1, r2)", + "body": "__asm__ volatile (\n \"swc2 $17, 0( %0 );\"\n \"swc2 $18, 0( %1 );\"\n \"swc2 $19, 0( %2 )\"\n :\n : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 166, + "files": 142, + "synthesized": false, + "names": { + "gte_stsz3": 165, + "gte_stsz3_80181E04": 1 + }, + "sony": true, + "nin": 3, + "nout": 0, + "tmpl": "swc2 $17, 0( %0 );swc2 $18, 0( %1 );swc2 $19, 0( %2 )" + }, + "000090e80000b1e80000d2e80000f3e8|0|4": { + "name": "gte_stsz4", + "params": "(r0, r1, r2, r3)", + "body": "__asm__ volatile (\n \"swc2 $16, 0( %0 );\"\n \"swc2 $17, 0( %1 );\"\n \"swc2 $18, 0( %2 );\"\n \"swc2 $19, 0( %3 )\"\n :\n : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 ), \"r\"( r3 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 156, + "files": 140, + "synthesized": false, + "names": { + "gte_stsz4": 166 + }, + "sony": true, + "nin": 4, + "nout": 0, + "tmpl": "swc2 $16, 0(%0);swc2 $17, 0(%1);swc2 $18, 0(%2);swc2 $19, 0(%3)" + }, + "000080c8040081c8080082c80c0083c8100084c8140085c8|0|1": { + "name": "gte_ldv3c", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lwc2 $0, 0( %0 );\"\n \"lwc2 $1, 4( %0 );\"\n \"lwc2 $2, 8( %0 );\"\n \"lwc2 $3, 12( %0 );\"\n \"lwc2 $4, 16( %0 );\"\n \"lwc2 $5, 20( %0 )\"\n :\n : \"r\"( r0 ) )", + "clob": [], + "defs": 163, + "files": 140, + "synthesized": false, + "names": { + "gte_ldv3c": 163 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "lwc2 $0, 0( %0 );lwc2 $1, 4( %0 );lwc2 $2, 8( %0 );lwc2 $3, 12( %0 );lwc2 $4, 16( %0 );lwc2 $5, 20( %0 )" + }, + "00008ce804008de808008ee8|0|1": { + "name": "gte_stsxy3c", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $12, 0( %0 );\"\n \"swc2 $13, 4( %0 );\"\n \"swc2 $14, 8( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 163, + "files": 141, + "synthesized": false, + "names": { + "gte_stsxy3c": 162, + "gte_stsxy3": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $12, 0( %0 );swc2 $13, 4( %0 );swc2 $14, 8( %0 )" + }, + "000086c8|0|1": { + "name": "gte_ldrgb", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lwc2 $6, 0( %0 )\"\n :\n : \"r\"( r0 ) )", + "clob": [], + "defs": 19, + "files": 2, + "synthesized": false, + "names": { + "LDRGB_DA34": 1, + "gte_ldrgb": 155 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "lwc2 $6, 0( %0 )" + }, + "08008ce810008de818008ee8|0|1": { + "name": "gte_stsxy3_ft3", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $12, 8( %0 );\"\n \"swc2 $13, 16( %0 );\"\n \"swc2 $14, 24( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 155, + "files": 124, + "synthesized": false, + "names": { + "gte_stsxy3_g3": 7, + "gte_stsxy3_g4": 6, + "gte_stsxy3_ft4": 2, + "gte_stsxy3_gt3": 1, + "gte_stsxy3_flat": 1, + "gte_stsxy3_gt4": 1, + "gte_stsxy3_ft3": 137 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $12, 8( %0 );swc2 $13, 16( %0 );swc2 $14, 24( %0 )" + }, + "04008d9400008c94006c0d0025608d0100008c48080081c8|0|1": { + "name": "gte_ldlv0", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lhu $13, 4( %0 );\"\n \"lhu $12, 0( %0 );\"\n \"sll $13, $13, 16;\"\n \"or $12, $12, $13;\"\n \"mtc2 $12, $0;\"\n \"lwc2 $1, 8( %0 )\"\n :\n : \"r\"( r0 )\n : \"$12\", \"$13\" )", + "clob": [ + "$12", + "$13" + ], + "defs": 145, + "files": 143, + "synthesized": false, + "names": { + "LDLVL_80020248": 1, + "LDLVL_80020598": 1, + "gte_ldlv0": 139, + "gte_ldlvl_85810": 1, + "gte_ldlvnl": 1, + "gte_ldlv0_1": 2 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "lhu $13, 4( %0 );lhu $12, 0( %0 );sll $13, $13, 16;or $12, $12, $13;mtc2 $12, $0;lwc2 $1, 8( %0 )" + }, + "00408048|0|0": { + "name": "gte_ldIR0z", + "params": "()", + "body": "__asm__ __volatile__(\"mtc2 $0, $8\")", + "clob": [], + "defs": 136, + "files": 136, + "synthesized": false, + "names": { + "gte_ldIR0z": 136 + }, + "sony": false, + "nin": 0, + "nout": 0, + "tmpl": "mtc2 $0, $8" + }, + "00009cc8|0|1": { + "name": "gte_ldIRGB", + "params": "(p)", + "body": "__asm__ __volatile__(\"lwc2 $28, 0(%0)\" :: \"r\"(p) : \"memory\")", + "clob": [ + "memory" + ], + "defs": 136, + "files": 136, + "synthesized": false, + "names": { + "gte_ldIRGB": 136 + }, + "sony": false, + "nin": 1, + "nout": 0, + "tmpl": "lwc2 $28, 0(%0)" + }, + "00000000000000002900684a|0|0": { + "name": "gte_dpcl", + "params": "()", + "body": "__asm__ __volatile__(\"nop\\n\\tnop\\n\\tdpcl\")", + "clob": [], + "defs": 136, + "files": 136, + "synthesized": false, + "names": { + "gte_dpcl": 136 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop\\n\\tnop\\n\\tdpcl" + }, + "00009de8|0|1": { + "name": "gte_stORGB", + "params": "(p)", + "body": "__asm__ __volatile__(\"swc2 $29, 0(%0)\" :: \"r\"(p) : \"memory\")", + "clob": [ + "memory" + ], + "defs": 136, + "files": 136, + "synthesized": false, + "names": { + "gte_stORGB": 136 + }, + "sony": false, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $29, 0(%0)" + }, + "00000000000000002e00684b|0|0": { + "name": "gte_avsz4", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;avsz4\")", + "clob": [], + "defs": 57, + "files": 34, + "synthesized": false, + "names": { + "gte_avsz4": 42, + "gte_avsz4_E38": 1, + "gte_avsz4_801837B0": 4, + "gte_avsz4_801843D8": 4, + "gte_avsz4_80187EE8": 1, + "ec4c_avsz4": 1, + "gte_avsz4_80180228": 1, + "gte_avsz4_1": 2, + "gte_avsz4_2": 1 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;avsz4" + }, + "000087e8|0|1": { + "name": "gte_stotz", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $7, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 51, + "files": 19, + "synthesized": false, + "names": { + "gte_stotz": 36, + "gte_stotz_E38": 1, + "gte_stotz_801837B0": 4, + "gte_stotz_801843D8": 4, + "gte_stotz_80187EE8": 1, + "ec4c_stotz": 1, + "gte_stotz_80180228": 1, + "gte_stotz_1": 2, + "gte_stotz_2": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $7, 0( %0 )" + }, + "00480c4800500d4800580e4800008ca402008da404008ea4|0|1": { + "name": "gte_stsv", + "params": "(r0)", + "body": "__asm__ __volatile__(\n \"mfc2 $12, $9\\n\"\n \"mfc2 $13, $10\\n\"\n \"mfc2 $14, $11\\n\"\n \"sh $12, 0(%0)\\n\"\n \"sh $13, 2(%0)\\n\"\n \"sh $14, 4(%0)\\n\"\n : : \"r\"(r0) : \"$12\", \"$13\", \"$14\", \"memory\")", + "clob": [ + "$12", + "$13", + "$14", + "memory" + ], + "defs": 33, + "files": 21, + "synthesized": false, + "names": { + "STSV": 1, + "STSV_A": 2, + "gte_stsv": 29, + "GTE_STSV": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "mfc2 $12, $9\\nmfc2 $13, $10\\nmfc2 $14, $11\\nsh $12, 0(%0)\\nsh $13, 2(%0)\\nsh $14, 4(%0)\\n" + }, + "00000000000000002d00584b|0|0": { + "name": "gte_avsz3", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;avsz3\")", + "clob": [], + "defs": 28, + "files": 21, + "synthesized": false, + "names": { + "gte_avsz3": 28 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;avsz3" + }, + "00000000000000001b04084b|0|0": { + "name": "gte_nccs", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;nccs\")", + "clob": [], + "defs": 15, + "files": 2, + "synthesized": false, + "names": { + "NCCS_DA34": 1, + "gte_nccs": 14 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;nccs" + }, + "000096e8|0|1": { + "name": "gte_strgb", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $22, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 15, + "files": 2, + "synthesized": false, + "names": { + "STRGB_DA34": 1, + "gte_strgb": 12, + "gte_strgb2": 2 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $22, 0( %0 )" + }, + "000093e8|0|1": { + "name": "gte_stsz", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $19, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 15, + "files": 12, + "synthesized": false, + "names": { + "gte_stsz_EA14": 1, + "stsz_8001EFE0": 1, + "gte_stsz_21D38": 1, + "STSZ221A8": 1, + "gte_stsz": 9, + "gte_stsz_80180B3C": 1, + "gte_stsz_85810": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $19, 0( %0 )" + }, + "00008c9406008d940c008e9400488c4800508d4800588e48|0|1": { + "name": "gte_ldclmv", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lhu $12, 0( %0 );\"\n \"lhu $13, 6( %0 );\"\n \"lhu $14, 12( %0 );\"\n \"mtc2 $12, $9;\"\n \"mtc2 $13, $10;\"\n \"mtc2 $14, $11\"\n :\n : \"r\"( r0 )\n : \"$12\", \"$13\", \"$14\" )", + "clob": [ + "$12", + "$13", + "$14" + ], + "defs": 12, + "files": 6, + "synthesized": false, + "names": { + "gte_ldclmv_139C8": 1, + "gte_ldclmvX": 1, + "LDCLMV_DA34": 1, + "LDCLMV_80020248": 1, + "LDCLMV_80020598": 1, + "LDCLMV_80020A28": 1, + "gte_ldclmv_85810": 1, + "gte_ldclmv": 3, + "gte_ldclmv_1": 2 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "lhu $12, 0( %0 );lhu $13, 6( %0 );lhu $14, 12( %0 );mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11" + }, + "000000000000000012e0494a|0|0": { + "name": "gte_rtir", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;mvmva 1, 0, 3, 3, 0\")", + "clob": [], + "defs": 9, + "files": 6, + "synthesized": false, + "names": { + "gte_rtir_139C8": 1, + "gte_rtirX": 1, + "RTIR_DA34": 1, + "RTIR_80020248": 1, + "RTIR_80020598": 1, + "RTIR_80020A28": 1, + "gte_rtir_85810": 1, + "gte_rtir": 3, + "gte_rtir_1": 2 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;mvmva 1, 0, 3, 3, 0" + }, + "00480c4800500d4800580e4800008ca406008da40c008ea4|0|1": { + "name": "gte_stclmv", + "params": "(r0)", + "body": "__asm__ volatile (\n \"mfc2 $12, $9;\"\n \"mfc2 $13, $10;\"\n \"mfc2 $14, $11;\"\n \"sh $12, 0( %0 );\"\n \"sh $13, 6( %0 );\"\n \"sh $14, 12( %0 )\"\n :\n : \"r\"( r0 )\n : \"$12\", \"$13\", \"$14\", \"memory\" )", + "clob": [ + "$12", + "$13", + "$14", + "memory" + ], + "defs": 11, + "files": 6, + "synthesized": false, + "names": { + "gte_stclmv_139C8": 1, + "gte_stclmvX": 1, + "STCLMV_DA34": 1, + "STCLMV_80020248": 1, + "STCLMV_80020598": 1, + "STCLMV_80020A28": 1, + "gte_stclmv_85810": 1, + "gte_stclmv": 3, + "gte_stclmv_1": 2 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0( %0 );sh $13, 6( %0 );sh $14, 12( %0 )" + }, + "00000000000000003f04184b|0|0": { + "name": "gte_ncct", + "params": "()", + "body": "__asm__ volatile (\"nop;nop;ncct\")", + "clob": [], + "defs": 10, + "files": 2, + "synthesized": false, + "names": { + "gte_ncct": 10 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;ncct" + }, + "00008ce8|0|1": { + "name": "gte_stsxy0", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $12, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 6, + "files": 5, + "synthesized": false, + "names": { + "gte_stsxy0_EA14": 1, + "stsxy0_8001EFE0": 1, + "gte_stsxy0": 1, + "gte_stsxy0_80180B3C": 1, + "gte_stsxy0_85810": 1, + "gte_stsxy0_2": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $12, 0( %0 )" + }, + "00008de8|0|1": { + "name": "gte_stsxy1", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $13, 0( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 6, + "files": 5, + "synthesized": false, + "names": { + "gte_stsxy1_EA14": 1, + "stsxy1_8001EFE0": 1, + "gte_stsxy1": 1, + "gte_stsxy1_80180B3C": 1, + "gte_stsxy1_85810": 1, + "gte_stsxy1_2": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $13, 0( %0 )" + }, + "00000000000000001260484a|0|0": { + "name": "gte_rtv0", + "params": "()", + "body": "__asm__ __volatile__(\n \"nop\\n\"\n \"nop\\n\"\n \"mvmva 1, 0, 0, 3, 0\\n\" )", + "clob": [], + "defs": 0, + "files": 0, + "synthesized": true, + "names": { + "RTV0_8001F730": 1, + "MVMVA_A": 2, + "gte_rtv0": 2, + "GTE_RTV0": 1 + }, + "sony": true, + "nin": 0, + "nout": 0, + "tmpl": "nop;nop;mvmva 1, 0, 0, 3, 0" + }, + "040094e80c0095e8140096e8|0|1": { + "name": "gte_strgb3_g3", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $20, 4( %0 );\"\n \"swc2 $21, 12( %0 );\"\n \"swc2 $22, 20( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 6, + "files": 2, + "synthesized": false, + "names": { + "gte_strgb3_g3": 2, + "gte_strgb3_g4": 2, + "gte_strgb3_flat": 1, + "gte_strgb3_gt4": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $20, 4( %0 );swc2 $21, 12( %0 );swc2 $22, 20( %0 )" + }, + "000094e80000b5e80000d6e8|0|3": { + "name": "gte_strgb3", + "params": "(r0, r1, r2)", + "body": "__asm__ volatile (\n \"swc2 $20, 0( %0 );\"\n \"swc2 $21, 0( %1 );\"\n \"swc2 $22, 0( %2 )\"\n :\n : \"r\"( r0 ), \"r\"( r1 ), \"r\"( r2 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 4, + "files": 2, + "synthesized": false, + "names": { + "gte_strgb3_gt3": 2, + "gte_strgb3": 2 + }, + "sony": true, + "nin": 3, + "nout": 0, + "tmpl": "swc2 $20, 0( %0 );swc2 $21, 0( %1 );swc2 $22, 0( %2 )" + }, + "08008ce814008de820008ee8|0|1": { + "name": "gte_stsxy3_gt4", + "params": "(r0)", + "body": "__asm__ volatile (\n \"swc2 $12, 8( %0 );\"\n \"swc2 $13, 20( %0 );\"\n \"swc2 $14, 32( %0 )\"\n :\n : \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 3, + "files": 2, + "synthesized": false, + "names": { + "gte_stsxy3_gt4": 2, + "gte_stsxy3_gt3": 1 + }, + "sony": true, + "nin": 1, + "nout": 0, + "tmpl": "swc2 $12, 8( %0 );swc2 $13, 20( %0 );swc2 $14, 32( %0 )" + }, + "00008c9406008d940c008e9400488c4800508d4800588e48000000000000000012e0494a00480c4800500d4800580e4800008ca406008da40c008ea4|0|1": { + "name": "gte_mulcol", + "params": "(r0)", + "body": "__asm__ __volatile__ (\n \"lhu $12, 0(%0)\\n\" \"lhu $13, 6(%0)\\n\" \"lhu $14, 12(%0)\\n\"\n \"mtc2 $12, $9\\n\" \"mtc2 $13, $10\\n\" \"mtc2 $14, $11\\n\"\n \"nop\\n\" \"nop\\n\" \"mvmva 1, 0, 3, 3, 0\\n\"\n \"mfc2 $12, $9\\n\" \"mfc2 $13, $10\\n\" \"mfc2 $14, $11\\n\"\n \"sh $12, 0(%0)\\n\" \"sh $13, 6(%0)\\n\" \"sh $14, 12(%0)\\n\"\n : : \"r\"(r0) : \"$12\", \"$13\", \"$14\", \"memory\")", + "clob": [ + "$12", + "$13", + "$14", + "memory" + ], + "defs": 2, + "files": 2, + "synthesized": false, + "names": { + "gte_mulcol_E38": 1, + "ec4c_rotcol": 1 + }, + "sony": false, + "nin": 1, + "nout": 0, + "tmpl": "lhu $12, 0(%0)\\nlhu $13, 6(%0)\\nlhu $14, 12(%0)\\nmtc2 $12, $9\\nmtc2 $13, $10\\nmtc2 $14, $11\\nnop\\nnop\\nmvmva 1, 0, 3, 3, 0\\nmfc2 $12, $9\\nmfc2 $13, $10\\nmfc2 $14, $11\\nsh $12, 0(%0)\\nsh $13, 6(%0)\\nsh $14, 12(%0)\\n" + }, + "04008d9400008c94006c0d0025608d0100008c48080081c800000000000000001200484a000099e804009ae808009be8|0|1": { + "name": "gte_multrans", + "params": "(r0)", + "body": "__asm__ __volatile__ (\n \"lhu $13, 4(%0)\\n\" \"lhu $12, 0(%0)\\n\"\n \"sll $13, $13, 16\\n\" \"or $12, $12, $13\\n\"\n \"mtc2 $12, $0\\n\" \"lwc2 $1, 8(%0)\\n\"\n \"nop\\n\" \"nop\\n\" \"mvmva 1, 0, 0, 0, 0\\n\"\n \"swc2 $25, 0(%0)\\n\" \"swc2 $26, 4(%0)\\n\" \"swc2 $27, 8(%0)\\n\"\n : : \"r\"(r0) : \"$12\", \"$13\", \"memory\")", + "clob": [ + "$12", + "$13", + "memory" + ], + "defs": 2, + "files": 2, + "synthesized": false, + "names": { + "gte_multrans_E38": 1, + "ec4c_rottrans": 1 + }, + "sony": false, + "nin": 1, + "nout": 0, + "tmpl": "lhu $13, 4(%0)\\nlhu $12, 0(%0)\\nsll $13, $13, 16\\nor $12, $12, $13\\nmtc2 $12, $0\\nlwc2 $1, 8(%0)\\nnop\\nnop\\nmvmva 1, 0, 0, 0, 0\\nswc2 $25, 0(%0)\\nswc2 $26, 4(%0)\\nswc2 $27, 8(%0)\\n" + }, + "000080c8040081c80000a2c80400a3c80000a4c80400a5c8|0|2": { + "name": "gte_ldv3_alt", + "params": "(r0, r1)", + "body": "__asm__ volatile (\n \"lwc2 $0, 0( %0 );\"\n \"lwc2 $1, 4( %0 );\"\n \"lwc2 $2, 0( %1 );\"\n \"lwc2 $3, 4( %1 );\"\n \"lwc2 $4, 0( %1 );\"\n \"lwc2 $5, 4( %1 )\"\n :\n : \"r\"( r0 ), \"r\"( r1 ) )", + "clob": [], + "defs": 1, + "files": 1, + "synthesized": false, + "names": { + "gte_ldv3_EA14": 1 + }, + "sony": false, + "nin": 2, + "nout": 0, + "tmpl": "lwc2 $0, 0( %0 );lwc2 $1, 4( %0 );lwc2 $2, 0( %1 );lwc2 $3, 4( %1 );lwc2 $4, 0( %1 );lwc2 $5, 4( %1 )" + }, + "0000a0c80400a1c800000000000000001260484a000099e804009ae808009be8|0|2": { + "name": "gte_rt_alt", + "params": "(r1, r0)", + "body": "__asm__ volatile (\n \"lwc2 $0, 0( %1 );\"\n \"lwc2 $1, 4( %1 );\"\n \"nop;\"\n \"nop;\"\n \"mvmva 1, 0, 0, 3, 0;\"\n \"swc2 $25, 0( %0 );\"\n \"swc2 $26, 4( %0 );\"\n \"swc2 $27, 8( %0 )\"\n :\n : \"r\"( r1 ), \"r\"( r0 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 1, + "files": 1, + "synthesized": false, + "names": { + "gte_rt_EA14": 1 + }, + "sony": false, + "nin": 2, + "nout": 0, + "tmpl": "lwc2 $0, 0( %1 );lwc2 $1, 4( %1 );nop;nop;mvmva 1, 0, 0, 3, 0;swc2 $25, 0( %0 );swc2 $26, 4( %0 );swc2 $27, 8( %0 )" + }, + "01008d8000008c80006c0d0000640c0002640c0025608d0102008d8000008c4800088d48|0|1": { + "name": "gte_ldlvl_alt", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lb $13, 1( %0 );\"\n \"lb $12, 0( %0 );\"\n \"sll $13, $13, 16;\"\n \"sll $12, $12, 16;\"\n \"srl $12, $12, 16;\"\n \"or $12, $12, $13;\"\n \"lb $13, 2( %0 );\"\n \"mtc2 $12, $0;\"\n \"mtc2 $13, $1\"\n :\n : \"r\"( r0 )\n : \"$12\", \"$13\" )", + "clob": [ + "$12", + "$13" + ], + "defs": 1, + "files": 1, + "synthesized": false, + "names": { + "LDLVL_80020A28": 1 + }, + "sony": false, + "nin": 1, + "nout": 0, + "tmpl": "lb $13, 1( %0 );lb $12, 0( %0 );sll $13, $13, 16;sll $12, $12, 16;srl $12, $12, 16;or $12, $12, $13;lb $13, 2( %0 );mtc2 $12, $0;mtc2 $13, $1" + }, + "00008ce80000ade8|0|2": { + "name": "gte_stsxy01", + "params": "(r0, r1)", + "body": "__asm__ volatile (\n \"swc2 $12, 0( %0 );\"\n \"swc2 $13, 0( %1 )\"\n :\n : \"r\"( r0 ), \"r\"( r1 )\n : \"memory\" )", + "clob": [ + "memory" + ], + "defs": 1, + "files": 1, + "synthesized": false, + "names": { + "gte_stsxy01_80181E04": 1 + }, + "sony": true, + "nin": 2, + "nout": 0, + "tmpl": "swc2 $12, 0( %0 );swc2 $13, 0( %1 )" + }, + "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce4814008c8c18008d8c0028cc481c008e8c0030cd480038ce48|0|1": { + "name": "gte_SetRotTransMatrix", + "params": "(r0)", + "body": "__asm__ volatile (\n \"lw $12, 0( %0 );\"\n \"lw $13, 4( %0 );\"\n \"ctc2 $12, $0;\"\n \"ctc2 $13, $1;\"\n \"lw $12, 8( %0 );\"\n \"lw $13, 12( %0 );\"\n \"lw $14, 16( %0 );\"\n \"ctc2 $12, $2;\"\n \"ctc2 $13, $3;\"\n \"ctc2 $14, $4;\"\n \"lw $12, 20( %0 );\"\n \"lw $13, 24( %0 );\"\n \"ctc2 $12, $5;\"\n \"lw $14, 28( %0 );\"\n \"ctc2 $13, $6;\"\n \"ctc2 $14, $7\"\n :\n : \"r\"( r0 )\n : \"$12\", \"$13\", \"$14\" )", + "clob": [ + "$12", + "$13", + "$14" + ], + "defs": 1, + "files": 1, + "synthesized": false, + "names": { + "gte_SetRotTransMatrix_A60": 1 + }, + "sony": false, + "nin": 1, + "nout": 0, + "tmpl": "lw $12, 0( %0 );lw $13, 4( %0 );ctc2 $12, $0;ctc2 $13, $1;lw $12, 8( %0 );lw $13, 12( %0 );lw $14, 16( %0 );ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;lw $12, 20( %0 );lw $13, 24( %0 );ctc2 $12, $5;lw $14, 28( %0 );ctc2 $13, $6;ctc2 $14, $7" + } + }, + "variants": { + "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce48|0|1|$12|$13|$14|memory": { + "name": "gte_SetRotMatrix_m", + "of": "gte_SetRotMatrix", + "key": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce48|0|1", + "clob": [ + "$12", + "$13", + "$14", + "memory" + ], + "extra": [ + "memory" + ], + "fewer": [], + "defs": 30, + "files": 13 + }, + "14008c8c18008d8c0028cc481c008e8c0030cd480038ce48|0|1|$12|$13|$14|memory": { + "name": "gte_SetTransMatrix_m", + "of": "gte_SetTransMatrix", + "key": "14008c8c18008d8c0028cc481c008e8c0030cd480038ce48|0|1", + "clob": [ + "$12", + "$13", + "$14", + "memory" + ], + "extra": [ + "memory" + ], + "fewer": [], + "defs": 25, + "files": 10 + }, + "000080c8040081c8|0|1|memory": { + "name": "gte_ldv0_m", + "of": "gte_ldv0", + "key": "000080c8040081c8|0|1", + "clob": [ + "memory" + ], + "extra": [ + "memory" + ], + "fewer": [], + "defs": 179, + "files": 163 + }, + "00008ee8|0|1|": { + "name": "gte_stsxy_vda39", + "of": "gte_stsxy", + "key": "00008ee8|0|1", + "clob": [], + "extra": [], + "fewer": [ + "memory" + ], + "defs": 1, + "files": 1 + }, + "00000000000000001200484a|0|0|memory": { + "name": "gte_rtv0tr_m", + "of": "gte_rtv0tr", + "key": "00000000000000001200484a|0|0", + "clob": [ + "memory" + ], + "extra": [ + "memory" + ], + "fewer": [], + "defs": 307, + "files": 293 + }, + "000090e80000b1e80000d2e80000f3e8|0|4|": { + "name": "gte_stsz4_vda39", + "of": "gte_stsz4", + "key": "000090e80000b1e80000d2e80000f3e8|0|4", + "clob": [], + "extra": [], + "fewer": [ + "memory" + ], + "defs": 10, + "files": 10 + }, + "000086c8|0|1|memory": { + "name": "gte_ldrgb_m", + "of": "gte_ldrgb", + "key": "000086c8|0|1", + "clob": [ + "memory" + ], + "extra": [ + "memory" + ], + "fewer": [], + "defs": 137, + "files": 137 + }, + "000000000000000012e0494a|0|0|memory": { + "name": "gte_rtir_m", + "of": "gte_rtir", + "key": "000000000000000012e0494a|0|0", + "clob": [ + "memory" + ], + "extra": [ + "memory" + ], + "fewer": [], + "defs": 3, + "files": 1 + }, + "00480c4800500d4800580e4800008ca406008da40c008ea4|0|1|$12|$13|$14": { + "name": "gte_stclmv_v41be", + "of": "gte_stclmv", + "key": "00480c4800500d4800580e4800008ca406008da40c008ea4|0|1", + "clob": [ + "$12", + "$13", + "$14" + ], + "extra": [], + "fewer": [ + "memory" + ], + "defs": 1, + "files": 1 + }, + "00000000000000001260484a|0|0|memory": { + "name": "gte_rtv0_m", + "of": "gte_rtv0", + "key": "00000000000000001260484a|0|0", + "clob": [ + "memory" + ], + "extra": [ + "memory" + ], + "fewer": [], + "defs": 6, + "files": 5 + } + }, + "unsigned": [ + { + "tu": "src/md_MAIN_019/md_MAIN_019.c", + "name": "gte_rt", + "l0": 315 + } + ] +} \ No newline at end of file diff --git a/.run/P36/gte/sig_cache.json b/.run/P36/gte/sig_cache.json new file mode 100644 index 000000000..fdeba473d --- /dev/null +++ b/.run/P36/gte/sig_cache.json @@ -0,0 +1,142 @@ +{ +"lw $12, 0( $4 );lw $13, 4( $4 );ctc2 $12, $0;ctc2 $13, $1;lw $12, 8( $4 );lw $13, 12( $4 );lw $14, 16( $4 );ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce48", +"lhu $12, 0( $4 );lhu $13, 6( $4 );lhu $14, 12( $4 );mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11": "00008c9406008d940c008e9400488c4800508d4800588e48", +"nop;nop;mvmva 1, 0, 3, 3, 0": "000000000000000012e0494a", +"mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0( $4 );sh $13, 6( $4 );sh $14, 12( $4 )": "00480c4800500d4800580e4800008ca406008da40c008ea4", +"lw $12, 0($4);lw $13, 4($4);ctc2 $12, $0;ctc2 $13, $1;lw $12, 8($4);lw $13, 12($4);lw $14, 16($4);ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce48", +"lhu $12, 0($4);lhu $13, 6($4);lhu $14, 12($4);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11": "00008c9406008d940c008e9400488c4800508d4800588e48", +"nop; nop; mvmva 1, 0, 3, 3, 0": "000000000000000012e0494a", +"mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($4);sh $13, 6($4);sh $14, 12($4)": "00480c4800500d4800580e4800008ca406008da40c008ea4", +"lwc2 $0, 0( $4 );lwc2 $1, 4( $4 )": "000080c8040081c8", +"lwc2 $0, 0( $4 );lwc2 $1, 4( $4 );lwc2 $2, 0( $5 );lwc2 $3, 4( $5 );lwc2 $4, 0( $6 );lwc2 $5, 4( $6 )": "000080c8040081c80000a2c80400a3c80000c4c80400c5c8", +"nop;nop;rtps": "00000000000000000100184a", +"nop;nop;rtpt": "00000000000000003000284a", +"nop;nop;avsz4": "00000000000000002e00684b", +"swc2 $14, 0( $4 )": "00008ee8", +"swc2 $12, 0( $4 );swc2 $13, 0( $5 );swc2 $14, 0( $6 )": "00008ce80000ade80000cee8", +"swc2 $7, 0( $4 )": "000087e8", +"cfc2 $12, $31;nop;sw $12, 0( $4 )": "00f84c480000000000008cac", +"nop;nop;mvmva 1, 0, 0, 0, 0": "00000000000000001200484a", +"swc2 $25, 0( $4 );swc2 $26, 4( $4 );swc2 $27, 8( $4 )": "000099e804009ae808009be8", +"lwc2 $6, 0( $4 )": "000086c8", +"nop;nop;nccs": "00000000000000001b04084b", +"swc2 $22, 0( $4 )": "000096e8", +"lw $12, 20( $4 );lw $13, 24( $4 );ctc2 $12, $5;lw $14, 28( $4 );ctc2 $13, $6;ctc2 $14, $7": "14008c8c18008d8c0028cc481c008e8c0030cd480038ce48", +"lwc2 $0, 0( $4 );lwc2 $1, 4( $4 );lwc2 $2, 0( $5 );lwc2 $3, 4( $5 );lwc2 $4, 0( $5 );lwc2 $5, 4( $5 )": "000080c8040081c80000a2c80400a3c80000a4c80400a5c8", +"swc2 $12, 0( $4 )": "00008ce8", +"swc2 $13, 0( $4 )": "00008de8", +"swc2 $19, 0( $4 )": "000093e8", +"mfc2 $12, $19;nop;sra $12, $12, 2;sw $12, 0( $4 )": "00980c480000000083600c0000008cac", +"lwc2 $0, 0( $5 );lwc2 $1, 4( $5 );nop;nop;mvmva 1, 0, 0, 3, 0;swc2 $25, 0( $4 );swc2 $26, 4( $4 );swc2 $27, 8( $4 )": "0000a0c80400a1c800000000000000001260484a000099e804009ae808009be8", +"nop;nop;mvmva 1, 0, 0, 3, 0": "00000000000000001260484a", +"lhu $13, 4( $4 );lhu $12, 0( $4 );sll $13, $13, 16;or $12, $12, $13;mtc2 $12, $0;lwc2 $1, 8( $4 )": "04008d9400008c94006c0d0025608d0100008c48080081c8", +"lb $13, 1( $4 );lb $12, 0( $4 );sll $13, $13, 16;sll $12, $12, 16;srl $12, $12, 16;or $12, $12, $13;lb $13, 2( $4 );mtc2 $12, $0;mtc2 $13, $1": "01008d8000008c80006c0d0000640c0002640c0025608d0102008d8000008c4800088d48", +"lwc2 $0, 0($4)\nlwc2 $1, 4($4)\n": "000080c8040081c8", +"nop\nnop\nmvmva 1, 0, 0, 0, 0\n": "00000000000000001200484a", +"swc2 $25, 0($4)\nswc2 $26, 4($4)\nswc2 $27, 8($4)\n": "000099e804009ae808009be8", +"cfc2 $12, $31\nnop\nsw $12, 0($4)\n": "00f84c480000000000008cac", +"nop;nop;nclip": "00000000000000000600404b", +"swc2 $24, 0( $4 )": "000098e8", +"lw $12, 20($4);lw $13, 24($4);ctc2 $12, $5;lw $14, 28($4);ctc2 $13, $6;ctc2 $14, $7": "14008c8c18008d8c0028cc481c008e8c0030cd480038ce48", +"swc2 $12, 8( $4 );swc2 $13, 12( $4 );swc2 $14, 16( $4 )": "08008ce80c008de810008ee8", +"nop;nop;avsz3": "00000000000000002d00584b", +"cfc2 $12, $31;nop;sw $12, 0( $4 )": "00f84c480000000000008cac", +"swc2 $12, 8( $4 );swc2 $13, 16( $4 );swc2 $14, 24( $4 )": "08008ce810008de818008ee8", +"swc2 $12, 8( $4 );swc2 $13, 16( $4 );swc2 $14, 24( $4 )": "08008ce810008de818008ee8", +"nop;nop;ncct": "00000000000000003f04184b", +"swc2 $17, 0( $4 );swc2 $18, 0( $5 );swc2 $19, 0( $6 )": "000091e80000b2e80000d3e8", +"swc2 $20, 4( $4 );swc2 $21, 12( $4 );swc2 $22, 20( $4 )": "040094e80c0095e8140096e8", +"lwc2 $0, 0($4);lwc2 $1, 4($4)": "000080c8040081c8", +"lwc2 $0, 0($4);lwc2 $1, 4($4);lwc2 $2, 0($5);lwc2 $3, 4($5);lwc2 $4, 0($6);lwc2 $5, 4($6)": "000080c8040081c80000a2c80400a3c80000c4c80400c5c8", +"lwc2 $6, 0($4)": "000086c8", +"nop;nop;cop2 0x0280030": "00000000000000003000284a", +"nop;nop;cop2 0x0180001": "00000000000000000100184a", +"nop;nop;cop2 0x1400006": "00000000000000000600404b", +"nop;nop;cop2 0x168002e": "00000000000000002e00684b", +"nop;nop;cop2 0x118043f": "00000000000000003f04184b", +"nop;nop;cop2 0x108041b": "00000000000000001b04084b", +"cfc2 $12, $31;nop;sw $12, 0($4)": "00f84c480000000000008cac", +"swc2 $24, 0($4)": "000098e8", +"swc2 $7, 0($4)": "000087e8", +"swc2 $14, 0($4)": "00008ee8", +"swc2 $22, 0($4)": "000096e8", +"swc2 $12, 8($4);swc2 $13, 16($4);swc2 $14, 24($4)": "08008ce810008de818008ee8", +"swc2 $20, 4($4);swc2 $21, 12($4);swc2 $22, 20($4)": "040094e80c0095e8140096e8", +"swc2 $16, 0($4);swc2 $17, 0($5);swc2 $18, 0($6);swc2 $19, 0($7)": "000090e80000b1e80000d2e80000f3e8", +"nop;nop;.word 0x4A280030": "00000000000000003000284a", +"nop;nop;.word 0x4B400006": "00000000000000000600404b", +"nop;nop;.word 0x4B58002D": "00000000000000002d00584b", +"nop;nop;.word 0x4B08041B": "00000000000000001b04084b", +"swc2 $16, 0( $4 );swc2 $17, 0( $5 );swc2 $18, 0( $6 );swc2 $19, 0( $7 )": "000090e80000b1e80000d2e80000f3e8", +"swc2 $20, 0( $4 );swc2 $21, 0( $5 );swc2 $22, 0( $6 )": "000094e80000b5e80000d6e8", +"swc2 $12, 8( $4 );swc2 $13, 20( $4 );swc2 $14, 32( $4 )": "08008ce814008de820008ee8", +"nop;nop;.word 0x4a180001": "00000000000000000100184a", +"nop;nop;.word 0x4a280030": "00000000000000003000284a", +"nop;nop;.word 0x4b400006": "00000000000000000600404b", +"nop;nop;.word 0x4b68002e": "00000000000000002e00684b", +"mfc2 $12, $9\nmfc2 $13, $10\nmfc2 $14, $11\nsh $12, 0($4)\nsh $13, 2($4)\nsh $14, 4($4)\n": "00480c4800500d4800580e4800008ca402008da404008ea4", +"lw $12, 0($4)\nlw $13, 4($4)\nctc2 $12, $0\nctc2 $13, $1\nlw $12, 8($4)\nlw $13, 12($4)\nlw $14, 16($4)\nctc2 $12, $2\nctc2 $13, $3\nctc2 $14, $4\n": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce48", +"nop\nnop\nmvmva 1, 0, 0, 3, 0\n": "00000000000000001260484a", +"lwc2 $0, 0($4)\nlwc2 $1, 4($4)": "000080c8040081c8", +"nop\nnop\nrtps": "00000000000000000100184a", +"lw $12, 20($4)\nlw $13, 24($4)\nctc2 $12, $5\nlw $14, 28($4)\nctc2 $13, $6\nctc2 $14, $7\n": "14008c8c18008d8c0028cc481c008e8c0030cd480038ce48", +"lhu $12, 0($4)\nlhu $13, 6($4)\nlhu $14, 12($4)\nmtc2 $12, $9\nmtc2 $13, $10\nmtc2 $14, $11\nnop\nnop\nmvmva 1, 0, 3, 3, 0\nmfc2 $12, $9\nmfc2 $13, $10\nmfc2 $14, $11\nsh $12, 0($4)\nsh $13, 6($4)\nsh $14, 12($4)\n": "00008c9406008d940c008e9400488c4800508d4800588e48000000000000000012e0494a00480c4800500d4800580e4800008ca406008da40c008ea4", +"lhu $13, 4($4)\nlhu $12, 0($4)\nsll $13, $13, 16\nor $12, $12, $13\nmtc2 $12, $0\nlwc2 $1, 8($4)\nnop\nnop\nmvmva 1, 0, 0, 0, 0\nswc2 $25, 0($4)\nswc2 $26, 4($4)\nswc2 $27, 8($4)\n": "04008d9400008c94006c0d0025608d0100008c48080081c800000000000000001200484a000099e804009ae808009be8", +"lwc2 $0, 0($4)\nlwc2 $1, 4($4)\nlwc2 $2, 0($5)\nlwc2 $3, 4($5)\nlwc2 $4, 0($6)\nlwc2 $5, 4($6)\n": "000080c8040081c80000a2c80400a3c80000c4c80400c5c8", +"nop\nnop\nrtpt": "00000000000000003000284a", +"nop\nnop\navsz4": "00000000000000002e00684b", +"swc2 $12, 0($4)\nswc2 $13, 0($5)\nswc2 $14, 0($6)": "00008ce80000ade80000cee8", +"cfc2 $12, $31\nnop\nsw $12, 0($4)": "00f84c480000000000008cac", +"mtc2 $0, $8": "00408048", +"lwc2 $28, 0($4)": "00009cc8", +"nop\n\nnop\n\ndpcl": "00000000000000002900684a", +"swc2 $29, 0($4)": "00009de8", +"lwc2 $0, 0( $4 );lwc2 $1, 4( $4 );lwc2 $2, 8( $4 );lwc2 $3, 12( $4 );lwc2 $4, 16( $4 );lwc2 $5, 20( $4 )": "000080c8040081c8080082c80c0083c8100084c8140085c8", +"swc2 $12, 0( $4 );swc2 $13, 4( $4 );swc2 $14, 8( $4 )": "00008ce804008de808008ee8", +"swc2 $12, 0( $4 );swc2 $13, 0( $5 )": "00008ce80000ade8", +"nop;nop;.word 0x4A480012": "00000000000000001200484a", +"lw $12, 0( $4 );lw $13, 4( $4 );ctc2 $12, $0;ctc2 $13, $1;lw $12, 8( $4 );lw $13, 12( $4 );lw $14, 16( $4 );ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;lw $12, 20( $4 );lw $13, 24( $4 );ctc2 $12, $5;lw $14, 28( $4 );ctc2 $13, $6;ctc2 $14, $7": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce4814008c8c18008d8c0028cc481c008e8c0030cd480038ce48", +"lhu $12, 0( $4 );lhu $13, 6( $4 );lhu $14, 12( $4 );mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0( $4 );sh $13, 6( $4 );sh $14, 12( $4 )": "00008c9406008d940c008e9400488c4800508d4800588e48000000000000000012e0494a00480c4800500d4800580e4800008ca406008da40c008ea4", +"lhu $13, 4( $4 );lhu $12, 0( $4 );sll $13, $13, 16;or $12, $12, $13;mtc2 $12, $0;lwc2 $1, 8( $4 );nop;nop;mvmva 1, 0, 0, 0, 0;swc2 $25, 0( $4 );swc2 $26, 4( $4 );swc2 $27, 8( $4 )": "04008d9400008c94006c0d0025608d0100008c48080081c800000000000000001200484a000099e804009ae808009be8", +"lw $12, 0($4);lw $13, 4($4);ctc2 $12, $0;ctc2 $13, $1;lw $12, 8($4);lw $13, 12($4);lw $14, 16($4);ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;addiu $2, $sp, 16;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($4);sh $13, 6($4);sh $14, 12($4);addiu $2, $sp, 18;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $4, 2;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2);addiu $2, $sp, 20;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $4, 4;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2)": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce481000a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a00480c4800500d4800580e4800008ca406008da40c008ea41200a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a0200822400480c4800500d4800580e4800004ca406004da40c004ea41400a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a0400822400480c4800500d4800580e4800004ca406004da40c004ea4", +"lwc2 $9, 0($4)\n\nlwc2 $10, 4($4)\n\nlwc2 $11, 8($4)": "000089c804008ac808008bc8", +"nop\n\nnop\n\nsqr 0": "00000000000000002804a04a", +"swc2 $25, 0($4)\n\nswc2 $26, 4($4)\n\nswc2 $27, 8($4)": "000099e804009ae808009be8", +"lw $12, 0($4);lw $13, 4($4);ctc2 $12, $0;ctc2 $13, $1;lw $12, 8($4);lw $13, 12($4);lw $14, 16($4);ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;lhu $12, 0($5);lhu $13, 6($5);lhu $14, 12($5);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($4);sh $13, 6($4);sh $14, 12($4);addiu $2, $sp, 50;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $sp, 18;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2);addiu $2, $sp, 52;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $sp, 20;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2)": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce480000ac940600ad940c00ae9400488c4800508d4800588e48000000000000000012e0494a00480c4800500d4800580e4800008ca406008da40c008ea43200a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a1200a22700480c4800500d4800580e4800004ca406004da40c004ea43400a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a1400a22700480c4800500d4800580e4800004ca406004da40c004ea4", +"lw $12, 0($5);lw $13, 4($5);ctc2 $12, $0;ctc2 $13, $1;lw $12, 8($5);lw $13, 12($5);lw $14, 16($5);ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;lhu $12, 0($4);lhu $13, 6($4);lhu $14, 12($4);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($5);sh $13, 6($5);sh $14, 12($5);addiu $2, $sp, 50;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $sp, 18;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2);addiu $2, $sp, 52;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $sp, 20;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2)": "0000ac8c0400ad8c0000cc480008cd480800ac8c0c00ad8c1000ae8c0010cc480018cd480020ce4800008c9406008d940c008e9400488c4800508d4800588e48000000000000000012e0494a00480c4800500d4800580e480000aca40600ada40c00aea43200a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a1200a22700480c4800500d4800580e4800004ca406004da40c004ea43400a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a1400a22700480c4800500d4800580e4800004ca406004da40c004ea4", +"lw $12, 0($4);lw $13, 4($4);ctc2 $12, $0;ctc2 $13, $1;lw $12, 8($4);lw $13, 12($4);lw $14, 16($4);ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce48", +"lhu $12, 0($4);lhu $13, 6($4);lhu $14, 12($4);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;": "00008c9406008d940c008e9400488c4800508d4800588e48", +"mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($4);sh $13, 6($4);sh $14, 12($4);": "00480c4800500d4800580e4800008ca406008da40c008ea4", +".set\nnoreorder\nlw $12, 0($4)\nlw $13, 4($4)\nctc2 $12, $0\nctc2 $13, $1\nlw $12, 8($4)\nlw $13, 12($4)\nlw $14, 16($4)\nctc2 $12, $2\nctc2 $13, $3\nctc2 $14, $4\nlwc2 $0, 0($5)\nlwc2 $1, 4($5)\nnop\nnop\nmvmva 1, 0, 0, 3, 0\nswc2 $25, 0($6)\nswc2 $26, 4($6)\nswc2 $27, 8($6)\n.set\nreorder\n": "ERROR: {standard input}:36: Error: unrecognized opcode `reorder'", +"swc2 $8, 0( $4 )": "000088e8", +"lw $12, 0($4);lw $13, 4($4);ctc2 $12, $0;ctc2 $13, $1;lw $12, 8($4);lw $13, 12($4);lw $14, 16($4);ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;addiu $2, $sp, 0x30;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($4);sh $13, 6($4);sh $14, 12($4);addiu $2, $sp, 0x32;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $sp, 0x12;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2);addiu $2, $sp, 0x34;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $sp, 0x14;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2);": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce483000a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a00480c4800500d4800580e4800008ca406008da40c008ea43200a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a1200a22700480c4800500d4800580e4800004ca406004da40c004ea43400a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a1400a22700480c4800500d4800580e4800004ca406004da40c004ea4", +"lw $12, 0($4);lw $13, 4($4);ctc2 $12, $0;ctc2 $13, $1;lw $12, 8($4);lw $13, 12($4);lw $14, 16($4);ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;lw $12, 20($4);lw $13, 24($4);ctc2 $12, $5;lw $14, 28($4);ctc2 $13, $6;ctc2 $14, $7": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce4814008c8c18008d8c0028cc481c008e8c0030cd480038ce48", +"lhu $12, 0($4)\nlhu $13, 6($4)\nlhu $14, 12($4)\nmtc2 $12, $9\nmtc2 $13, $10\nmtc2 $14, $11\nnop\nnop\nmvmva 1, 0, 3, 3, 0\n": "00008c9406008d940c008e9400488c4800508d4800588e48000000000000000012e0494a", +"mfc2 $12, $9\nmfc2 $13, $10\nmfc2 $14, $11\nsh $12, 0($4)\nsh $13, 6($4)\nsh $14, 12($4)\n": "00480c4800500d4800580e4800008ca406008da40c008ea4", +"lhu $13, 4($4)\nlhu $12, 0($4)\nsll $13, $13, 16\nor $12, $12, $13\nmtc2 $12, $0\nlwc2 $1, 8($4)\nnop\nnop\nmvmva 1, 0, 0, 0, 0\n": "04008d9400008c94006c0d0025608d0100008c48080081c800000000000000001200484a", +"swc2 $8, 0($4)": "000088e8", +"mfc2 $12, $19;nop;sra $12, $12, 2;sw $12, 0($4)": "00980c480000000083600c0000008cac", +"lhu $12, 0( $4 );lhu $13, 6( $4 );lhu $14, 12( $4 );mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0": "00008c9406008d940c008e9400488c4800508d4800588e48000000000000000012e0494a", +"lwc2 $9, 0($4)\nlwc2 $10, 4($4)\nlwc2 $11, 8($4)\nnop\nnop\nsqr 0\n": "000089c804008ac808008bc800000000000000002804a04a", +"lwc2 $0, 0($4)\nlwc2 $1, 4($4)\nnop\nnop\nmvmva 1, 0, 0, 0, 0\n": "000080c8040081c800000000000000001200484a", +"lwc2 $0, 0($4)\nlwc2 $1, 4($4)\nnop\nnop\nmvmva 1, 0, 0, 3, 0\n": "000080c8040081c800000000000000001260484a", +"lw $12, 0($4)\nlw $13, 4($4)\nctc2 $12, $0\nctc2 $13, $1\nlw $12, 8($4)\nlw $13, 12($4)\nlw $14, 16($4)\nctc2 $12, $2\nctc2 $13, $3\nctc2 $14, $4\nlw $12, 20($4)\nlw $13, 24($4)\nctc2 $12, $5\nlw $14, 28($4)\nctc2 $13, $6\nctc2 $14, $7\n": "00008c8c04008d8c0000cc480008cd4808008c8c0c008d8c10008e8c0010cc480018cd480020ce4814008c8c18008d8c0028cc481c008e8c0030cd480038ce48", +"lwc2 $0, 0($4)\n\nlwc2 $1, 4($4)": "000080c8040081c8", +"nop\n\nnop\n\nrtps": "00000000000000000100184a", +"cfc2 $12, $31\n\nnop\n\nsw $12, 0($4)": "00f84c480000000000008cac", +"lw $12, 0($2);lw $13, 4($2);ctc2 $12, $0;ctc2 $13, $1;lw $12, 8($2);lw $13, 12($2);lw $14, 16($2);ctc2 $12, $2;ctc2 $13, $3;ctc2 $14, $4;addiu $2, $sp, 0x10;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2);addiu $2, $sp, 0x12;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $2, 0x2;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2);addiu $2, $sp, 0x14;lhu $12, 0($2);lhu $13, 6($2);lhu $14, 12($2);mtc2 $12, $9;mtc2 $13, $10;mtc2 $14, $11;nop;nop;mvmva 1, 0, 3, 3, 0;addiu $2, $2, 4;mfc2 $12, $9;mfc2 $13, $10;mfc2 $14, $11;sh $12, 0($2);sh $13, 6($2);sh $14, 12($2)": "00004c8c04004d8c0000cc480008cd4808004c8c0c004d8c10004e8c0010cc480018cd480020ce481000a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a00480c4800500d4800580e4800004ca406004da40c004ea41200a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a0200422400480c4800500d4800580e4800004ca406004da40c004ea41400a22700004c9406004d940c004e9400488c4800508d4800588e48000000000000000012e0494a0400422400480c4800500d4800580e4800004ca406004da40c004ea4", +"lui $2,%%hi(D_800AF648);addiu $2,$2,%%lo(D_800AF648);lw $12,0($2);lw $13,4($2);ctc2 $12,$0;ctc2 $13,$1;lw $12,8($2);lw $13,12($2);lw $14,16($2);ctc2 $12,$2;ctc2 $13,$3;ctc2 $14,$4;lw $12,20($2);lw $13,24($2);ctc2 $12,$5;lw $14,28($2);ctc2 $13,$6;ctc2 $14,$7": "ERROR: {standard input}:10: Error: operand 3 must be constant `addiu $2,$2,%%lo(D_800AF648)'", +"lwc2 $0,0($4);lwc2 $1,4($4);nop;nop;rtps;swc2 $14,0($4)": "000080c8040081c800000000000000000100184a00008ee8", +"cfc2 $12,$31;nop;sw $12,0($4)": "00f84c480000000000008cac", +"lwc2 $9, 0($sp)\nlwc2 $10, 4($sp)\nlwc2 $11, 8($sp)\nnop\nnop\nsqr 0\n": "0000a9cb0400aacb0800abcb00000000000000002804a04a", +"swc2 $25, 0($sp)\nswc2 $26, 4($sp)\nswc2 $27, 8($sp)\n": "0000b9eb0400baeb0800bbeb", +"lw $2, 0(%3);lw $3, 4(%3);ctc2 $2, $0;ctc2 $3, $1;lw $2, 8(%3);lw $3, 12(%3);lw $4, 16(%3);ctc2 $2, $2;ctc2 $3, $3;ctc2 $4, $4;lw $2, 20(%3);lw $3, 24(%3);ctc2 $2, $5;lw $4, 28(%3);ctc2 $3, $6;ctc2 $4, $7": "ERROR: {standard input}:10: Error: invalid operands `lw $4,28(%3)'", +"lwc2 $0, 0($4);lwc2 $1, 4($4);nop;nop;rtps": "000080c8040081c800000000000000000100184a", +"cfc2 $2, $31; nop; sw $2, 0($4)": "00f8424800000000000082ac", +"lwc2 $9, 0( $4 );lwc2 $10, 4( $4 );lwc2 $11, 8( $4 );nop;nop;sqr 0;swc2 $25, 0( $4 );swc2 $26, 4( $4 );swc2 $27, 8( $4 )": "000089c804008ac808008bc800000000000000002804a04a000099e804009ae808009be8", +"nop\nnop\nmvmva 1, 0, 0, 3, 0": "00000000000000001260484a", +"mfc2 $12, $9\nmfc2 $13, $10\nmfc2 $14, $11\nsh $12, 0($4)\nsh $13, 2($4)\nsh $14, 4($4)": "00480c4800500d4800580e4800008ca402008da404008ea4", +"swc2 $19, 0($4)": "000093e8", +"mfc2 $12, $19\nnop\nsra $12, $12, 2\nsw $12, 0($4)\n": "00980c480000000083600c0000008cac", +"lwc2 $9, 0($4)\nlwc2 $10, 4($4)\nlwc2 $11, 8($4)\nnop\nnop\nsqr 1\n": "000089c804008ac808008bc800000000000000002804a84a" +} \ No newline at end of file diff --git a/config/tool_dictionary.tsv b/config/tool_dictionary.tsv index 75b46af53..eca16e3d1 100644 --- a/config/tool_dictionary.tsv +++ b/config/tool_dictionary.tsv @@ -71,6 +71,7 @@ tools/dedup_integrate.py P6 ADAPT validate a code-share registry byte-honestly, tools/dedup_propagate.py P6 ADAPT lift one matched body into a shared macro and instantiate it everywhere Lifts one matched body into a shared macro and instantiates it at every duplicate site repo shared-header/src layout SUPERSEDED tools/share_body.py tools/delever.py P10 ADAPT take register pins, asm statements, volatile and register levers out of matched C, byte-gated per site The Phase-36 de-lever engine and campaign tool: positional rewrites per lever class (pin -> plain declaration, barrier/keep-alive deleted, a launder deleted or turned into the assignment it is, a hand-placed instruction -> its C, the zero-register variable -> 0, a macro-carried site deleted/valued/refused by its macro's shape, volatile/register dropped); per body replay -> rung A strip-all -> rung B greedy through delever_oracle; the file is the write unit and its final compile through every recipe the proof; --plan/--apply batches (TUs parallel, exemplar files first; headers serial, includers parallel), the ledger keyed by tu+fn+addr with the body's nhash before/after, !FAKE markers on class A/B survivors, --redraw for bodies refused by an older tool, --restore from inflight.json, --scrub for orphan markers, --apply-body for T6/T7, --selftest with a stub oracle, --probe (T2) the census site records, the oracle LIVE tools/delever_oracle.py P10 ADAPT judge one translation-unit edit by the bytes of its object in under a second The Phase-36 fast byte oracle: every object's exact build command captured once via make -n -W (the Makefile's own recipe, pad stage and -O0 overrides included), a candidate compiled in place with -o/-MF redirected to scratch and compared with the fleet run's object; --calibrate proves 100 % equality untouched, twin == primary and a positive control before any verdict is trusted the Makefile's object rules, the twin rule LIVE +tools/gte_consolidate.py P10 ADAPT consolidate the GTE coprocessor inline-asm macros under Sony's names in one header and sweep dead lever macros The Phase-36 T5 tool: every asm-bearing macro definition and direct GTE statement SIGNED by the build's own maspsx→as tail (template bytes with operands bound to fixed registers, operand counts, clobbers); one canonical text per signature named by PsyQ's inline_c.h convention (Sony's file supplies names and clobber lists, never opcode words) written to include/gte_inline.h; per file the canonical duplicates deleted, private names renamed, a variant with extra clobbers tried as canonical and kept as a marked _m lever only when the object differs, direct statements rewritten into canonical calls (a concatenation of two included); every file judged through every recipe; --sweep deletes dead asm-bearing macros and drops a compound macro's inner asm when byte-neutral Sony's inline_c.h path, the census sites, the oracle LIVE tools/demacroize.py P6 ADAPT escape a shared-header declaration conflict locally by unmacroizing one body Per-binary local escape from a shared-header declaration conflict by unmacroizing one body repo shared-header layout FROZEN tools/share_body.py tools/diff_autopsy.sh P7 ADAPT find which words diverge when the whole-binary gate says different but not where Reproduces exactly what the gate saw, then decodes the diverging words and restores the tree repo src/build paths STILL-NEEDED find WHICH words diverge when the whole-binary gate says DIFF but not where tools/diff_regions.py P7 ADAPT classify where a remapped sibling's compiled bytes diverge from its target Classifies where a remapped member's compiled bytes diverge from its target repo build paths STILL-NEEDED classify where a mechanically remapped sibling's compiled bytes diverge from its target diff --git a/decomp-architect/corpus/tools/INDEX.md b/decomp-architect/corpus/tools/INDEX.md index ef1fac449..62f9abc49 100644 --- a/decomp-architect/corpus/tools/INDEX.md +++ b/decomp-architect/corpus/tools/INDEX.md @@ -8,8 +8,8 @@ > its platform SDK need the marked adaptation. The last table lists the tools that are project-only in code (their *shape* is a task; > their code does not transfer). *TODO(platform): the MIPS and PlayStation SDK hard-codes are the ones another platform replaces first.* > -> **Coverage:** 299 tool files in scope (submodules, vendored and downloaded code excluded), of which 299 live rows -> below; per phase: P1 2 · P2 26 · P3 17 · P4 9 · P5 26 · P6 51 · P7 20 · P8 86 · P9 27 · P10 19 · PROJECT-ONLY 16. Superseded tools appear only as pointers to their successor (30 pointer rows); one-offs are omitted. Table rows in all: 329 (the installer checks its copy against this figure). +> **Coverage:** 300 tool files in scope (submodules, vendored and downloaded code excluded), of which 300 live rows +> below; per phase: P1 2 · P2 26 · P3 17 · P4 9 · P5 26 · P6 51 · P7 20 · P8 86 · P9 27 · P10 20 · PROJECT-ONLY 16. Superseded tools appear only as pointers to their successor (30 pointer rows); one-offs are omitted. Table rows in all: 330 (the installer checks its copy against this figure). ## P1 — extraction + manifest @@ -327,6 +327,7 @@ | `cast_call_sites.py` | add per-site function-pointer casts so a draft can call a differently typed callee | Adds per-site function-pointer casts so a draft can call a differently typed callee | repo src layout | | `ghidra_scripts/ApplySymbols.java` | apply curated names and signatures inside the analysis tool and save | The in-tool half of that mirror: apply curated names and signatures, save on exit | none | | `lever_census.py` | census every compiler-forcing construct in the C and gate the levers-off phase | The Phase-36 census of lever sites (register pins, asm statements by kind, volatile levers, bare register, asm-label aliases, builtins, attributes; the whole-body hand-asm routines and the GTE ops set apart) derived from the shared-body scanner with a per-token coverage assertion against the raw text, four known-true controls, the !FAKE marker split, --check (0 unmarked pins/asm, 0 orphan markers) and --strict (0 pins, 0 asm) gates, --sites for the delever ledger, a fixture self-test | repo paths, the shared-body scanner | +| `gte_consolidate.py` | consolidate the GTE coprocessor inline-asm macros under Sony's names in one header and sweep dead lever macros | The Phase-36 T5 tool: every asm-bearing macro definition and direct GTE statement SIGNED by the build's own maspsx→as tail (template bytes with operands bound to fixed registers, operand counts, clobbers); one canonical text per signature named by PsyQ's inline_c.h convention (Sony's file supplies names and clobber lists, never opcode words) written to include/gte_inline.h; per file the canonical duplicates deleted, private names renamed, a variant with extra clobbers tried as canonical and kept as a marked _m lever only when the object differs, direct statements rewritten into canonical calls (a concatenation of two included); every file judged through every recipe; --sweep deletes dead asm-bearing macros and drops a compound macro's inner asm when byte-neutral | Sony's inline_c.h path, the census sites, the oracle | | `macro_to_header.py` | convert a shared-body macro header into per-function plain-C headers included at each site | The Phase-35 converter: every DEFINE_ macro body becomes a plain-C header under src/shared// included at its site, the legacy name-parameterized headers converted, the registry text-edited, the macro header deleted; --plan / --apply / --finalize / --verify | the macro form is this project's; a kit-born project shares headers from its first bank | | `asm_verbatim.py` | emit a function's target assembly as an inline-assembly body | Emits the file-scope inline-assembly body form from a disassembly file | repo asm layout | | `build_engine_types.py` | extract inline-defined types and typedefs from a source file into a shared header | Extracts inline-defined named types and typedefs from a source file into a shared header | repo shared-header path | diff --git a/decomp-architect/corpus/tools/P10/delever_cycle.sh b/decomp-architect/corpus/tools/P10/delever_cycle.sh index 4bf60793f..5b1c4170b 100644 --- a/decomp-architect/corpus/tools/P10/delever_cycle.sh +++ b/decomp-architect/corpus/tools/P10/delever_cycle.sh @@ -9,7 +9,7 @@ # and src/ + the ledger/batch record/log + the census + the phase log are committed (R42). # Stops on the first red (a non-zero tool exit, a final N/M with N != M, a fleet run that is not 218/218) — the batch's files are then # still in place: inspect, then `tools/delever.py --restore` (never git checkout, R102). Stops cleanly when nothing is drawable. -# Usage: [LABEL_PREFIX=t3_] [TASK=T4] [REDRAW="REFUSED NOTHING-USABLE"] tools/delever_cycle.sh START END [BATCH=300] [MODE=tus|headers] [ONLY="alias1 alias2 …"] +# Usage: [LABEL_PREFIX=t3_] [TASK=T4] [REDRAW="REFUSED NOTHING-USABLE"] tools/delever_cycle.sh START END [BATCH=300] [MODE=tus|headers|gte] [ONLY="alias1 alias2 …"] # RUN IT DETACHED from the Claude Code harness (its low-memory guard kills a long BACKGROUND task — batch tus3 died mid-apply, S98): # setsid nohup bash -c 'TASK=T4 tools/delever_cycle.sh 3 12 300 tus; echo "cycle exit=$?"' > .run/P36/delever/cycle_.log 2>&1 & # and watch the log (a tiny waiter: `until grep -q 'cycle exit=' ; do sleep 60; done`). A killed batch: `tools/delever.py --restore`. @@ -20,7 +20,12 @@ set -o pipefail cd "$(dirname "$0")/.." || exit 2 START=$1; END=$2; BATCH=${3:-300}; MODE=${4:-tus}; ONLY=${5:-} [ -n "$START" ] && [ -n "$END" ] || { echo "usage: $0 START END [BATCH] [tus|headers] [ONLY]"; exit 2; } -case "$MODE" in tus) HFLAG="";; headers) HFLAG="--headers";; *) echo "MODE must be tus or headers"; exit 2;; esac +case "$MODE" in + tus) HFLAG=""; TOOL="tools/delever.py --apply"; VPAT='delever: batch .*';; + headers) HFLAG="--headers"; TOOL="tools/delever.py --apply"; VPAT='delever: batch .*';; + gte) HFLAG=""; TOOL="tools/gte_consolidate.py --apply"; VPAT='gte_consolidate: batch .*';; # T5: the GTE consolidation per file + *) echo "MODE must be tus, headers or gte"; exit 2;; +esac ONLYFLAG=""; [ -n "$ONLY" ] && ONLYFLAG="--only $ONLY" REDRAWFLAG=""; [ -n "${REDRAW:-}" ] && REDRAWFLAG="--redraw $REDRAW" # e.g. REDRAW="REFUSED NOTHING-USABLE" after a tool fix FLEET=$(ls config/check.*.sha | wc -l) @@ -41,11 +46,11 @@ for k in $(seq "$START" "$END"); do [ -z "$(git status --short --porcelain src | grep '^??')" ] || { echo "cycle: untracked files under src/ (a dotfile probe?) — sweep them first"; exit 3; } $PY tools/delever_oracle.py --status >/dev/null 2>&1 || $PY tools/delever_oracle.py --calibrate ov_SC04_011 ov_SC03_015 ov_SC03_014 main -j 16 > .run/P36/delever/calibrate_${label}.log 2>&1 \ || { echo "cycle: calibration FAILED"; tail -5 .run/P36/delever/calibrate_${label}.log; exit 1; } - { /usr/bin/time -f "$label wall=%e s" $PY tools/delever.py --apply --batch "$BATCH" --label "$label" $HFLAG $ONLYFLAG $REDRAWFLAG -j 12; echo "exit=$?"; } > "$log" 2>&1 + { /usr/bin/time -f "$label wall=%e s" $PY $TOOL --batch "$BATCH" --label "$label" $HFLAG $ONLYFLAG $REDRAWFLAG -j 12; echo "exit=$?"; } > "$log" 2>&1 fi grep -q '^exit=0$' "$log" || { echo "cycle: batch $label — delever exited non-zero"; tail -4 "$log"; exit 1; } - if grep -q 'nothing to do (no drawable file)' "$log"; then echo "cycle: nothing drawable at $label — done"; exit 0; fi - vline=$(grep -oE 'delever: batch .*' "$log" | tail -1) + if grep -qE 'nothing to do' "$log"; then echo "cycle: nothing drawable at $label — done"; exit 0; fi + vline=$(grep -oE "$VPAT" "$log" | tail -1) [ -n "$vline" ] || { echo "cycle: batch $label — no verify line in $log (R32: an empty line is not a pass)"; tail -3 "$log"; exit 1; } final=$(echo "$vline" | grep -oE 'final [0-9]+/[0-9]+' | grep -oE '[0-9]+/[0-9]+') [ -n "$final" ] && [ "${final%/*}" = "${final#*/}" ] || { echo "cycle: batch $label — $vline"; exit 1; } diff --git a/decomp-architect/corpus/tools/P10/gte_consolidate.py b/decomp-architect/corpus/tools/P10/gte_consolidate.py new file mode 100644 index 000000000..76037970c --- /dev/null +++ b/decomp-architect/corpus/tools/P10/gte_consolidate.py @@ -0,0 +1,922 @@ +#!/usr/bin/env python3 +"""gte_consolidate.py — the GTE coprocessor asm consolidated under Sony's names, and the dead lever-macro sweep (Phase 36 T5). + + tools/gte_consolidate.py --inventory # every asm-bearing macro definition + every direct GTE statement, SIGNED by the + # build's own maspsx→as tail; the canonical table → .run/P36/gte/{inventory,canonical}.json + tools/gte_consolidate.py --header # write include/gte_inline.h (one canonical macro per signature) + the include in common.h + tools/gte_consolidate.py --apply --batch N --label L [--only …] [-j 12] + # per file: canonical-duplicate definitions deleted, private/variant names renamed, direct + # statements rewritten into canonical calls; every file judged through every recipe + tools/gte_consolidate.py --sweep --label L [--only …] # dead asm-bearing macros deleted; a compound macro's inner asm dropped when byte-neutral + tools/gte_consolidate.py --status | --selftest + +A SIGNATURE is what the assembler makes of a template, not how it is spelled: the template with its operands bound to fixed registers +(%0.. → $4 $5 $6 $7 for inputs, $2 $3 for outputs) is assembled through the SAME tail as the build (maspsx --aspsx-version=2.56 → +mipsel-linux-gnu-as with include/macro.inc + include/gte_macros.inc, where `rtps`, `mvmva`, `sqr 0` are GAS macros), and the signature +is (bytes, #outputs, #inputs). `nop;nop;rtps`, `nop;nop;.word 0x4a180001` and `nop;nop;cop2 0x0180001` are one signature. Sony's +converted inline_c.h is the source of NAMES and of operand/clobber lists only — its `.word` opcode spellings assemble to nothing +useful (`gte_rtps` there is `.word 0x0000007f`). + +THE CANONICAL TABLE: definitions grouped by signature; the canonical CLOBBER set of a signature is Sony's for that name (a store macro +legitimately clobbers "memory"), else the majority's; the canonical NAME is the most-used `gte_*` name in the group (Sony's convention), +else a name derived from gte_macros.inc, else `gte_seq_`; the canonical TEXT is the majority definition text (byte-proven in the +fleet — the header ships nothing that was not already in the tree). A definition with the canonical signature but EXTRA clobbers (the +`"memory"` a drafter added to a load or a compute op to force the schedule) is a LEVER VARIANT: it stays per TU, renamed `_m`, and +its uses carry `// !FAKE:` markers for T7. A direct statement is rewritten into `NAME(args)` (or `NAME1(args); NAME2();` for the +concatenation of two canonical macros) when bytes and clobbers agree; with extra clobbers it is a lever variant too (marked); a sequence +that matches nothing is counted and left. Every file's final text is judged through every recipe of the file (tools/delever_oracle.py); +the clean fleet run gates every batch (tools/delever_cycle.sh MODE=gte). +""" +import argparse +import collections +import hashlib +import json +import os +import pathlib +import re +import subprocess +import sys +import time +from concurrent.futures import ThreadPoolExecutor + +REPO = pathlib.Path(__file__).resolve().parent.parent +sys.path.insert(0, str(REPO / "tools")) +import delever as dl # noqa: E402 +import delever_oracle as oracle # noqa: E402 +import lever_census as lc # noqa: E402 +import share_census as sc # noqa: E402 + +RUN = REPO / ".run" / "P36" / "gte" +SIG_CACHE = RUN / "sig_cache.json" +INVENTORY = RUN / "inventory.json" +CANON = RUN / "canonical.json" +LEDGER = REPO / ".run" / "P36" / "delever" / "ledger.jsonl" +HEADER = "include/gte_inline.h" +COMMON = "include/common.h" +SONY = REPO / "tools/psyq/conv47/psyq-4_7-converted/include/inline_c.h" +MASPSX = ".venv/bin/python tools/maspsx/maspsx.py --aspsx-version=2.56 --expand-div" +AS = "mipsel-linux-gnu-as -Iinclude -march=r3000 -mtune=r3000 -no-pad-sections -O1 -G0" +FAKE = dl.FAKE +DEFINE_LINE = re.compile(r"^[ \t]*#[ \t]*define[ \t]+([A-Za-z_]\w*)(\([^)]*\))?[ \t]*(.*)$") +_LOCK = dl._LOCK + + +class Refuse(Exception): + pass + + +# ---------------------------------------------------------------------------------------------------------------------- +# the signature engine +# ---------------------------------------------------------------------------------------------------------------------- +def parse_asm(inner): + """(template, outs, ins, clobbers) — delever's operand parser plus the clobber section.""" + tmpl, outs, ins = dl.parse_asm_operands(inner) + s = inner.strip() + i, n = 0, len(s) + while i < n: + if s[i] in " \t\r\n": + i += 1 + continue + mm = lc.STRLIT.match(s, i) + if not mm: + break + i = mm.end() + rest = s[i:].strip() + secs = lc._split_sections(rest[1:]) if rest.startswith(":") else [] + clob = [m.group(1) for m in re.finditer(r'"([^"]*)"', secs[2])] if len(secs) > 2 else [] + return tmpl, outs, ins, sorted(set(clob)) + + +def bind_regs(tmpl, nout, nin): + regs = ["$2", "$3"][:nout] + ["$4", "$5", "$6", "$7"][:nin] + def sub(m): + k = int(m.group(1)) + return regs[k] if k < len(regs) else m.group(0) + t = re.sub(r"%(\d+)", sub, tmpl) + t = re.sub(r"\\n|\\t", "\n", t) + return t + + +_sig_cache = None + + +def _load_cache(): + global _sig_cache + if _sig_cache is None: + _sig_cache = json.loads(SIG_CACHE.read_text()) if SIG_CACHE.exists() else {} + return _sig_cache + + +def _save_cache(): + RUN.mkdir(parents=True, exist_ok=True) + tmp = SIG_CACHE.with_suffix(".tmp") + tmp.write_text(json.dumps(_sig_cache, indent=0)) + os.replace(tmp, SIG_CACHE) + + +def asm_bytes(bound_template): + """hex of the .text bytes the build's tail makes of the template (cached by text); 'ERROR: …' when it does not assemble.""" + cache = _load_cache() + key = bound_template + if key in cache: + return cache[key] + d = RUN / "probe" + d.mkdir(parents=True, exist_ok=True) + tag = hashlib.sha1(key.encode()).hexdigest()[:10] + s_path, o_path, b_path = d / f"{tag}.s", d / f"{tag}.o", d / f"{tag}.bin" + s_path.write_text("\t.include \"include/macro.inc\"\n\t.include \"gte_macros.inc\"\n\t.set\tnoreorder\n\t.set\tnoat\n\t.text\n\t.align\t2\n" + "\t.globl\tprobe\n\t.ent\tprobe\nprobe:\n" + bound_template + "\n\t.end\tprobe\n") + cmd = f"set -o pipefail; cat {s_path} | {MASPSX} | {AS} -o {o_path} && mipsel-linux-gnu-objcopy -O binary -j .text {o_path} {b_path}" + r = subprocess.run(["bash", "-c", cmd], cwd=REPO, capture_output=True, text=True) + if r.returncode != 0 or not b_path.exists(): + res = "ERROR: " + (r.stderr.strip().splitlines() or ["?"])[-1][:120] + else: + res = b_path.read_bytes().hex() + for p in (s_path, o_path, b_path): + try: + p.unlink() + except OSError: + pass + cache[key] = res + return res + + +def signature(inner): + """dict(bytes, nout, nin, clob, tmpl, ok) for the text between an asm statement's parens.""" + tmpl, outs, ins, clob = parse_asm(inner) + bound = bind_regs(tmpl, len(outs), len(ins)) + b = asm_bytes(bound) + return dict(bytes=b, nout=len(outs), nin=len(ins), clob=clob, tmpl=tmpl, ok=not b.startswith("ERROR"), + ins=[e for _, e in ins], outs=[e for _, e in outs]) + + +def set_clobbers(body, clob): + """the macro body with the asm statement's clobber section replaced by `clob` (removed when empty).""" + m_asm = lc.ASM_KW.search(body) + o = body.find("(", m_asm.end()) + c = lc._paren_span(body, o) + inner = body[o + 1:c] + # the sections: template, then up to three ':'-separated parts outside string literals + s = inner + i, n = 0, len(s) + while i < n: + if s[i] in " \t\r\n": + i += 1 + continue + mm = lc.STRLIT.match(s, i) + if not mm: + break + i = mm.end() + head, rest = s[:i], s[i:] + secs = lc._split_sections(rest.strip()[1:]) if rest.strip().startswith(":") else [] + while len(secs) < 3: + secs.append("") + secs[2] = ", ".join(f'"{x}"' for x in clob) if clob else "" + while secs and secs[-1].strip() == "": + secs.pop() + new_inner = head.rstrip() + ("".join(" : " + x.strip() for x in secs) if secs else "") + " " + return body[:o + 1] + new_inner + body[c:] + + +def sig_key(s): + return f"{s['bytes']}|{s['nout']}|{s['nin']}" + + +# ---------------------------------------------------------------------------------------------------------------------- +# the inventory +# ---------------------------------------------------------------------------------------------------------------------- +def asm_inner(body_masked): + """the text between the parens of the FIRST asm statement in a macro body (None if none / more than one).""" + ms = list(lc.ASM_KW.finditer(body_masked)) + if len(ms) != 1: + return None + o = body_masked.find("(", ms[0].end()) + c = lc._paren_span(body_masked, o) if o >= 0 else -1 + return body_masked[o + 1:c] if (o >= 0 and c > 0) else None + + +def define_params(raw, l0): + m = DEFINE_LINE.match(raw.split("\n")[l0 - 1]) + return (m.group(2) or "") if m else "" + + +def sony_table(): + """name -> (nout, nin, clobbers) from Sony's inline_c.h — the parts of it that are plain C text.""" + out = {} + if not SONY.exists(): + return out + raw = SONY.read_text(errors="surrogateescape") + for (l0, l1, name, body) in lc.define_blocks(raw): + inner = asm_inner(sc.mask_text(body) if "/*" in body else body) + if inner is None: + continue + try: + _, outs, ins, clob = parse_asm(inner) + except Exception: # noqa: BLE001 + continue + out[name] = (len(outs), len(ins), clob) + return out + + +def inc_names(): + """bytes -> name for gte_macros.inc's single-op macros (assembled as `nop;nop;`), for signatures without a gte_* name.""" + raw = (REPO / "include/gte_macros.inc").read_text(errors="surrogateescape") + out = {} + for m in re.finditer(r"^\.macro\s+(\w+)\s*$", raw, re.M): + b = asm_bytes(f"nop\nnop\n{m.group(1)}") + if not b.startswith("ERROR"): + out[f"{b}|0|0"] = m.group(1) + return out + + +def files_under_src(): + return [p for p in sorted((REPO / "src").rglob("*")) if p.suffix in (".c", ".h") and not p.name.startswith(".")] + + +def inventory(jobs=12, quiet=False): + """definitions: [{tu, l0, l1, name, params, body, kind, sig}], direct: [{tu, line, col, inner, sig}], uses: Counter(name).""" + sites = dl.load_sites() + uses = collections.Counter(s["via"] for s in sites if s.get("via") and s["kind"] == "gte") + direct_sites = [s for s in sites if s["kind"] == "gte" and not s.get("via")] + defs, direct = [], [] + for p in files_under_src(): + raw = p.read_text(errors="surrogateescape") + if "#define" not in raw and "asm" not in raw: + continue + rel = p.relative_to(REPO).as_posix() + for (l0, l1, name, body) in lc.define_blocks(raw): + kind = lc.macro_kind(body) + if not kind: + continue + d = dict(tu=rel, l0=l0, l1=l1, name=name, params=define_params(raw, l0), body=body, kind=kind, sig=None) + if kind == "gte": + inner = asm_inner(sc.mask_text(body) if ("/*" in body or "//" in body) else body) + if inner is not None: + try: + d["sig"] = signature(inner) + except Exception as ex: # noqa: BLE001 + d["sig"] = dict(bytes=f"ERROR: {ex}"[:100], ok=False, nout=0, nin=0, clob=[], tmpl="", ins=[], outs=[]) + defs.append(d) + by_tu = collections.defaultdict(list) + for s in direct_sites: + by_tu[s["tu"]].append(s) + for tu, ss in by_tu.items(): + raw = (REPO / tu).read_text(errors="surrogateescape") + m = dl.same_len_mask(raw) + ls = dl.line_starts(raw) + for s in ss: + pos = ls[s["line"] - 1] + s["col"] - 1 + o = m.find("(", pos) + c = lc._paren_span(m, o) if o >= 0 else -1 + if o < 0 or c < 0: + continue + inner = m[o + 1:c] + try: + sg = signature(inner) + except Exception as ex: # noqa: BLE001 + sg = dict(bytes=f"ERROR: {ex}"[:100], ok=False, nout=0, nin=0, clob=[], tmpl="", ins=[], outs=[]) + direct.append(dict(tu=tu, line=s["line"], col=s["col"], fn=s.get("fn"), inner=inner, sig=sg, marked=s.get("marked", False))) + _save_cache() + inv = dict(generated=time.strftime("%Y-%m-%d %H:%M"), definitions=defs, direct=direct, uses=dict(uses)) + RUN.mkdir(parents=True, exist_ok=True) + INVENTORY.write_text(json.dumps(inv)) + if not quiet: + gte = [d for d in defs if d["kind"] == "gte"] + print(f"gte_consolidate --inventory: {len(defs)} asm-bearing macro definitions ({len(gte)} GTE, {sum(1 for d in gte if d['sig'] and d['sig']['ok'])} signed), " + f"{len(direct)} direct GTE statements ({sum(1 for d in direct if d['sig']['ok'])} signed), {sum(uses.values())} macro-carried GTE uses") + return inv + + +# ---------------------------------------------------------------------------------------------------------------------- +# the canonical table +# ---------------------------------------------------------------------------------------------------------------------- +def canonical_table(inv, quiet=False): + sony = sony_table() + incn = inc_names() + groups = collections.defaultdict(list) + for d in inv["definitions"]: + if d["kind"] == "gte" and d["sig"] and d["sig"]["ok"]: + groups[sig_key(d["sig"])].append(d) + table, variants, unsigned = {}, {}, [d for d in inv["definitions"] if d["kind"] == "gte" and not (d["sig"] and d["sig"]["ok"])] + names_taken = set() + for key, ds in sorted(groups.items(), key=lambda kv: -len(kv[1])): + names = collections.Counter(d["name"] for d in ds) + # candidates: the names with their address / variant suffixes stripped (`gte_stsxy01_80181E04` is Sony's gte_stsxy01; + # `LDV0_DA34` is a private copy of gte_ldv0), Sony's spelling preferred, then the most-used gte_* spelling + stripped = collections.Counter() + for n, cnt in names.items(): + base = re.sub(r"(_[0-9A-Fa-f]{3,8}|X|_m|_A|_B)$", "", n) + base = re.sub(r"_v[0-9a-f]{4}$", "", base) + stripped[base] += cnt + nout0, nin0 = ds[0]["sig"]["nout"], ds[0]["sig"]["nin"] + # a Sony name is taken only when the operand counts agree with Sony's macro (a private compound that borrowed the name is not it) + sony_named = [n for n, _ in stripped.most_common() if n in sony and (sony[n][0], sony[n][1]) == (nout0, nin0)] + gte_names = [n for n, _ in stripped.most_common() if n.startswith("gte_")] + name = (sony_named or gte_names or [None])[0] + if name is None: + base = incn.get(key) + priv = stripped.most_common(1)[0][0] + name = f"gte_{base}" if base else f"gte_{re.sub(r'[^A-Za-z0-9]', '', priv).lower()}" + if name in sony and not sony_named: + name = f"{name}_alt" + while name in names_taken: + name = f"{name}_alt" + names_taken.add(name) + clob_sets = collections.Counter(tuple(d["sig"]["clob"]) for d in ds) + if name in sony: + canon_clob = tuple(sony[name][2]) + else: + canon_clob = clob_sets.most_common(1)[0][0] + canon_defs = [d for d in ds if tuple(d["sig"]["clob"]) == canon_clob] + synthesized = False + if canon_defs: + texts = collections.Counter((d["params"], re.sub(r"[ \t]+\n", "\n", d["body"]).strip()) for d in canon_defs) + (params, body), _ = texts.most_common(1)[0] + else: + # nobody spells it with Sony's clobbers (every definition carries the steer): the canonical text is the majority body + # with its clobber list set to Sony's — the steer must not become canonical by being universal + texts = collections.Counter((d["params"], re.sub(r"[ \t]+\n", "\n", d["body"]).strip()) for d in ds) + (params, body), _ = texts.most_common(1)[0] + body = set_clobbers(body, list(canon_clob)) + synthesized = True + table[key] = dict(name=name, params=params, body=body, clob=list(canon_clob), defs=len(canon_defs), files=len({d["tu"] for d in canon_defs}), + synthesized=synthesized, + names=dict(names), sony=(name in sony), nin=ds[0]["sig"]["nin"], nout=ds[0]["sig"]["nout"], tmpl=ds[0]["sig"]["tmpl"]) + for cs, cnt in clob_sets.items(): + if cs != canon_clob: + extra = sorted(set(cs) - set(canon_clob)) + fewer = sorted(set(canon_clob) - set(cs)) + vname = f"{name}_m" if extra == ["memory"] and not fewer else f"{name}_v{hashlib.sha1('|'.join(cs).encode()).hexdigest()[:4]}" + variants[f"{key}|{'|'.join(cs)}"] = dict(name=vname, of=name, key=key, clob=list(cs), extra=extra, fewer=fewer, defs=cnt, + files=len({d["tu"] for d in ds if tuple(d["sig"]["clob"]) == cs})) + out = dict(generated=time.strftime("%Y-%m-%d %H:%M"), canonical=table, variants=variants, unsigned=[dict(tu=d["tu"], name=d["name"], l0=d["l0"]) for d in unsigned]) + CANON.write_text(json.dumps(out, indent=1)) + if not quiet: + print(f"gte_consolidate: canonical table — {len(table)} signatures ({sum(1 for t in table.values() if t['sony'])} with Sony's name), " + f"{sum(t['defs'] for t in table.values())} canonical definitions; {len(variants)} lever variants holding {sum(v['defs'] for v in variants.values())} definitions; " + f"{len(unsigned)} unsigned definitions") + for v in sorted(variants.values(), key=lambda v: -v["defs"])[:12]: + print(f" variant {v['name']:24s} of {v['of']:18s} defs {v['defs']:4d} files {v['files']:4d} extra {v['extra']} fewer {v['fewer']}") + for u in unsigned[:8]: + print(f" unsigned {u['tu']}:{u['l0']} {u['name']}") + return out + + +def render_header(canon): + L = ["/* include/gte_inline.h — the GTE coprocessor macros under Sony's names, ONE definition per signature (Phase 36 T5).", + " *", + " * Every macro here is the majority spelling the tree already carried in its per-TU definitions (byte-proven in the fleet),", + " * named by PsyQ's inline_c.h convention; the signature of each (the bytes the build's maspsx → as tail makes of the template,", + " * its operand counts, its clobbers) was computed by tools/gte_consolidate.py, which also deleted the per-TU duplicates.", + " * A definition that differs from the one here only by an extra clobber (a scheduling steer) lives on in its TU as _m", + " * and is a marked lever, not a second spelling. Generated: do not edit by hand — regenerate with `tools/gte_consolidate.py --header`.", + " */", "#ifndef GTE_INLINE_H", "#define GTE_INLINE_H", ""] + for key, t in sorted(canon["canonical"].items(), key=lambda kv: kv[1]["name"]): + body_lines = t["body"].split("\n") + L.append(f"/* {t['tmpl'][:90]}{' …' if len(t['tmpl']) > 90 else ''} ({t['defs']} definitions in {t['files']} files{'' if t['sony'] else '; not a PsyQ name'}) */") + if len(body_lines) == 1: + L.append(f"#define {t['name']}{t['params']} {body_lines[0]}") + else: + L.append(f"#define {t['name']}{t['params']} \\") + for i, bl in enumerate(body_lines): + L.append(f" {bl.strip()}" + (" \\" if i < len(body_lines) - 1 else "")) + L.append("") + L += ["#endif /* GTE_INLINE_H */", ""] + return "\n".join(L) + + +def write_header(canon): + RUN.mkdir(parents=True, exist_ok=True) + (REPO / HEADER).write_text(render_header(canon)) + c = REPO / COMMON + t = c.read_text() + if '#include "gte_inline.h"' not in t: + t = t.replace("#endif /* COMMON_H */", '#include "gte_inline.h" /* Phase 36 T5: the GTE coprocessor macros, one definition each */\n#endif /* COMMON_H */', 1) + c.write_text(t) + print(f"gte_consolidate --header: {HEADER} written ({len(canon['canonical'])} macros); {COMMON} includes it") + + +# ---------------------------------------------------------------------------------------------------------------------- +# --apply: per file +# ---------------------------------------------------------------------------------------------------------------------- +def plan_files(inv, canon, only=None): + """tu -> dict(defs=[definitions to delete/rename], direct=[direct statements], renames={old: new})""" + by_key = canon["canonical"] + var_by = {v["key"] + "|" + "|".join(v["clob"]): v for v in canon["variants"].values()} + plan = collections.defaultdict(lambda: dict(defs=[], direct=[], renames={})) + for d in inv["definitions"]: + if d["kind"] != "gte" or not (d["sig"] and d["sig"]["ok"]): + continue + key = sig_key(d["sig"]) + t = by_key.get(key) + if not t: + continue + vkey = key + "|" + "|".join(d["sig"]["clob"]) + if tuple(d["sig"]["clob"]) == tuple(t["clob"]): + plan[d["tu"]]["defs"].append(dict(d, action="delete", canonical=t["name"])) + if d["name"] != t["name"]: + plan[d["tu"]]["renames"][d["name"]] = t["name"] + elif vkey in var_by: + v = var_by[vkey] + plan[d["tu"]]["defs"].append(dict(d, action="rename", canonical=t["name"], variant=v["name"], extra=v["extra"], fewer=v["fewer"])) + if d["name"] != v["name"]: + plan[d["tu"]]["renames"][d["name"]] = v["name"] + for s in inv["direct"]: + plan[s["tu"]]["direct"].append(s) + files = {tu: p for tu, p in plan.items() if p["defs"] or p["direct"]} + if only: + files = {tu: p for tu, p in files.items() if any(o == tu or tu.endswith("/" + o) or ("/" + o + "/") in tu for o in only)} + return files + + +def direct_rewrite(s, canon): + """('call', text, name) | ('lever', variant_name, extra) | ('none', why, None) for a direct GTE statement.""" + sg = s["sig"] + if not sg["ok"]: + return "none", "unsigned", None + key = sig_key(sg) + t = canon["canonical"].get(key) + if t and sg["nout"] == 0: + if tuple(sg["clob"]) == tuple(t["clob"]): + return "call", f"{t['name']}({', '.join(sg['ins'])});", t["name"] + extra = sorted(set(sg["clob"]) - set(t["clob"])) + fewer = sorted(set(t["clob"]) - set(sg["clob"])) + return "lever", (f"{t['name']}_m" if extra == ["memory"] and not fewer else f"{t['name']}_v"), extra or fewer + # a concatenation of two canonical macros (a load then an op): bytes = b1 + b2, inputs = the first's, clobbers = the union + b = sg["bytes"] + for k1, t1 in canon["canonical"].items(): + b1 = k1.split("|")[0] + if not b.startswith(b1) or len(b1) == 0 or len(b1) >= len(b): + continue + k2 = f"{b[len(b1):]}|0|0" + t2 = canon["canonical"].get(k2) + if not t2 or t1["nout"] or t1["nin"] != sg["nin"]: + continue + union = sorted(set(t1["clob"]) | set(t2["clob"])) + if union == list(sg["clob"]): + return "call", f"{t1['name']}({', '.join(sg['ins'])}); {t2['name']}();", f"{t1['name']}+{t2['name']}" + extra = sorted(set(sg["clob"]) - set(union)) + return "lever", f"{t1['name']}+{t2['name']}_m" if extra == ["memory"] else f"{t1['name']}+{t2['name']}_v", extra or sorted(set(union) - set(sg["clob"])) + return "none", "no canonical signature", None + + +def file_edits(tu, raw, p, canon, label): + """[(start, end, repl)] + the record (per definition / use / direct statement) for one file's consolidation.""" + m = dl.same_len_mask(raw) + ls = dl.line_starts(raw) + edits, rec = [], dict(deleted=0, renamed_defs=0, use_renames=0, direct_calls=0, direct_levers=0, direct_none=0, marked=0, defs=[], direct=[]) + # definitions: delete or rename (the #define line's name token); a renamed variant gets a comment line above + for d in sorted(p["defs"], key=lambda d: d["l0"]): + start, end = ls[d["l0"] - 1], ls[d["l1"]] if d["l1"] < len(ls) else len(raw) + if d["action"] == "delete": + edits.append((start, end, "")) + rec["deleted"] += 1 + rec["defs"].append(dict(name=d["name"], l0=d["l0"], action="deleted", canonical=d["canonical"])) + else: + line = raw[start:ls[d["l0"]] - 1] + k = line.find(d["name"]) + if k < 0: + raise Refuse(f"{tu}:{d['l0']}: the #define line does not carry `{d['name']}`") + note = f"/* {FAKE[3:]} gte variant `{d['variant']}` — {', '.join(d['extra']) or 'fewer clobbers'} beyond Sony's `{d['canonical']}` (a scheduling steer; P36 T5) */\n" + edits.append((start, start, note)) + edits.append((start + k, start + k + len(d["name"]), d["variant"])) + rec["renamed_defs"] += 1 + rec["defs"].append(dict(name=d["name"], l0=d["l0"], action="renamed", variant=d["variant"], canonical=d["canonical"])) + # uses: rename tokens (outside the #define lines being edited); mark the uses of a lever variant + def_lines = {ln for d in p["defs"] for ln in range(d["l0"], d["l1"] + 1)} + lever_names = {d["name"] for d in p["defs"] if d["action"] == "rename"} | {d["variant"] for d in p["defs"] if d["action"] == "rename"} + for old, new in p["renames"].items(): + for mm in re.finditer(r"\b%s\b(?=\s*\()" % re.escape(old), m): + ln = m.count("\n", 0, mm.start()) + 1 + if ln in def_lines: + continue + edits.append((mm.start(), mm.end(), new)) + rec["use_renames"] += 1 + marked_lines = set() + for name in lever_names: + for mm in re.finditer(r"\b%s\b(?=\s*\()" % re.escape(name), m): + ln = m.count("\n", 0, mm.start()) + 1 + if ln in def_lines or ln in marked_lines: + continue + le = m.find("\n", mm.start()) + le = len(raw) if le < 0 else le + if FAKE in raw[ls[ln - 1]:le]: + continue + edits.append((le, le, f" {FAKE} gte via {name if name.endswith(('_m',)) or '_v' in name else p['renames'].get(name, name)} — a clobber Sony's macro lacks (P36 T5 {label})")) + marked_lines.add(ln) + rec["marked"] += 1 + # direct statements + for s in p["direct"]: + pos = ls[s["line"] - 1] + s["col"] - 1 + e = dl.stmt_end(m, pos) + if e < 0 or not dl.ASM_HEAD.match(m, pos): + rec["direct"].append(dict(line=s["line"], action="refused", why="statement not found at the census position")) + continue + how, text, name = direct_rewrite(s, canon) + if how == "call": + edits.append((pos, e, text)) + rec["direct_calls"] += 1 + rec["direct"].append(dict(line=s["line"], action="call", name=name)) + elif how == "lever": + le = m.find("\n", e) + le = len(raw) if le < 0 else le + if FAKE not in raw[ls[s["line"] - 1]:le] and s["line"] not in marked_lines: + edits.append((le, le, f" {FAKE} gte direct — clobbers {name} ({', '.join(text if isinstance(text, list) else [str(text)])}) beyond Sony's (P36 T5 {label})".replace("clobbers " + str(text) + " (", "as " + str(text) + " ("))) + marked_lines.add(s["line"]) + rec["marked"] += 1 + rec["direct_levers"] += 1 + rec["direct"].append(dict(line=s["line"], action="lever", variant=text, delta=name)) + else: + rec["direct_none"] += 1 + rec["direct"].append(dict(line=s["line"], action="none", why=text)) + return edits, rec + + +def apply_batch(a): + clean, dirty = dl.src_clean() + if not clean: + sys.exit(f"gte_consolidate --apply: src/ is dirty — commit or tools/delever.py --restore first:\n{dirty[:400]}") + ok, why = oracle.calibration_current() + if not ok: + sys.exit(f"gte_consolidate --apply: calibration not current ({why})") + if not (REPO / HEADER).exists() or '#include "gte_inline.h"' not in (REPO / COMMON).read_text(): + sys.exit("gte_consolidate --apply: the header is not in place (--header first, then the fleet run and its commit)") + dl.ensure_census(a.jobs) + inv = inventory(a.jobs, quiet=True) + canon = canonical_table(inv, quiet=True) + files = plan_files(inv, canon, a.only) + order = sorted(files, key=lambda tu: (-len(files[tu]["defs"]) - len(files[tu]["direct"]), tu)) + ledger_rows = [json.loads(l) for l in LEDGER.read_text().splitlines() if l.strip()] if LEDGER.exists() else [] + done = {r["tu"] for r in ledger_rows if r.get("rung") == "gte" and r.get("verdict") in ("CONSOLIDATED", "UNCHANGED")} + order = [tu for tu in order if tu not in done or a.rejudge][:a.batch] + print(f"gte_consolidate --apply {a.label}: {len(order)} files of {len(files)} with work ({len(done)} done) — " + f"{sum(len(files[t]['defs']) for t in order)} definitions, {sum(len(files[t]['direct']) for t in order)} direct statements", flush=True) + if not order: + print("gte_consolidate --apply: nothing to do") + return 0 + recipes = oracle.load_recipes()["recipes"] + by_src = oracle.recipes_by_src(recipes) + inc = dl.includers() + def recipes_for(tu): + return [r for t in inc.get(tu, []) for r in by_src.get(t, [])] if tu.endswith(".h") else by_src.get(tu, []) + dl.INFLIGHT.write_text(json.dumps(dict(label=a.label, files={tu: (REPO / tu).read_text(errors="surrogateescape") for tu in order}))) + log_p = RUN / f"apply_{a.label}.log" + log_f = open(log_p, "a") + def log(msg): + line = f"{time.strftime('%H:%M:%S')} {msg}" + with _LOCK: + print(line, flush=True) + log_f.write(line + "\n") + log_f.flush() + pool = ThreadPoolExecutor(max_workers=a.jobs) + results = [] + + def work(tu): + path = REPO / tu + st = path.stat() + raw = path.read_text(errors="surrogateescape") + recs = recipes_for(tu) + row = dict(ts=time.strftime("%Y-%m-%d %H:%M:%S"), label=a.label, rung="gte", calib=dict(head=oracle.head(), stamp=oracle.config_stamp()), + tu=tu, fn=None, addr=None, aliases=None, header=tu.endswith(".h"), sites=[], compiles=0, seconds=0.0) + if not recs: + row["verdict"] = "NO-RECIPE" + return row + plan_tu = files[tu] + # the variant trial: a definition whose only difference from the canonical one is a clobber is tried AS canonical (deleted, its + # uses renamed to the canonical name), one at a time on the untouched text; IDENTICAL -> the clobber was no lever here + variants = [d for d in plan_tu["defs"] if d["action"] == "rename"] + freed = 0 + for d in variants: + trial = dict(defs=[dict(d, action="delete")], direct=[], renames=({d["name"]: d["canonical"]} if d["name"] != d["canonical"] else {})) + try: + ed, _ = file_edits(tu, raw, trial, canon, a.label) + cand = dl.apply_edits(raw, ed) + if cand == raw: + continue + try: + v, dt, err = oracle.judge_all(recs, cand, tag="gtev", write_path=(tu if tu.endswith(".h") else None)) + finally: + dl.restore_file(path, raw, st) + row["compiles"] += len(recs) + row["seconds"] += dt + if v == "IDENTICAL": + d["action"], d["trial"] = "delete", "IDENTICAL" + if d["name"] != d["canonical"]: + plan_tu["renames"][d["name"]] = d["canonical"] + plan_tu["renames"].pop(d["name"], None) if d["name"] == d["canonical"] else None + freed += 1 + else: + d["trial"] = v + except (Refuse, dl.Refuse) as ex: + d["trial"] = f"REFUSED {ex}" + # a variant that stays a variant keeps its rename to _m + for d in variants: + if d["action"] == "rename" and d["name"] != d["variant"]: + plan_tu["renames"][d["name"]] = d["variant"] + try: + edits, rec = file_edits(tu, raw, plan_tu, canon, a.label) + except Refuse as ex: + row.update(verdict="REFUSED", why=str(ex)) + log(f" {tu}: REFUSED {ex}") + return row + rec["variants_freed"] = freed + rec["variants_kept"] = sum(1 for d in variants if d["action"] == "rename") + row["record"] = rec + cands = [] + try: + cands.append(("all", dl.apply_edits(raw, edits))) + no_direct = [e for e in edits if not any(e[0] == dl.line_starts(raw)[s["line"] - 1] + s["col"] - 1 for s in files[tu]["direct"])] + if len(no_direct) != len(edits): + cands.append(("defs-only", dl.apply_edits(raw, no_direct))) + except dl.Refuse as ex: + row.update(verdict="REFUSED", why=f"edits: {ex}") + log(f" {tu}: REFUSED edits {ex}") + return row + verdict = "UNCHANGED" + for tag, cand in cands: + if cand == raw: + continue + try: + if tu.endswith(".h") and len(recs) > 1: + path.write_text(cand, errors="surrogateescape") + vs = list(pool.map(lambda r: oracle.judge(r, None, tag="gte"), recs)) + bad = [v for v in vs if v[0] != "IDENTICAL"] + v, dt, err = (bad[0][0], sum(x[1] for x in vs), bad[0][2]) if bad else ("IDENTICAL", sum(x[1] for x in vs), "") + else: + v, dt, err = oracle.judge_all(recs, cand, tag="gte", write_path=(tu if tu.endswith(".h") else None)) + finally: + dl.restore_file(path, raw, st) + row["compiles"] += len(recs) + row["seconds"] += dt + if v == "IDENTICAL": + path.write_text(cand, errors="surrogateescape") + verdict = "CONSOLIDATED" if tag == "all" else "CONSOLIDATED-DEFS-ONLY" + if tag != "all": + rec["direct_calls_refused"] = rec.pop("direct_calls", 0) + log(f" {tu}: the direct-statement rewrites DIFFER — kept the definition edits only") + break + verdict = f"DIFFERS-{tag}" if v == "DIFFERS" else f"{v}-{tag}" + log(f" {tu}: {tag} {v} {err[:120]}") + row["verdict"] = verdict if verdict.startswith(("CONSOLIDATED", "UNCHANGED")) else "REFUSED" + if not verdict.startswith(("CONSOLIDATED", "UNCHANGED")): + row["why"] = verdict + log(f" {tu}: {row['verdict']} — deleted {rec['deleted']} defs, renamed {rec['renamed_defs']}, use renames {rec['use_renames']}, " + f"direct calls {rec.get('direct_calls', 0)}, direct levers {rec['direct_levers']}, unmatched {rec['direct_none']}, marked {rec['marked']}") + return row + tus = [tu for tu in order if not tu.endswith(".h")] + hdrs = [tu for tu in order if tu.endswith(".h")] + with ThreadPoolExecutor(max_workers=a.jobs) as ex: + results = list(ex.map(work, tus)) + for h in hdrs: + results.append(work(h)) + pool.shutdown(wait=True) + dl.ledger_append(results) + agg = collections.Counter() + for r in results: + agg[r["verdict"]] += 1 + for k in ("deleted", "renamed_defs", "use_renames", "direct_calls", "direct_levers", "direct_none", "marked", "variants_freed", "variants_kept"): + agg[k] += r.get("record", {}).get(k, 0) + agg["compiles"] += r["compiles"] + line = (f"gte_consolidate: batch {a.label} — {len(order)} files: {agg['CONSOLIDATED']} consolidated, {agg['CONSOLIDATED-DEFS-ONLY']} defs-only, " + f"{agg['UNCHANGED']} unchanged, {agg['REFUSED']} refused, {agg['NO-RECIPE']} no-recipe · definitions deleted {agg['deleted']} / renamed as lever variants " + f"{agg['renamed_defs']} (variant trials: {agg['variants_freed']} freed, {agg['variants_kept']} kept) · use renames {agg['use_renames']} · direct statements → calls {agg['direct_calls']} / lever {agg['direct_levers']} / " + f"unmatched {agg['direct_none']} · markers {agg['marked']} · compiles {agg['compiles']} · final {len(order) - agg['REFUSED'] - agg['NO-RECIPE']}/{len(order)} identical") + log(line) + (RUN / f"batch_{a.label}.json").write_text(json.dumps(dict(label=a.label, files=order, totals=dict(agg), rows=results), indent=1)) + return 0 if agg["REFUSED"] == 0 else 1 + + +# ---------------------------------------------------------------------------------------------------------------------- +# --sweep: dead asm-bearing macros; a compound macro's inner asm dropped when byte-neutral +# ---------------------------------------------------------------------------------------------------------------------- +def sweep(a): + clean, dirty = dl.src_clean() + if not clean: + sys.exit(f"gte_consolidate --sweep: src/ is dirty:\n{dirty[:400]}") + ok, why = oracle.calibration_current() + if not ok: + sys.exit(f"gte_consolidate --sweep: calibration not current ({why})") + dl.ensure_census(a.jobs) + sites = dl.load_sites() + uses_by_file = collections.defaultdict(collections.Counter) + for s in sites: + if s.get("via"): + uses_by_file[s["tu"]][s["via"]] += 1 + inc = dl.includers() + # a macro used by an included shared header counts as used by every includer + hdr_uses = {h: uses_by_file.get(h, collections.Counter()) for h in inc} + recipes = oracle.load_recipes()["recipes"] + by_src = oracle.recipes_by_src(recipes) + rows, n_dead, n_inner, n_files = [], 0, 0, 0 + files = files_under_src() + if a.only: + files = [p for p in files if any(o in p.as_posix() for o in a.only)] + for p in files: + rel = p.relative_to(REPO).as_posix() + raw = p.read_text(errors="surrogateescape") + if "#define" not in raw: + continue + blocks = [(l0, l1, name, body) for (l0, l1, name, body) in lc.define_blocks(raw) if lc.macro_kind(body) and lc.macro_kind(body) != "gte"] + if not blocks: + continue + used = collections.Counter(uses_by_file.get(rel, {})) + for h, hu in hdr_uses.items(): + if rel in inc.get(h, []): + used.update(hu) + m = dl.same_len_mask(raw) + ls = dl.line_starts(raw) + edits, dead, inner = [], [], [] + for (l0, l1, name, body) in blocks: + start, end = ls[l0 - 1], ls[l1] if l1 < len(ls) else len(raw) + if used.get(name, 0) == 0 and not re.search(r"\b%s\b" % re.escape(name), m[:start] + m[end:]): + edits.append((start, end, "")) + dead.append(name) + continue + # a compound macro: drop the asm statement line(s) inside the definition (the launder/barrier steer), keep the code + lines = raw[start:end].split("\n") + keep, dropped = [], 0 + for ln in lines: + if lc.ASM_KW.search(ln) and ("__asm__" in ln or "asm" in ln) and ('"' in ln): + dropped += 1 + continue + keep.append(ln) + if dropped and len(keep) > 1: + new = "\n".join(keep) + if not new.endswith("\n") and raw[start:end].endswith("\n"): + new += "\n" + edits.append((start, end, new)) + inner.append(name) + if not edits: + continue + recs = [r for t in inc.get(rel, []) for r in by_src.get(t, [])] if rel.endswith(".h") else by_src.get(rel, []) + if not recs: + print(f" {rel}: no recipe — skipped") + continue + st = p.stat() + try: + cand = dl.apply_edits(raw, edits) + except dl.Refuse as ex: + print(f" {rel}: REFUSED {ex}") + continue + verdict_all = None + for tag, cand_t in (("all", cand), ("dead-only", dl.apply_edits(raw, [e for e in edits if e[2] == ""]) if inner and dead else None)): + if cand_t is None or cand_t == raw: + continue + try: + v, dt, err = oracle.judge_all(recs, cand_t, tag="sweep", write_path=(rel if rel.endswith(".h") else None)) + finally: + dl.restore_file(p, raw, st) + if v == "IDENTICAL": + p.write_text(cand_t, errors="surrogateescape") + verdict_all = tag + break + print(f" {rel}: {tag} {v} {err[:100]}") + n_files += verdict_all is not None + if verdict_all == "all": + n_dead += len(dead) + n_inner += len(inner) + elif verdict_all == "dead-only": + n_dead += len(dead) + inner_kept = inner + inner = [] + rows.append(dict(ts=time.strftime("%Y-%m-%d %H:%M:%S"), label=a.label, rung="sweep", calib=dict(head=oracle.head(), stamp=oracle.config_stamp()), + tu=rel, fn=None, addr=None, aliases=None, header=rel.endswith(".h"), verdict=("SWEPT-" + verdict_all if verdict_all else "REFUSED"), + dead=dead, inner_dropped=(inner if verdict_all else []), sites=[], compiles=len(recs))) + print(f" {rel}: {rows[-1]['verdict']} — dead {dead} inner-asm dropped {inner if verdict_all else []}") + dl.ledger_append(rows) + print(f"gte_consolidate --sweep {a.label}: {n_dead} dead asm-bearing macro definitions deleted, {n_inner} compound macros' inner asm dropped, " + f"{n_files} files written, {sum(1 for r in rows if r['verdict'] == 'REFUSED')} refused") + return 0 + + +def status(): + rows = [json.loads(l) for l in LEDGER.read_text().splitlines() if l.strip()] if LEDGER.exists() else [] + g = [r for r in rows if r.get("rung") in ("gte", "sweep")] + print(f"gte_consolidate --status: {len(g)} rows — {dict(collections.Counter(r['verdict'] for r in g))}") + return 0 + + +# ---------------------------------------------------------------------------------------------------------------------- +def selftest(): + ok = True + def fail(msg): + nonlocal ok + ok = False + print("selftest FAIL:", msg) + # 1. the signature engine: three spellings of rtps are one signature; a template with an operand binds to $4 + s1 = signature('"nop;nop;rtps"') + s2 = signature('"nop;" "nop;" ".word 0x4a180001"') + s3 = signature('"nop;nop;cop2 0x0180001"') + if not (s1["ok"] and s1["bytes"] == s2["bytes"] == s3["bytes"]): + fail(f"rtps spellings: {s1['bytes'][:40]} {s2['bytes'][:40]} {s3['bytes'][:40]}") + s4 = signature('"lwc2 $0, 0( %0 );" "lwc2 $1, 4( %0 )" : : "r"( r0 )') + s5 = signature('"lwc2 $0, 0(%0)\\n" "lwc2 $1, 4(%0)\\n" : : "r"(r0) : "memory"') + if not (s4["ok"] and s4["bytes"] == s5["bytes"] and s4["nin"] == 1 and s4["clob"] == [] and s5["clob"] == ["memory"]): + fail(f"ldv0 spellings/clobbers: {s4} {s5}") + if signature('"nop;nop;rtpt"')["bytes"] == s1["bytes"]: + fail("rtps and rtpt must differ") + # 2. the canonical table on a synthetic inventory: canonical / variant / private name / concatenated direct statement + inv = dict(definitions=[ + dict(tu="a.c", l0=1, l1=2, name="gte_ldv0", params="( r0 )", body='__asm__ volatile ( "lwc2 $0, 0( %0 );" "lwc2 $1, 4( %0 )" : : "r"( r0 ) )', kind="gte", sig=s4), + dict(tu="b.c", l0=1, l1=2, name="gte_ldv0", params="(r0)", body='__asm__ __volatile__( "lwc2 $0, 0(%0)\\n" "lwc2 $1, 4(%0)\\n" : : "r"(r0) : "memory")', kind="gte", sig=s5), + dict(tu="c.c", l0=1, l1=2, name="LDV0_DA34", params="( r0 )", body='__asm__ volatile ("lwc2 $0, 0( %0 );lwc2 $1, 4( %0 )" : : "r"( r0 ))', kind="gte", sig=s4), + dict(tu="a.c", l0=3, l1=3, name="gte_rtps", params="()", body='__asm__ volatile ("nop;nop;rtps")', kind="gte", sig=s1), + ], direct=[], uses={}) + canon = canonical_table(inv, quiet=True) + t = canon["canonical"].get(sig_key(s4)) + if not t or t["name"] != "gte_ldv0" or t["clob"] != [] or t["defs"] != 2: + fail(f"canonical ldv0: {t}") + v = [x for x in canon["variants"].values() if x["of"] == "gte_ldv0"] + if len(v) != 1 or v[0]["name"] != "gte_ldv0_m" or v[0]["extra"] != ["memory"]: + fail(f"ldv0 memory variant: {v}") + # 3. direct statements: a canonical call, a lever, a concatenation + d_call = dict(sig=signature('"lwc2 $0, 0(%0);" "lwc2 $1, 4(%0)" : : "r"(p)')) + d_lever = dict(sig=signature('"lwc2 $0, 0(%0);" "lwc2 $1, 4(%0)" : : "r"(p) : "memory"')) + d_cat = dict(sig=signature('"lwc2 $0, 0(%0);" "lwc2 $1, 4(%0);" "nop;nop;rtps" : : "r"(p)')) + if direct_rewrite(d_call, canon) != ("call", "gte_ldv0(p);", "gte_ldv0"): + fail(f"direct call: {direct_rewrite(d_call, canon)}") + if direct_rewrite(d_lever, canon)[0] != "lever" or direct_rewrite(d_lever, canon)[1] != "gte_ldv0_m": + fail(f"direct lever: {direct_rewrite(d_lever, canon)}") + r = direct_rewrite(d_cat, canon) + if r != ("call", "gte_ldv0(p); gte_rtps();", "gte_ldv0+gte_rtps"): + fail(f"direct concatenation: {r}") + # 4. the per-file edits on a fixture: the canonical def deleted, the private use renamed, the variant renamed + marked, a direct call + fx = ('#define gte_ldv0( r0 ) __asm__ volatile ( "lwc2 $0, 0( %0 );" "lwc2 $1, 4( %0 )" : : "r"( r0 ) )\n' + '#define LDV0_DA34( r0 ) __asm__ volatile ("lwc2 $0, 0( %0 );lwc2 $1, 4( %0 )" : : "r"( r0 ))\n' + '#define gte_ldv0m( r0 ) __asm__ __volatile__( "lwc2 $0, 0(%0)\\n" "lwc2 $1, 4(%0)\\n" : : "r"(r0) : "memory")\n' + 'void f(s32 *v) {\n LDV0_DA34(v);\n gte_ldv0m(v);\n __asm__ volatile("lwc2 $0, 0(%0);" "lwc2 $1, 4(%0)" : : "r"(v));\n}\n') + defs = [] + for (l0, l1, name, body) in lc.define_blocks(fx): + sg = signature(asm_inner(body)) + defs.append(dict(tu="fx.c", l0=l0, l1=l1, name=name, params=define_params(fx, l0), body=body, kind="gte", sig=sg)) + fm, fls = dl.same_len_mask(fx), dl.line_starts(fx) + fpos = fls[6] + 4 + fo = fm.find("(", fpos) + finner = fm[fo + 1:lc._paren_span(fm, fo)] + inv2 = dict(definitions=defs, direct=[dict(tu="fx.c", line=7, col=5, fn="f", inner=finner, sig=signature(finner))], uses={}) + canon2 = canonical_table(inv2, quiet=True) + plan = plan_files(inv2, canon2) + edits, rec = file_edits("fx.c", fx, plan["fx.c"], canon2, "self") + out = dl.apply_edits(fx, edits) + if "#define gte_ldv0(" in out or "#define LDV0_DA34" in out: + fail("canonical/private definitions must be deleted") + if "#define gte_ldv0_m( r0 )" not in out or "gte variant `gte_ldv0_m`" not in out: + fail(f"the variant definition renamed + noted:\n{out}") + if " gte_ldv0(v);\n" not in out: + fail(f"the private use renamed to the canonical name:\n{out}") + if "gte_ldv0_m(v); // !FAKE: gte via gte_ldv0_m" not in out: + fail(f"the lever variant's use marked:\n{out}") + if " gte_ldv0(v);\n}" not in out: + fail(f"the direct statement rewritten into the canonical call:\n{out}") + if rec["deleted"] != 2 or rec["renamed_defs"] != 1 or rec["use_renames"] != 2 or rec["direct_calls"] != 1 or rec["marked"] != 1: + fail(f"record: {rec}") + # 5. the header renders every canonical macro once, with its parameters + h = render_header(canon2) + if h.count("#define gte_ldv0(") != 1 or "#define gte_ldv0_m" in h: + fail("header: one canonical definition, no variant") + print(f"gte_consolidate --selftest: {'OK' if ok else 'FAIL'} — signatures rtps={s1['bytes'][16:24]} ldv0={s4['bytes'][:16]}; table {len(canon2['canonical'])} canonical / {len(canon2['variants'])} variant; fixture edits {len(edits)}") + return ok + + +def main(): + ap = argparse.ArgumentParser(description=__doc__.split("\n")[0]) + ap.add_argument("--inventory", action="store_true") + ap.add_argument("--header", action="store_true") + ap.add_argument("--apply", action="store_true") + ap.add_argument("--sweep", action="store_true") + ap.add_argument("--status", action="store_true") + ap.add_argument("--selftest", action="store_true") + ap.add_argument("--batch", type=int, default=400) + ap.add_argument("--label", default=None) + ap.add_argument("--only", nargs="*", default=None) + ap.add_argument("--rejudge", action="store_true") + ap.add_argument("-j", "--jobs", type=int, default=12) + a = ap.parse_args() + RUN.mkdir(parents=True, exist_ok=True) + if a.selftest: + sys.exit(0 if selftest() else 1) + if a.status: + sys.exit(status()) + if a.inventory: + dl.ensure_census(a.jobs) + inv = inventory(a.jobs) + canonical_table(inv) + return + if a.header: + inv = json.loads(INVENTORY.read_text()) if INVENTORY.exists() else inventory(a.jobs, quiet=True) + canon = canonical_table(inv, quiet=True) + write_header(canon) + return + if a.apply: + if not a.label: + sys.exit("--label is required") + sys.exit(apply_batch(a)) + if a.sweep: + if not a.label: + sys.exit("--label is required") + sys.exit(sweep(a)) + ap.print_help() + + +if __name__ == "__main__": + main() diff --git a/decomp-architect/corpus/tools/P10/lever_census.py b/decomp-architect/corpus/tools/P10/lever_census.py index 12d647503..fb244f569 100644 --- a/decomp-architect/corpus/tools/P10/lever_census.py +++ b/decomp-architect/corpus/tools/P10/lever_census.py @@ -69,7 +69,50 @@ MIPS_REG_NAMES = {"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", GTE_MNEMONICS = {"lwc2", "swc2", "mtc2", "mfc2", "ctc2", "cfc2", "cop2", "rtps", "rtpt", "nclip", "ncds", "nccs", "ncdt", "ncct", "ncs", "nct", "cdp", "cc", "dpcs", "dpct", "dpcl", "intpl", "sqr", "op", "gpf", "gpl", "avsz3", "avsz4", "mvmva"} FAKE_MARK = "!FAKE:" -NON_LEVER_KINDS = {"gte", "verbatim-body"} # Sony's coprocessor idiom; a manifest-listed hand-asm routine — censused, never a lever +NON_LEVER_KINDS = {"gte", "verbatim-body", "gte-unsigned"} # Sony's coprocessor idiom; a manifest-listed hand-asm routine — censused, never a lever +GTE_LEVER_KIND = "gte-lever" # a GTE op whose clobbers exceed its canonical's (a `_m`/`_v` variant macro, or a direct statement): a steer +GTE_VARIANT_NAME = re.compile(r"(_m|_v[0-9a-f]{4})$") +_gte_tables = None + + +def _gte_lookup(): + """(sig_cache, canonical-by-bytes) from tools/gte_consolidate.py's files, read once; ({}, {}) when T5 has not run.""" + global _gte_tables + if _gte_tables is None: + cache, canon = {}, {} + try: + import json as _json + base = REPO / ".run" / "P36" / "gte" + if (base / "sig_cache.json").exists(): + cache = _json.loads((base / "sig_cache.json").read_text()) + if (base / "canonical.json").exists(): + for key, tbl in _json.loads((base / "canonical.json").read_text())["canonical"].items(): + canon[key] = dict(name=tbl["name"], clob=sorted(tbl["clob"])) + except Exception: # noqa: BLE001 — a torn file reads as "no table" + cache, canon = {}, {} + _gte_tables = (cache, canon) + return _gte_tables + + +def classify_direct_gte(inner): + """'gte' (Sony's idiom or no canonical to compare), 'gte-lever' (clobbers beyond the canonical's), 'gte-unsigned' (a text the + consolidation tool has not signed yet — run `tools/gte_consolidate.py --inventory`).""" + cache, canon = _gte_lookup() + if not canon: + return "gte" + try: + import gte_consolidate as gc + tmpl, outs, ins, clob = gc.parse_asm(inner) + bound = gc.bind_regs(tmpl, len(outs), len(ins)) + except Exception: # noqa: BLE001 + return "gte-unsigned" + b = cache.get(bound) + if not b or b.startswith("ERROR"): + return "gte-unsigned" + c = canon.get(f"{b}|{len(outs)}|{len(ins)}") + if not c: + return "gte" + return GTE_LEVER_KIND if sorted(clob) != c["clob"] else "gte" # an `asm-body` site (a whole routine as one asm statement inside a C shell) becomes `verbatim-body` only when the manifest lists the # routine as PERMANENT-VERBATIM; an unlisted or DECOMPILE-* one stays a lever and the guard (verbatim_check) names it NORM_SYM = re.compile(r"\b(?:func|D)_80[0-9A-Fa-f]{6}\b") @@ -479,6 +522,8 @@ def walk_file(raw, rel, is_header): continue role(pos, "asm-stmt") d = span_of_line.get(ln) + if kind == "gte" and d: + kind = classify_direct_gte(masked[o + 1:c]) if d and is_whole_body_asm(masked, line_starts[d["line"] - 1], line_starts[d["end"]] - 1, pos, c): kind = "asm-body" # a whole routine as one asm statement inside a C shell (any template: GTE ones too); the manifest decides its fate add_site("B", kind, pos, masked[pos:c + 1], detail=detail, via="") @@ -501,7 +546,10 @@ def walk_file(raw, rel, is_header): continue name = m.group(1) c = _paren_span(masked, m.end() - 1) - add_site("B", asm_macro_names[name], m.start(), masked[m.start():c + 1] if c > 0 else name, detail=name, via=name) + k = asm_macro_names[name] + if k == "gte" and GTE_VARIANT_NAME.search(name): + k = GTE_LEVER_KIND + add_site("B", k, m.start(), masked[m.start():c + 1] if c > 0 else name, detail=name, via=name) # ---- 4. volatile tokens for m in VOLATILE_KW.finditer(masked): @@ -814,6 +862,17 @@ def run_census(jobs, use_cache=True, out_dir=OUT_DIR_DEFAULT, want_sites=False, what="whole routines written in assembly inside a C shell (the §265 lane's in-function form): the manifest's " "PERMANENT-VERBATIM rows are hand asm and not levers; an asm-body the manifest does not list as permanent " "stays a lever (unlisted_routines names them with their disposition)"), + gte_levers=dict(sites=sum(1 for s in sites if s["kind"] == GTE_LEVER_KIND), + marked=sum(1 for s in sites if s["kind"] == GTE_LEVER_KIND and s["marked"]), + unmarked=sum(1 for s in sites if s["kind"] == GTE_LEVER_KIND and not s["marked"]), + via_macro=sum(1 for s in sites if s["kind"] == GTE_LEVER_KIND and s.get("via")), + direct=sum(1 for s in sites if s["kind"] == GTE_LEVER_KIND and not s.get("via")), + unsigned=sum(1 for s in sites if s["kind"] == "gte-unsigned"), + what="GTE ops whose clobbers exceed the canonical macro's (a scheduling steer): levers for T7, outside the headline number"), + per_tu_asm_macro_definitions=dict(total=sum(1 for m in mdefs_all if m["tu"] != gte_header), + by_kind=dict(collections.Counter(m["kind"] for m in mdefs_all if m["tu"] != gte_header)), + gte_variants=sum(1 for m in mdefs_all if m["tu"] != gte_header and m["kind"] == "gte" and GTE_VARIANT_NAME.search(m["name"])), + what="asm-bearing #define blocks outside the GTE header: 0 at the close (T5 deletes the canonical duplicates, T7 the variants)"), macro_definitions=dict(total=len(mdefs_all), names=len(macro_names), kinds=dict(macro_kinds), names_with_multiple_texts=sum(1 for n, t in macro_texts.items() if len(t) > 1), top=[(n, c, len(macro_texts[n])) for n, c in macro_names.most_common(25)]), @@ -888,6 +947,12 @@ def render(s): L.append(f" THE PHASE'S NUMBER (pins + asm statements, GTE excluded): {ab['sites']:,} sites in {ab['bodies']:,} bodies " f"({ab['distinct_bodies']:,} distinct) · marked !FAKE {ab['marked']:,} · UNMARKED {ab['unmarked']:,}") L.append(f" orphan !FAKE markers (no pin/asm site on the line nor below): {s.get('orphan_markers', {}).get('count', 0)}") + g = s.get("gte_levers", {}) + if g: + L.append(f" GTE levers (clobbers beyond the canonical macro's): {g['sites']:,} sites ({g['via_macro']:,} via a variant macro, {g['direct']:,} direct) · " + f"marked {g['marked']:,} · UNMARKED {g['unmarked']:,} · unsigned GTE statements {g['unsigned']:,}") + pt = s.get("per_tu_asm_macro_definitions", {}) + L.append(f" per-TU asm macro definitions outside the GTE header: {pt.get('total', 0):,} {pt.get('by_kind', {})} (GTE variants {pt.get('gte_variants', 0):,})") p = s["pins"] L.append(f" pins: {p['sites']:,} · $0 {p['zero']:,} · $sp {p['sp']} · with initializer {p['init']:,} · volatile-qualified " f"{p['volatile_qualified']} · bare-name {p['bare_name']} · spellings {p['spelling']}") @@ -1032,9 +1097,12 @@ def main(): ab = [x for x in sites if x["cls"] in "AB" and x["kind"] not in NON_LEVER_KINDS and x["tu"] != a.gte_header] un = [x for x in ab if not x["marked"]] if a.strict: - print(f"lever_census --check --strict: pins {s['pins']['sites']}, asm {sum(1 for x in ab if x['cls'] == 'B')}, " - f"volatile-needed {s['classes']['C']['sites']}, register-needed {s['classes']['D']['sites']} — {'OK' if not ab else 'FAIL'}") - if ab: + pt = s.get("per_tu_asm_macro_definitions", {}).get("total", 0) + gl = s.get("gte_levers", {}).get("sites", 0) + print(f"lever_census --check --strict: pins {s['pins']['sites']}, asm {sum(1 for x in ab if x['cls'] == 'B' and x['kind'] != GTE_LEVER_KIND)}, " + f"gte-levers {gl}, per-TU asm macro definitions {pt}, volatile-needed {s['classes']['C']['sites']}, register-needed {s['classes']['D']['sites']} — " + f"{'OK' if not ab and not pt else 'FAIL'}") + if ab or pt: for x in ab[:10]: print(f" {x['tu']}:{x['line']} {x['fn']} {x['cls']}/{x['kind']} {x['detail']}") rc = 1 diff --git a/decomp-architect/tools/MANIFEST.md b/decomp-architect/tools/MANIFEST.md index 743deb6d3..70cd897ad 100644 --- a/decomp-architect/tools/MANIFEST.md +++ b/decomp-architect/tools/MANIFEST.md @@ -8,8 +8,8 @@ > its platform SDK need the marked adaptation. The last table lists the tools that are project-only in code (their *shape* is a task; > their code does not transfer). *TODO(platform): the MIPS and PlayStation SDK hard-codes are the ones another platform replaces first.* > -> **Coverage:** 299 tool files in scope (submodules, vendored and downloaded code excluded), of which 299 live rows -> below; per phase: P1 2 · P2 26 · P3 17 · P4 9 · P5 26 · P6 51 · P7 20 · P8 86 · P9 27 · P10 19 · PROJECT-ONLY 16. Superseded tools appear only as pointers to their successor (30 pointer rows); one-offs are omitted. Table rows in all: 329 (the installer checks its copy against this figure). +> **Coverage:** 300 tool files in scope (submodules, vendored and downloaded code excluded), of which 300 live rows +> below; per phase: P1 2 · P2 26 · P3 17 · P4 9 · P5 26 · P6 51 · P7 20 · P8 86 · P9 27 · P10 20 · PROJECT-ONLY 16. Superseded tools appear only as pointers to their successor (30 pointer rows); one-offs are omitted. Table rows in all: 330 (the installer checks its copy against this figure). ## P1 — extraction + manifest @@ -327,6 +327,7 @@ | `cast_call_sites.py` | add per-site function-pointer casts so a draft can call a differently typed callee | Adds per-site function-pointer casts so a draft can call a differently typed callee | repo src layout | | `ghidra_scripts/ApplySymbols.java` | apply curated names and signatures inside the analysis tool and save | The in-tool half of that mirror: apply curated names and signatures, save on exit | none | | `lever_census.py` | census every compiler-forcing construct in the C and gate the levers-off phase | The Phase-36 census of lever sites (register pins, asm statements by kind, volatile levers, bare register, asm-label aliases, builtins, attributes; the whole-body hand-asm routines and the GTE ops set apart) derived from the shared-body scanner with a per-token coverage assertion against the raw text, four known-true controls, the !FAKE marker split, --check (0 unmarked pins/asm, 0 orphan markers) and --strict (0 pins, 0 asm) gates, --sites for the delever ledger, a fixture self-test | repo paths, the shared-body scanner | +| `gte_consolidate.py` | consolidate the GTE coprocessor inline-asm macros under Sony's names in one header and sweep dead lever macros | The Phase-36 T5 tool: every asm-bearing macro definition and direct GTE statement SIGNED by the build's own maspsx→as tail (template bytes with operands bound to fixed registers, operand counts, clobbers); one canonical text per signature named by PsyQ's inline_c.h convention (Sony's file supplies names and clobber lists, never opcode words) written to include/gte_inline.h; per file the canonical duplicates deleted, private names renamed, a variant with extra clobbers tried as canonical and kept as a marked _m lever only when the object differs, direct statements rewritten into canonical calls (a concatenation of two included); every file judged through every recipe; --sweep deletes dead asm-bearing macros and drops a compound macro's inner asm when byte-neutral | Sony's inline_c.h path, the census sites, the oracle | | `macro_to_header.py` | convert a shared-body macro header into per-function plain-C headers included at each site | The Phase-35 converter: every DEFINE_ macro body becomes a plain-C header under src/shared// included at its site, the legacy name-parameterized headers converted, the registry text-edited, the macro header deleted; --plan / --apply / --finalize / --verify | the macro form is this project's; a kit-born project shares headers from its first bank | | `asm_verbatim.py` | emit a function's target assembly as an inline-assembly body | Emits the file-scope inline-assembly body form from a disassembly file | repo asm layout | | `build_engine_types.py` | extract inline-defined types and typedefs from a source file into a shared header | Extracts inline-defined named types and typedefs from a source file into a shared header | repo shared-header path | diff --git a/docs/SETUP.md b/docs/SETUP.md index 2e8f4d83f..ee4d21620 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -785,6 +785,7 @@ Every script under `tools/` (plus the two report make-targets), grouped by purpo | | `tools/lever_census.py` | **(P36 T1)** The census of every compiler-forcing construct ("lever") in the fleet's C — register pins, asm statements by kind (barrier / launder / keepalive / instruction / GTE / verbatim-body), volatile levers, bare `register`, plus the deferred asm-label aliases, builtins and attributes — derived from `share_census`'s scanner with a per-token coverage assertion against the raw text, four known-true controls, the `// !FAKE:` marker split, `--check` (0 unmarked pins/asm AND 0 orphan markers — a `// !FAKE:` line with no pin/asm site on it nor on the line below) and `--check --strict` (0 pins, 0 asm outside the GTE header) gates, the JSON's `head` + stat-based `src_stamp` (delever refuses a census that does not describe the tree) and a per-file walk cache keyed on the walker's own hash (a tool change invalidates it, R35), `--sites` (every site to `.run/P36/census/lever_sites.jsonl`, the delever ledger's input), `--selftest`. Evidence: `.run/P36/census/lever_census.{json,txt}`; `progress.py` publishes the `levers` block and a README sentence from it. | | | `tools/delever_oracle.py` | **(P36 T2)** The fast byte oracle for a single-translation-unit edit: `--recipes` captures every object's exact build command through `make -n -W BINARY=` (the Makefile's own pipeline — the jump-table pad stage, the per-object `-O0` overrides, the twin rule — into `.run/P36/delever/recipes.json`, regenerable in ~15 s); a candidate is compiled IN PLACE with `-o`/`-MF` redirected to scratch and its bytes compared with `build/`'s object from the fleet run (build/ is never written); `--calibrate ` proves 100 % equality untouched + twin == primary + a positive control (a nop injected at the end of a real body → DIFFERS) and writes `calibration.json` (HEAD, config stamp, per-object seconds); `--status`. Measured at T2: main 0.08–0.77 s per object, overlays ~0.14 s. | | | `tools/delever.py` | **(P36 T2/T3)** The de-lever engine AND the campaign tool. Rewrites per lever class on the raw text at the census's positions (a token mismatch REFUSES, never guesses): pin → plain declaration (type/qualifiers/initializer kept; the `$0` zero-register variable's uses → 0, refused if it is ever assigned), barrier / keep-alive → deleted, launder → deleted when it launders a value into itself, **an ASSIGNMENT `out = in;` when its output and input differ** (deleting those made cc1 2.7.2 abort — the T2 probe counted them NEEDED), a hand-placed instruction → its C (addu-$zero/move/la/lh/lw/addiu/sll/srl/and/andi/lui/li and the lui+addiu / lui+ori pairs), a macro-carried site → deleted for a pure launder statement macro (`SHB`), its value `((T)(p))` for a launder statement-expression, REFUSED for a compound macro (XFER/DRAW/RTP_SND: the lever is in the `#define`, T5), volatile / register → dropped. Per body: replay (a ledger exemplar with the same normalized text: 1 compile) → rung A strip-all → rung B greedy, through `delever_oracle` (verdicts IDENTICAL / DIFFERS / COMPILE-ERROR / COMPILE-CRASH). **The file is the write unit and its final compile the proof**: every body's accepted edits + the file-scope volatile edits + the `// !FAKE:` markers spliced once, compiled through every recipe of the file (a twin's object; every includer of a header, in parallel) — IDENTICAL or the file-scope edits are dropped, or the file is restored and REFUSED (COMBINATION-FAILED). `--plan` / `--apply --batch N --label L [--headers] [--only …] [-j 12]` (TUs in parallel, exemplar files before their copies; headers serial; the tree must be clean, the calibration current, the census's src stamp the tree's — it reruns the census itself), `--redraw REFUSED NOTHING-USABLE` (draw again the bodies whose latest ledger verdict is one of these — after a tool fix), `--restore` (from `inflight.json`, the only restore — R102; it also drops the in-flight batch's ledger rows into an ignored `ledger.jsonl.killed_