feat(phase-29): func_80179B74 family probe 3/3 banked

This commit is contained in:
Drew T
2026-07-27 13:39:41 -06:00
parent e721452526
commit 5ec8aa77af
7 changed files with 246 additions and 6 deletions
+3
View File
@@ -151,6 +151,7 @@ build/src/ov_SC01_000/ov_SC01_000_jr_801588CC.o: JTBL_PADS := 0,4 # §8e pads (
build/src/ov_SC01_000/ov_SC01_000_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_000/ov_SC01_000_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_000/ov_SC01_000_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_000/ov_SC01_000_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
ov_SC01_000_CHECK_SHA := config/check.ov_SC01_000.sha
ov_SC01_000_SYMBOLS := config/symbols.ov_SC01_000.txt
ov_SC01_000_SIG := .run/sig.ov_SC01_000.jsonl
@@ -181,6 +182,7 @@ build/src/ov_SC01_001/ov_SC01_001_jr_801588CC.o: JTBL_PADS := 0,4 # §8e pads (
build/src/ov_SC01_001/ov_SC01_001_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_001/ov_SC01_001_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_001/ov_SC01_001_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_001/ov_SC01_001_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
ov_SC01_001_CHECK_SHA := config/check.ov_SC01_001.sha
ov_SC01_001_SYMBOLS := config/symbols.ov_SC01_001.txt
ov_SC01_001_SIG := .run/sig.ov_SC01_001.jsonl
@@ -511,6 +513,7 @@ build/src/ov_SC01_004/ov_SC01_004_jr_801588CC.o: JTBL_PADS := 0,4 # §8e pads (
build/src/ov_SC01_004/ov_SC01_004_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_004/ov_SC01_004_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_004/ov_SC01_004_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_004/ov_SC01_004_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
ov_SC01_004_CHECK_SHA := config/check.ov_SC01_004.sha
ov_SC01_004_SYMBOLS := config/symbols.ov_SC01_004.txt
ov_SC01_004_SIG := .run/sig.ov_SC01_004.jsonl
+1 -1
View File
@@ -153,7 +153,7 @@ segments:
- [0x7bdb4, .rodata, ov_SC01_000_jr_801734BC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x7bdc8, data, tail17]
- [0x7bf70, .rodata, ov_SC01_000_jr_80178D40] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x7c0e8, data, tail18]
- [0x7c174, data, tail18]
- [0x7c178, .rodata, ov_SC01_000_jr_8017A4AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x7c204, data, tail19]
- [0x7c208, .rodata, ov_SC01_000_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
+1 -1
View File
@@ -154,7 +154,7 @@ segments:
- [0xc3e8c, .rodata, ov_SC01_001_jr_801734BC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xc3ea0, data, tail17]
- [0xc4048, .rodata, ov_SC01_001_jr_80178D40] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xc41c0, data, tail18]
- [0xc424c, data, tail18]
- [0xc4250, .rodata, ov_SC01_001_jr_8017A4AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xc42dc, data, tail19]
- [0xc42e0, .rodata, ov_SC01_001_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
+1 -1
View File
@@ -153,7 +153,7 @@ segments:
- [0x6626c, .rodata, ov_SC01_004_jr_801734BC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x66280, data, tail17]
- [0x66428, .rodata, ov_SC01_004_jr_80178D40] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x665a0, data, tail18]
- [0x6662c, data, tail18]
- [0x66630, .rodata, ov_SC01_004_jr_8017A4AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x666bc, data, tail19]
- [0x666c0, .rodata, ov_SC01_004_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
+80 -1
View File
@@ -3291,7 +3291,86 @@ Lend:
DEFINE_func_80179B28() /* dedup: shared engine-core @0x80179B28 (src/shared) */
INCLUDE_ASM("asm/ov_SC01_000/nonmatchings/ov_SC01_000_jr_80178D40", func_80179B74);
extern short D_801DA710;
extern void func_8017A4AC(void);
// @class: schedule
// @stuck: none — MATCH (111 ins). symcheck: data syms CLEAN (D_801A5268/D_801A566C, 0 INVENTED); its lone MISSING is jtbl_801D8F9C, the COMPILER-emitted table ($L17 -> .rdata) — banking needs the §8a/§8e rodata-island flip (35 entries, .align 3), not a source-side ref.
/* func_80179B74 (ov_SC01_077) — command-queue WRITER: copies the opcode + its
* operand halfwords from *p into the 0x200-entry ring D_801A5268 at write index
* D_801A566C. Mirror of the reader func_8017A4AC (same ring, read index D_801DA710).
*
* Three levers were needed on top of the obvious shape (each byte-proven here):
* 1. jtbl SPAN — the target's table is 35 entries (0..0x22) with NO `addiu a0,a0,-1`
* bias and `sltiu v0,a0,0x23`, so the source must contain an empty `case 0:` and
* an empty `case 0x22:`; without them gcc biases by -1 and emits sltiu 0x20.
* 2. SCHEDULE — the operand push must route through a NAMED block-scoped temp
* (`{ s16 t = *p++; ring[idx] = t; ... }`). Written as the anonymous
* `ring[idx] = *p++;` the sched1 pass puts the `lh D_801A566C` ahead of the
* `lhu 0(a1)` in exactly the two blocks that also carry a live `addiu a1,a1,2`
* (cases {1,5} and {0x17,0x1c,0x1d,0x20}) — 6 of the 8 residual mismatches.
* The temp gives the loaded value its own pseudo and flips those two blocks.
* 3. FRAME — the target reserves 0x80 with NO saves and NO spills; gcc's own
* (unused) area for this body is 0x58, so +0x28 of address-taken local is
* required: `s32 pad[10]; (void)&pad;` (cookbook §17 phantom-frame INDUCE
* lever). 10 words exactly; 8 -> 0x78 and 12 -> 0x88 both miss.
*
* Case-block ORDER in the source is the emitted block order: {1,5} then {0x13}
* then {2,3,4,6,0x12,0x14,0x1f} then {0x17,0x1c,0x1d,0x20}. The 3-/2-/1-push
* tails are then cross-jump merged (no calls, so §88 does not block it) into the
* shared .L80179CE4 / .L80179D08 tail that sits after the last case block.
*
* Symbols are the splat spellings and match the sibling TU ov_SC01_077_jr_8017A4AC.c
* (`extern u16 D_801A5268[0x200];` / `extern s16 D_801A566C;`) so the whole-binary
* link and any one-big-TU build see one consistent type.
*/
extern u16 D_801A5268[0x200];
extern s16 D_801A566C;
void func_80179B74(u16 *p) {
s32 pad[10];
s16 c;
(void)&pad;
c = *p++;
D_801A5268[D_801A566C] = c;
D_801A566C = (D_801A566C + 1) & 0x1FF;
switch (c) {
case 0:
break;
case 1:
case 5:
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
break;
case 0x13:
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
break;
case 2:
case 3:
case 4:
case 6:
case 0x12:
case 0x14:
case 0x1F:
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
break;
case 0x17:
case 0x1C:
case 0x1D:
case 0x20:
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
{ s16 t = *p++; D_801A5268[D_801A566C] = t; D_801A566C = (D_801A566C + 1) & 0x1FF; }
break;
case 0x22:
break;
}
}
DEFINE_func_80179D30() /* dedup: shared engine-core @0x80179D30 (src/shared) */
+80 -1
View File
@@ -3289,7 +3289,86 @@ Lend:
DEFINE_func_80179B28() /* dedup: shared engine-core @0x80179B28 (src/shared) */
INCLUDE_ASM("asm/ov_SC01_001/nonmatchings/ov_SC01_001_jr_80178D40", func_80179B74);
extern short D_801DA710;
extern void func_8017A4AC(void);
// @class: schedule
// @stuck: none — MATCH (111 ins). symcheck: data syms CLEAN (D_801ED4F8/D_801ED8FC, 0 INVENTED); its lone MISSING is jtbl_801D8F9C, the COMPILER-emitted table ($L17 -> .rdata) — banking needs the §8a/§8e rodata-island flip (35 entries, .align 3), not a source-side ref.
/* func_80179B74 (ov_SC01_077) — command-queue WRITER: copies the opcode + its
* operand halfwords from *p into the 0x200-entry ring D_801ED4F8 at write index
* D_801ED8FC. Mirror of the reader func_8017A4AC (same ring, read index D_801DA710).
*
* Three levers were needed on top of the obvious shape (each byte-proven here):
* 1. jtbl SPAN — the target's table is 35 entries (0..0x22) with NO `addiu a0,a0,-1`
* bias and `sltiu v0,a0,0x23`, so the source must contain an empty `case 0:` and
* an empty `case 0x22:`; without them gcc biases by -1 and emits sltiu 0x20.
* 2. SCHEDULE — the operand push must route through a NAMED block-scoped temp
* (`{ s16 t = *p++; ring[idx] = t; ... }`). Written as the anonymous
* `ring[idx] = *p++;` the sched1 pass puts the `lh D_801ED8FC` ahead of the
* `lhu 0(a1)` in exactly the two blocks that also carry a live `addiu a1,a1,2`
* (cases {1,5} and {0x17,0x1c,0x1d,0x20}) — 6 of the 8 residual mismatches.
* The temp gives the loaded value its own pseudo and flips those two blocks.
* 3. FRAME — the target reserves 0x80 with NO saves and NO spills; gcc's own
* (unused) area for this body is 0x58, so +0x28 of address-taken local is
* required: `s32 pad[10]; (void)&pad;` (cookbook §17 phantom-frame INDUCE
* lever). 10 words exactly; 8 -> 0x78 and 12 -> 0x88 both miss.
*
* Case-block ORDER in the source is the emitted block order: {1,5} then {0x13}
* then {2,3,4,6,0x12,0x14,0x1f} then {0x17,0x1c,0x1d,0x20}. The 3-/2-/1-push
* tails are then cross-jump merged (no calls, so §88 does not block it) into the
* shared .L80179CE4 / .L80179D08 tail that sits after the last case block.
*
* Symbols are the splat spellings and match the sibling TU ov_SC01_077_jr_8017A4AC.c
* (`extern u16 D_801ED4F8[0x200];` / `extern s16 D_801ED8FC;`) so the whole-binary
* link and any one-big-TU build see one consistent type.
*/
extern u16 D_801ED4F8[0x200];
extern s16 D_801ED8FC;
void func_80179B74(u16 *p) {
s32 pad[10];
s16 c;
(void)&pad;
c = *p++;
D_801ED4F8[D_801ED8FC] = c;
D_801ED8FC = (D_801ED8FC + 1) & 0x1FF;
switch (c) {
case 0:
break;
case 1:
case 5:
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
break;
case 0x13:
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
break;
case 2:
case 3:
case 4:
case 6:
case 0x12:
case 0x14:
case 0x1F:
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
break;
case 0x17:
case 0x1C:
case 0x1D:
case 0x20:
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
{ s16 t = *p++; D_801ED4F8[D_801ED8FC] = t; D_801ED8FC = (D_801ED8FC + 1) & 0x1FF; }
break;
case 0x22:
break;
}
}
DEFINE_func_80179D30() /* dedup: shared engine-core @0x80179D30 (src/shared) */
+80 -1
View File
@@ -3289,7 +3289,86 @@ Lend:
DEFINE_func_80179B28() /* dedup: shared engine-core @0x80179B28 (src/shared) */
INCLUDE_ASM("asm/ov_SC01_004/nonmatchings/ov_SC01_004_jr_80178D40", func_80179B74);
extern short D_801DA710;
extern void func_8017A4AC(void);
// @class: schedule
// @stuck: none — MATCH (111 ins). symcheck: data syms CLEAN (D_8018FC60/D_80190064, 0 INVENTED); its lone MISSING is jtbl_801D8F9C, the COMPILER-emitted table ($L17 -> .rdata) — banking needs the §8a/§8e rodata-island flip (35 entries, .align 3), not a source-side ref.
/* func_80179B74 (ov_SC01_077) — command-queue WRITER: copies the opcode + its
* operand halfwords from *p into the 0x200-entry ring D_8018FC60 at write index
* D_80190064. Mirror of the reader func_8017A4AC (same ring, read index D_801DA710).
*
* Three levers were needed on top of the obvious shape (each byte-proven here):
* 1. jtbl SPAN — the target's table is 35 entries (0..0x22) with NO `addiu a0,a0,-1`
* bias and `sltiu v0,a0,0x23`, so the source must contain an empty `case 0:` and
* an empty `case 0x22:`; without them gcc biases by -1 and emits sltiu 0x20.
* 2. SCHEDULE — the operand push must route through a NAMED block-scoped temp
* (`{ s16 t = *p++; ring[idx] = t; ... }`). Written as the anonymous
* `ring[idx] = *p++;` the sched1 pass puts the `lh D_80190064` ahead of the
* `lhu 0(a1)` in exactly the two blocks that also carry a live `addiu a1,a1,2`
* (cases {1,5} and {0x17,0x1c,0x1d,0x20}) — 6 of the 8 residual mismatches.
* The temp gives the loaded value its own pseudo and flips those two blocks.
* 3. FRAME — the target reserves 0x80 with NO saves and NO spills; gcc's own
* (unused) area for this body is 0x58, so +0x28 of address-taken local is
* required: `s32 pad[10]; (void)&pad;` (cookbook §17 phantom-frame INDUCE
* lever). 10 words exactly; 8 -> 0x78 and 12 -> 0x88 both miss.
*
* Case-block ORDER in the source is the emitted block order: {1,5} then {0x13}
* then {2,3,4,6,0x12,0x14,0x1f} then {0x17,0x1c,0x1d,0x20}. The 3-/2-/1-push
* tails are then cross-jump merged (no calls, so §88 does not block it) into the
* shared .L80179CE4 / .L80179D08 tail that sits after the last case block.
*
* Symbols are the splat spellings and match the sibling TU ov_SC01_077_jr_8017A4AC.c
* (`extern u16 D_8018FC60[0x200];` / `extern s16 D_80190064;`) so the whole-binary
* link and any one-big-TU build see one consistent type.
*/
extern u16 D_8018FC60[0x200];
extern s16 D_80190064;
void func_80179B74(u16 *p) {
s32 pad[10];
s16 c;
(void)&pad;
c = *p++;
D_8018FC60[D_80190064] = c;
D_80190064 = (D_80190064 + 1) & 0x1FF;
switch (c) {
case 0:
break;
case 1:
case 5:
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
break;
case 0x13:
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
break;
case 2:
case 3:
case 4:
case 6:
case 0x12:
case 0x14:
case 0x1F:
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
break;
case 0x17:
case 0x1C:
case 0x1D:
case 0x20:
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
{ s16 t = *p++; D_8018FC60[D_80190064] = t; D_80190064 = (D_80190064 + 1) & 0x1FF; }
break;
case 0x22:
break;
}
}
DEFINE_func_80179D30() /* dedup: shared engine-core @0x80179D30 (src/shared) */