mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 21:36:06 -04:00
feat(phase-30 S47-A3): jtbl family func_80179B74 — 2/3 siblings banked
Exemplar ov_SC01_077 @0x80179b74 (matched-ov077), 3 members. Per-sibling whole-binary byte-gate (G3/P9) is the
arbiter: jtbl_carve -> make extract -> remap_hseq -> make build, keep iff byte-identical else
revert. Tally: === func_80179B74: {'BANKED': 2, 'isolate-fail': 1} ===
Committed per family because jtbl_family_bank's per-sibling revert restores from HEAD — an
uncommitted prior family would be lost. Campaign-end R22 verifies the fleet.
This commit is contained in:
@@ -4915,6 +4915,7 @@ ov_MAIN_012_MAPFILE := $(ov_MAIN_012_OUT).map
|
||||
ov_MAIN_012_LD_SCRIPT := $(ov_MAIN_012_OUT).ld
|
||||
ov_MAIN_012_SPLAT_YAML := config/splat.ov_MAIN_012.yaml
|
||||
ov_MAIN_012_JTBL_INTERLEAVE := --order tail.data.o,ov_MAIN_012.o,tail2.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_MAIN_012/ov_MAIN_012.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
|
||||
ov_MAIN_012_CHECK_SHA := config/check.ov_MAIN_012.sha
|
||||
ov_MAIN_012_SYMBOLS := config/symbols.ov_MAIN_012.txt
|
||||
ov_MAIN_012_SIG := .run/sig.ov_MAIN_012.jsonl
|
||||
@@ -4960,6 +4961,7 @@ ov_SC03_107_MAPFILE := $(ov_SC03_107_OUT).map
|
||||
ov_SC03_107_LD_SCRIPT := $(ov_SC03_107_OUT).ld
|
||||
ov_SC03_107_SPLAT_YAML := config/splat.ov_SC03_107.yaml
|
||||
ov_SC03_107_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_107.o,tail2.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_SC03_107/ov_SC03_107.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
|
||||
ov_SC03_107_CHECK_SHA := config/check.ov_SC03_107.sha
|
||||
ov_SC03_107_SYMBOLS := config/symbols.ov_SC03_107.txt
|
||||
ov_SC03_107_SIG := .run/sig.ov_SC03_107.jsonl
|
||||
|
||||
@@ -96,7 +96,7 @@ segments:
|
||||
- [0x0, c, ov_MAIN_012] # code: starts at file 0x0 (overlays open with a prologue)
|
||||
- [0x561e0, data, tail]
|
||||
- [0x5ba58, .rodata, ov_MAIN_012] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x5bbd0, data, tail2]
|
||||
- [0x5bc5c, data, tail2]
|
||||
- [0x5DB24, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
|
||||
- [0x5DB27] # EOF marker = the 0.4.dec byte length
|
||||
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
|
||||
|
||||
@@ -96,7 +96,7 @@ segments:
|
||||
- [0x0, c, ov_SC03_107] # code: starts at file 0x0 (overlays open with a prologue)
|
||||
- [0x5a304, data, tail]
|
||||
- [0x72270, .rodata, ov_SC03_107] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x723e8, data, tail2]
|
||||
- [0x72474, data, tail2]
|
||||
- [0x73BE4, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
|
||||
- [0x73BE7] # EOF marker = the 0.4.dec byte length
|
||||
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
|
||||
|
||||
@@ -23880,7 +23880,84 @@ Lend:
|
||||
DEFINE_func_80179B28() /* dedup: shared engine-core @0x80179b28 (src/shared) */
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012", func_80179B74);
|
||||
|
||||
// @class: schedule
|
||||
// @stuck: none — MATCH (111 ins). symcheck: data syms CLEAN (D_80184F40/D_80185344, 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_80184F40 at write index
|
||||
* D_80185344. 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_80185344` 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_80184F40[0x200];` / `extern s16 D_80185344;`) so the whole-binary
|
||||
* link and any one-big-TU build see one consistent type.
|
||||
*/
|
||||
|
||||
extern u16 D_80184F40[0x200];
|
||||
extern s16 D_80185344;
|
||||
|
||||
void func_80179B74(u16 *p) {
|
||||
s32 pad[10];
|
||||
s16 c;
|
||||
|
||||
(void)&pad;
|
||||
c = *p++;
|
||||
D_80184F40[D_80185344] = c;
|
||||
D_80185344 = (D_80185344 + 1) & 0x1FF;
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
case 5:
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
break;
|
||||
case 0x13:
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 6:
|
||||
case 0x12:
|
||||
case 0x14:
|
||||
case 0x1F:
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
break;
|
||||
case 0x17:
|
||||
case 0x1C:
|
||||
case 0x1D:
|
||||
case 0x20:
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_80184F40[D_80185344] = t; D_80185344 = (D_80185344 + 1) & 0x1FF; }
|
||||
break;
|
||||
case 0x22:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_func_80179D30() /* dedup: shared engine-core @0x80179d30 (src/shared) */
|
||||
|
||||
|
||||
@@ -23582,7 +23582,84 @@ Lend:
|
||||
DEFINE_func_80179B28() /* dedup: shared engine-core @0x80179b28 (src/shared) */
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_107/nonmatchings/ov_SC03_107", func_80179B74);
|
||||
|
||||
// @class: schedule
|
||||
// @stuck: none — MATCH (111 ins). symcheck: data syms CLEAN (D_8019B598/D_8019B99C, 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_8019B598 at write index
|
||||
* D_8019B99C. 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_8019B99C` 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_8019B598[0x200];` / `extern s16 D_8019B99C;`) so the whole-binary
|
||||
* link and any one-big-TU build see one consistent type.
|
||||
*/
|
||||
|
||||
extern u16 D_8019B598[0x200];
|
||||
extern s16 D_8019B99C;
|
||||
|
||||
void func_80179B74(u16 *p) {
|
||||
s32 pad[10];
|
||||
s16 c;
|
||||
|
||||
(void)&pad;
|
||||
c = *p++;
|
||||
D_8019B598[D_8019B99C] = c;
|
||||
D_8019B99C = (D_8019B99C + 1) & 0x1FF;
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
case 5:
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
break;
|
||||
case 0x13:
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 6:
|
||||
case 0x12:
|
||||
case 0x14:
|
||||
case 0x1F:
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
break;
|
||||
case 0x17:
|
||||
case 0x1C:
|
||||
case 0x1D:
|
||||
case 0x20:
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
{ s16 t = *p++; D_8019B598[D_8019B99C] = t; D_8019B99C = (D_8019B99C + 1) & 0x1FF; }
|
||||
break;
|
||||
case 0x22:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_func_80179D30() /* dedup: shared engine-core @0x80179d30 (src/shared) */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user