feat(phase-30 S48-T6): wave 3 — 27 exemplars banked, 0 drafts lost

Wave 3 (wf_2680d8ff-539, 74 agents, 8.08M tok): 39 targets -> 35 agent-MATCH,
0 refuted, 4 NEAR, 0 FAIL -> 27 BANKED on the whole-binary gate (69%).

THE HARDENED HARNESS HELD: 0 drafts missing on disk (wave 2 lost 21 of 26 to a
shared output dir). Per-agent dirs + "never touch anything outside your own
directory" + a verifier that re-runs sha1sum LAST.

PRIOR-NOTES SEEDING IS THE SESSION'S BEST LEVER: 7 of 9 seeded targets
converted, including all three wave-2 whole-binary-gate misses and both big
NEARs — func_80189540 (551 ins, was NEAR +2) and func_8017C3BC (407 ins, was
NEAR 17). func_8017C294 (the x16 family) went 18 -> 11 ins: narrowing, not a
wall.

func_80189540 also required the one host edit its agent byte-probed:
  src/ov_SC04_018/ov_SC04_018_jr_80188E1C.c:3093
  extern s32 func_80189540(s32 a0, s16 a1)  ->  (s16 a0, s16 a1)
That TU has no call site, so the edit is inert; the OTHER TUs' (s32,s16) decls
are deliberately left alone (real call sites, and an s16 prototype there would
force caller-side truncation and could de-match banked callers).

Its agent also recovered a better draft that already existed at
.run/backlog_drafts/func_80189540.c — a 551-ins MATCH that had been DE-matched
to 549 by "fixing" the definition's s16 first parameter to s32, the exact
inverse of that draft's own warning. Restoring s16 recovered the match.
This commit is contained in:
Drew T
2026-08-11 22:51:32 -06:00
parent a67c82d340
commit 50dd6b3c3f
36 changed files with 27242 additions and 446 deletions
+13 -8
View File
@@ -21,7 +21,7 @@ ov_SC01_077_ELF := $(ov_SC01_077_OUT).elf
ov_SC01_077_MAPFILE := $(ov_SC01_077_OUT).map
ov_SC01_077_LD_SCRIPT := $(ov_SC01_077_OUT).ld
ov_SC01_077_SPLAT_YAML := config/splat.ov_SC01_077.yaml
ov_SC01_077_JTBL_INTERLEAVE := --order tail.data.o,ov_SC01_077_a.o,ov_SC01_077_jr_8012ACE0.o,tail2.data.o,ov_SC01_077_jr_80135888.o,tail3.data.o,ov_SC01_077_jr_80135A4C.o,tail4.data.o,ov_SC01_077_jr_80135D20.o,tail5.data.o,ov_SC01_077_jr_801380E0.o,ov_SC01_077_o0.o,tail6.data.o,ov_SC01_077.o,tail7.data.o,ov_SC01_077_jr_8015444C.o,ov_SC01_077_jr_80154C24.o,ov_SC01_077_jr_801588CC.o,ov_SC01_077_jr_80159C84.o,tail8.data.o,ov_SC01_077_jr_8015A3C8.o,tail9.data.o,ov_SC01_077_jr_8015AE2C.o,tail10.data.o,ov_SC01_077_jr_8015C32C.o,tail11.data.o,ov_SC01_077_jr_8016AB6C.o,tail12.data.o,ov_SC01_077_jr_80171B4C.o,ov_SC01_077_jr_801734BC.o,tail13.data.o,ov_SC01_077_jr_801789AC.o,ov_SC01_077_jr_80178D40.o,tail14.data.o,ov_SC01_077_jr_8017A4AC.o,tail15.data.o,ov_SC01_077_jr_8017AE2C.o,tail16.data.o,ov_SC01_077_jr_80180B64.o,tail17.data.o,ov_SC01_077_jr_8018103C.o,tail18.data.o,ov_SC01_077_jr_801820DC.o,ov_SC01_077_jr_80182268.o,ov_SC01_077_jr_80182E7C.o,tail19.data.o,ov_SC01_077_jr_80183AF0.o,ov_SC01_077_jr_80183BAC.o,ov_SC01_077_jr_80183CF4.o,tail20.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_SC01_077_JTBL_INTERLEAVE := --order tail.data.o,ov_SC01_077_a.o,ov_SC01_077_jr_8012ACE0.o,tail2.data.o,ov_SC01_077_jr_80135888.o,tail3.data.o,ov_SC01_077_jr_80135A4C.o,tail4.data.o,ov_SC01_077_jr_80135D20.o,tail5.data.o,ov_SC01_077_jr_801380E0.o,ov_SC01_077_o0.o,tail6.data.o,ov_SC01_077.o,tail7.data.o,ov_SC01_077_jr_8015444C.o,ov_SC01_077_jr_80154C24.o,ov_SC01_077_jr_801588CC.o,ov_SC01_077_jr_80159C84.o,tail8.data.o,ov_SC01_077_jr_8015A3C8.o,tail9.data.o,ov_SC01_077_jr_8015AE2C.o,tail10.data.o,ov_SC01_077_jr_8015C32C.o,tail11.data.o,ov_SC01_077_jr_8016AB6C.o,tail12.data.o,ov_SC01_077_jr_80171B4C.o,ov_SC01_077_jr_801734BC.o,tail13.data.o,ov_SC01_077_jr_801789AC.o,ov_SC01_077_jr_80178D40.o,tail14.data.o,ov_SC01_077_jr_8017A4AC.o,tail15.data.o,ov_SC01_077_jr_8017AE2C.o,tail16.data.o,ov_SC01_077_jr_80180B64.o,tail17.data.o,ov_SC01_077_jr_8018103C.o,tail18.data.o,ov_SC01_077_jr_80181BE4.o,tail19.data.o,ov_SC01_077_jr_801820DC.o,ov_SC01_077_jr_80182268.o,ov_SC01_077_jr_80182E7C.o,tail20.data.o,ov_SC01_077_jr_80183324.o,tail21.data.o,ov_SC01_077_jr_80183AF0.o,ov_SC01_077_jr_80183BAC.o,ov_SC01_077_jr_80183CF4.o,tail22.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_SC01_077/ov_SC01_077.o: JTBL_PADS := 0,0,4,0,4,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x38,+0x58,+0x70,+0x90,+0xa8
build/src/ov_SC01_077/ov_SC01_077_a.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
build/src/ov_SC01_077/ov_SC01_077_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
@@ -36,6 +36,7 @@ build/src/ov_SC01_077/ov_SC01_077_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (
build/src/ov_SC01_077/ov_SC01_077_jr_8017AE2C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
build/src/ov_SC01_077/ov_SC01_077_jr_8018103C.o: JTBL_PADS := 0,4,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18,+0x38,+0x58
build/src/ov_SC01_077/ov_SC01_077_jr_80182268.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x40
build/src/ov_SC01_077/ov_SC01_077_jr_80183324.o: JTBL_PADS := 0,0,0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x40,+0x60,+0x80
build/src/ov_SC01_077/ov_SC01_077_jr_80183BAC.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC01_077/ov_SC01_077_o0.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
ov_SC01_077_CHECK_SHA := config/check.ov_SC01_077.sha
@@ -59,7 +60,7 @@ ov_SC01_005_ELF := $(ov_SC01_005_OUT).elf
ov_SC01_005_MAPFILE := $(ov_SC01_005_OUT).map
ov_SC01_005_LD_SCRIPT := $(ov_SC01_005_OUT).ld
ov_SC01_005_SPLAT_YAML := config/splat.ov_SC01_005.yaml
ov_SC01_005_JTBL_INTERLEAVE := --order tail.data.o,ov_SC01_005.o,ov_SC01_005_jr_8012ACE0.o,tail2.data.o,ov_SC01_005_jr_80135888.o,tail3.data.o,ov_SC01_005_jr_80135A4C.o,tail4.data.o,ov_SC01_005_jr_80135D20.o,tail5.data.o,ov_SC01_005_jr_801380E0.o,ov_SC01_005_o0c.o,tail6.data.o,ov_SC01_005_jr_8013F350.o,tail7.data.o,ov_SC01_005_jr_8013FFD8.o,tail8.data.o,ov_SC01_005_jr_80140608.o,tail9.data.o,ov_SC01_005_jr_8015444C.o,ov_SC01_005_jr_80154C24.o,ov_SC01_005_jr_801588CC.o,ov_SC01_005_jr_80159C84.o,tail10.data.o,ov_SC01_005_jr_8015A3C8.o,tail11.data.o,ov_SC01_005_jr_8015AE2C.o,tail12.data.o,ov_SC01_005_jr_8015C32C.o,tail13.data.o,ov_SC01_005_jr_8016AB6C.o,tail14.data.o,ov_SC01_005_jr_80171B4C.o,ov_SC01_005_jr_801734BC.o,tail15.data.o,ov_SC01_005_jr_801789AC.o,ov_SC01_005_jr_80178D40.o,tail16.data.o,ov_SC01_005_jr_8017A4AC.o,tail17.data.o,ov_SC01_005_jr_8017AE2C.o,ov_SC01_005_jr_8017C340.o,tail18.data.o,ov_SC01_005_jr_8017ED5C.o,tail19.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_SC01_005_JTBL_INTERLEAVE := --order tail.data.o,ov_SC01_005.o,ov_SC01_005_jr_8012ACE0.o,tail2.data.o,ov_SC01_005_jr_80135888.o,tail3.data.o,ov_SC01_005_jr_80135A4C.o,tail4.data.o,ov_SC01_005_jr_80135D20.o,tail5.data.o,ov_SC01_005_jr_801380E0.o,ov_SC01_005_o0c.o,tail6.data.o,ov_SC01_005_jr_8013F350.o,tail7.data.o,ov_SC01_005_jr_8013FFD8.o,tail8.data.o,ov_SC01_005_jr_80140608.o,tail9.data.o,ov_SC01_005_jr_8015444C.o,ov_SC01_005_jr_80154C24.o,ov_SC01_005_jr_801588CC.o,ov_SC01_005_jr_80159C84.o,tail10.data.o,ov_SC01_005_jr_8015A3C8.o,tail11.data.o,ov_SC01_005_jr_8015AE2C.o,tail12.data.o,ov_SC01_005_jr_8015C32C.o,tail13.data.o,ov_SC01_005_jr_8016AB6C.o,tail14.data.o,ov_SC01_005_jr_80171B4C.o,ov_SC01_005_jr_801734BC.o,tail15.data.o,ov_SC01_005_jr_801789AC.o,ov_SC01_005_jr_80178D40.o,tail16.data.o,ov_SC01_005_jr_8017A4AC.o,tail17.data.o,ov_SC01_005_jr_8017AE2C.o,ov_SC01_005_jr_8017C340.o,tail18.data.o,ov_SC01_005_jr_8017EB44.o,ov_SC01_005_jr_8017ED5C.o,tail19.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_SC01_005/ov_SC01_005.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
build/src/ov_SC01_005/ov_SC01_005_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
build/src/ov_SC01_005/ov_SC01_005_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
@@ -417,7 +418,7 @@ ov_SC04_018_ELF := $(ov_SC04_018_OUT).elf
ov_SC04_018_MAPFILE := $(ov_SC04_018_OUT).map
ov_SC04_018_LD_SCRIPT := $(ov_SC04_018_OUT).ld
ov_SC04_018_SPLAT_YAML := config/splat.ov_SC04_018.yaml
ov_SC04_018_JTBL_INTERLEAVE := --order tail.data.o,ov_SC04_018.o,ov_SC04_018_jr_8012ACE0.o,tail2.data.o,ov_SC04_018_jr_80135888.o,tail3.data.o,ov_SC04_018_jr_80135A4C.o,tail4.data.o,ov_SC04_018_jr_80135D20.o,tail5.data.o,ov_SC04_018_jr_801380E0.o,ov_SC04_018_o0c.o,tail6.data.o,ov_SC04_018_jr_8013F350.o,tail7.data.o,ov_SC04_018_jr_8013FFD8.o,tail8.data.o,ov_SC04_018_jr_80140608.o,tail9.data.o,ov_SC04_018_jr_8015444C.o,ov_SC04_018_jr_80154C24.o,ov_SC04_018_jr_801588CC.o,ov_SC04_018_jr_80159C84.o,tail10.data.o,ov_SC04_018_jr_8015A3C8.o,tail11.data.o,ov_SC04_018_jr_8015AE2C.o,tail12.data.o,ov_SC04_018_jr_8015C32C.o,tail13.data.o,ov_SC04_018_jr_8016AB6C.o,tail14.data.o,ov_SC04_018_jr_80171B4C.o,ov_SC04_018_jr_801734BC.o,tail15.data.o,ov_SC04_018_jr_801789AC.o,ov_SC04_018_jr_80178D40.o,tail16.data.o,ov_SC04_018_jr_8017A4AC.o,tail17.data.o,ov_SC04_018_jr_8017AE2C.o,tail18.data.o,ov_SC04_018_jr_80185D70.o,tail19.data.o,ov_SC04_018_jr_80186570.o,tail20.data.o,ov_SC04_018_jr_801878E8.o,ov_SC04_018_jr_80188E1C.o,tail21.data.o,ov_SC04_018_jr_8018CC40.o,tail22.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_SC04_018_JTBL_INTERLEAVE := --order tail.data.o,ov_SC04_018.o,ov_SC04_018_jr_8012ACE0.o,tail2.data.o,ov_SC04_018_jr_80135888.o,tail3.data.o,ov_SC04_018_jr_80135A4C.o,tail4.data.o,ov_SC04_018_jr_80135D20.o,tail5.data.o,ov_SC04_018_jr_801380E0.o,ov_SC04_018_o0c.o,tail6.data.o,ov_SC04_018_jr_8013F350.o,tail7.data.o,ov_SC04_018_jr_8013FFD8.o,tail8.data.o,ov_SC04_018_jr_80140608.o,tail9.data.o,ov_SC04_018_jr_8015444C.o,ov_SC04_018_jr_80154C24.o,ov_SC04_018_jr_801588CC.o,ov_SC04_018_jr_80159C84.o,tail10.data.o,ov_SC04_018_jr_8015A3C8.o,tail11.data.o,ov_SC04_018_jr_8015AE2C.o,tail12.data.o,ov_SC04_018_jr_8015C32C.o,tail13.data.o,ov_SC04_018_jr_8016AB6C.o,tail14.data.o,ov_SC04_018_jr_80171B4C.o,ov_SC04_018_jr_801734BC.o,tail15.data.o,ov_SC04_018_jr_801789AC.o,ov_SC04_018_jr_80178D40.o,tail16.data.o,ov_SC04_018_jr_8017A4AC.o,tail17.data.o,ov_SC04_018_jr_8017AE2C.o,tail18.data.o,ov_SC04_018_jr_80185D70.o,tail19.data.o,ov_SC04_018_jr_80186570.o,tail20.data.o,ov_SC04_018_jr_801878E8.o,ov_SC04_018_jr_80188E1C.o,ov_SC04_018_jr_8018CC40.o,tail21.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_SC04_018/ov_SC04_018.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
build/src/ov_SC04_018/ov_SC04_018_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
build/src/ov_SC04_018/ov_SC04_018_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
@@ -432,6 +433,7 @@ build/src/ov_SC04_018/ov_SC04_018_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (
build/src/ov_SC04_018/ov_SC04_018_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
build/src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
build/src/ov_SC04_018/ov_SC04_018_jr_801878E8.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38
build/src/ov_SC04_018/ov_SC04_018_jr_80188E1C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC04_018/ov_SC04_018_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
ov_SC04_018_CHECK_SHA := config/check.ov_SC04_018.sha
ov_SC04_018_SYMBOLS := config/symbols.ov_SC04_018.txt
@@ -1811,7 +1813,7 @@ build/src/ov_SC03_089/ov_SC03_089_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (
build/src/ov_SC03_089/ov_SC03_089_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC03_089/ov_SC03_089_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC03_089/ov_SC03_089_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
build/src/ov_SC03_089/ov_SC03_089_jr_8017CA80.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC03_089/ov_SC03_089_jr_8017CA80.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x38
build/src/ov_SC03_089/ov_SC03_089_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
ov_SC03_089_CHECK_SHA := config/check.ov_SC03_089.sha
ov_SC03_089_SYMBOLS := config/symbols.ov_SC03_089.txt
@@ -1941,7 +1943,7 @@ ov_SC03_093_ELF := $(ov_SC03_093_OUT).elf
ov_SC03_093_MAPFILE := $(ov_SC03_093_OUT).map
ov_SC03_093_LD_SCRIPT := $(ov_SC03_093_OUT).ld
ov_SC03_093_SPLAT_YAML := config/splat.ov_SC03_093.yaml
ov_SC03_093_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_093.o,ov_SC03_093_jr_8012ACE0.o,tail2.data.o,ov_SC03_093_jr_80135888.o,tail3.data.o,ov_SC03_093_jr_80135A4C.o,tail4.data.o,ov_SC03_093_jr_80135D20.o,tail5.data.o,ov_SC03_093_jr_801380E0.o,ov_SC03_093_o0c.o,tail6.data.o,ov_SC03_093_jr_8013F350.o,tail7.data.o,ov_SC03_093_jr_8013FFD8.o,tail8.data.o,ov_SC03_093_jr_80140608.o,tail9.data.o,ov_SC03_093_jr_8015444C.o,ov_SC03_093_jr_80154C24.o,ov_SC03_093_jr_801588CC.o,ov_SC03_093_jr_80159C84.o,tail10.data.o,ov_SC03_093_jr_8015A3C8.o,tail11.data.o,ov_SC03_093_jr_8015AE2C.o,tail12.data.o,ov_SC03_093_jr_8015C32C.o,tail13.data.o,ov_SC03_093_jr_8016AB6C.o,tail14.data.o,ov_SC03_093_jr_80171B4C.o,ov_SC03_093_jr_801734BC.o,tail15.data.o,ov_SC03_093_jr_801789AC.o,ov_SC03_093_jr_80178D40.o,tail16.data.o,ov_SC03_093_jr_8017A4AC.o,tail17.data.o,ov_SC03_093_jr_8017AE2C.o,ov_SC03_093_jr_8017D898.o,ov_SC03_093_jr_801825B8.o,tail18.data.o,ov_SC03_093_jr_801859DC.o,tail19.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_SC03_093_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_093.o,ov_SC03_093_jr_8012ACE0.o,tail2.data.o,ov_SC03_093_jr_80135888.o,tail3.data.o,ov_SC03_093_jr_80135A4C.o,tail4.data.o,ov_SC03_093_jr_80135D20.o,tail5.data.o,ov_SC03_093_jr_801380E0.o,ov_SC03_093_o0c.o,tail6.data.o,ov_SC03_093_jr_8013F350.o,tail7.data.o,ov_SC03_093_jr_8013FFD8.o,tail8.data.o,ov_SC03_093_jr_80140608.o,tail9.data.o,ov_SC03_093_jr_8015444C.o,ov_SC03_093_jr_80154C24.o,ov_SC03_093_jr_801588CC.o,ov_SC03_093_jr_80159C84.o,tail10.data.o,ov_SC03_093_jr_8015A3C8.o,tail11.data.o,ov_SC03_093_jr_8015AE2C.o,tail12.data.o,ov_SC03_093_jr_8015C32C.o,tail13.data.o,ov_SC03_093_jr_8016AB6C.o,tail14.data.o,ov_SC03_093_jr_80171B4C.o,ov_SC03_093_jr_801734BC.o,tail15.data.o,ov_SC03_093_jr_801789AC.o,ov_SC03_093_jr_80178D40.o,tail16.data.o,ov_SC03_093_jr_8017A4AC.o,tail17.data.o,ov_SC03_093_jr_8017AE2C.o,ov_SC03_093_jr_8017D898.o,ov_SC03_093_jr_801825B8.o,ov_SC03_093_jr_801859DC.o,tail18.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_SC03_093/ov_SC03_093.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
build/src/ov_SC03_093/ov_SC03_093_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
build/src/ov_SC03_093/ov_SC03_093_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
@@ -1955,6 +1957,7 @@ build/src/ov_SC03_093/ov_SC03_093_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (
build/src/ov_SC03_093/ov_SC03_093_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC03_093/ov_SC03_093_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
build/src/ov_SC03_093/ov_SC03_093_jr_8017D898.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x38
build/src/ov_SC03_093/ov_SC03_093_jr_801825B8.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
build/src/ov_SC03_093/ov_SC03_093_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
ov_SC03_093_CHECK_SHA := config/check.ov_SC03_093.sha
ov_SC03_093_SYMBOLS := config/symbols.ov_SC03_093.txt
@@ -2408,7 +2411,7 @@ ov_SC03_108_ELF := $(ov_SC03_108_OUT).elf
ov_SC03_108_MAPFILE := $(ov_SC03_108_OUT).map
ov_SC03_108_LD_SCRIPT := $(ov_SC03_108_OUT).ld
ov_SC03_108_SPLAT_YAML := config/splat.ov_SC03_108.yaml
ov_SC03_108_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_108.o,ov_SC03_108_jr_8012ACE0.o,tail2.data.o,ov_SC03_108_jr_80135888.o,tail3.data.o,ov_SC03_108_jr_80135A4C.o,tail4.data.o,ov_SC03_108_jr_80135D20.o,tail5.data.o,ov_SC03_108_jr_801380E0.o,ov_SC03_108_o0c.o,tail6.data.o,ov_SC03_108_jr_8013F350.o,tail7.data.o,ov_SC03_108_jr_8013FFD8.o,tail8.data.o,ov_SC03_108_jr_80140608.o,tail9.data.o,ov_SC03_108_jr_8015444C.o,ov_SC03_108_jr_80154C24.o,ov_SC03_108_jr_801588CC.o,ov_SC03_108_jr_80159C84.o,tail10.data.o,ov_SC03_108_jr_8015A3C8.o,tail11.data.o,ov_SC03_108_jr_8015AE2C.o,tail12.data.o,ov_SC03_108_jr_8015C32C.o,tail13.data.o,ov_SC03_108_jr_8016AB6C.o,tail14.data.o,ov_SC03_108_jr_80171B4C.o,ov_SC03_108_jr_801734BC.o,tail15.data.o,ov_SC03_108_jr_801789AC.o,ov_SC03_108_jr_80178D40.o,tail16.data.o,ov_SC03_108_jr_8017A4AC.o,tail17.data.o,ov_SC03_108_jr_8017AE2C.o,ov_SC03_108_jr_8017BEBC.o,tail18.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_SC03_108_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_108.o,ov_SC03_108_jr_8012ACE0.o,tail2.data.o,ov_SC03_108_jr_80135888.o,tail3.data.o,ov_SC03_108_jr_80135A4C.o,tail4.data.o,ov_SC03_108_jr_80135D20.o,tail5.data.o,ov_SC03_108_jr_801380E0.o,ov_SC03_108_o0c.o,tail6.data.o,ov_SC03_108_jr_8013F350.o,tail7.data.o,ov_SC03_108_jr_8013FFD8.o,tail8.data.o,ov_SC03_108_jr_80140608.o,tail9.data.o,ov_SC03_108_jr_8015444C.o,ov_SC03_108_jr_80154C24.o,ov_SC03_108_jr_801588CC.o,ov_SC03_108_jr_80159C84.o,tail10.data.o,ov_SC03_108_jr_8015A3C8.o,tail11.data.o,ov_SC03_108_jr_8015AE2C.o,tail12.data.o,ov_SC03_108_jr_8015C32C.o,tail13.data.o,ov_SC03_108_jr_8016AB6C.o,tail14.data.o,ov_SC03_108_jr_80171B4C.o,ov_SC03_108_jr_801734BC.o,tail15.data.o,ov_SC03_108_jr_801789AC.o,ov_SC03_108_jr_80178D40.o,tail16.data.o,ov_SC03_108_jr_8017A4AC.o,tail17.data.o,ov_SC03_108_jr_8017AE2C.o,ov_SC03_108_jr_8017BEBC.o,tail18.data.o,ov_SC03_108_jr_8017F83C.o,tail19.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_SC03_108/ov_SC03_108.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
build/src/ov_SC03_108/ov_SC03_108_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
build/src/ov_SC03_108/ov_SC03_108_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
@@ -4282,7 +4285,7 @@ ov_SC06_018_ELF := $(ov_SC06_018_OUT).elf
ov_SC06_018_MAPFILE := $(ov_SC06_018_OUT).map
ov_SC06_018_LD_SCRIPT := $(ov_SC06_018_OUT).ld
ov_SC06_018_SPLAT_YAML := config/splat.ov_SC06_018.yaml
ov_SC06_018_JTBL_INTERLEAVE := --order tail.data.o,ov_SC06_018.o,ov_SC06_018_jr_8012ACE0.o,tail2.data.o,ov_SC06_018_jr_80135888.o,tail3.data.o,ov_SC06_018_jr_80135A4C.o,tail4.data.o,ov_SC06_018_jr_80135D20.o,tail5.data.o,ov_SC06_018_jr_801380E0.o,ov_SC06_018_o0c.o,tail6.data.o,ov_SC06_018_jr_8013F350.o,tail7.data.o,ov_SC06_018_jr_8013FFD8.o,tail8.data.o,ov_SC06_018_jr_80140608.o,tail9.data.o,ov_SC06_018_jr_8015444C.o,ov_SC06_018_jr_80154C24.o,ov_SC06_018_jr_801588CC.o,ov_SC06_018_jr_80159C84.o,tail10.data.o,ov_SC06_018_jr_8015A3C8.o,tail11.data.o,ov_SC06_018_jr_8015AE2C.o,tail12.data.o,ov_SC06_018_jr_8015C32C.o,tail13.data.o,ov_SC06_018_jr_8016AB6C.o,tail14.data.o,ov_SC06_018_jr_80171B4C.o,ov_SC06_018_jr_801734BC.o,tail15.data.o,ov_SC06_018_jr_801789AC.o,ov_SC06_018_jr_80178D40.o,tail16.data.o,ov_SC06_018_jr_8017A4AC.o,tail17.data.o,ov_SC06_018_jr_8017AE2C.o,ov_SC06_018_jr_8017C24C.o,ov_SC06_018_jr_80186270.o,tail18.data.o,ov_SC06_018_jr_80187AEC.o,tail19.data.o,ov_SC06_018_jr_8019059C.o,tail20.data.o,ov_SC06_018_jr_80191C50.o,tail21.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_SC06_018_JTBL_INTERLEAVE := --order tail.data.o,ov_SC06_018.o,ov_SC06_018_jr_8012ACE0.o,tail2.data.o,ov_SC06_018_jr_80135888.o,tail3.data.o,ov_SC06_018_jr_80135A4C.o,tail4.data.o,ov_SC06_018_jr_80135D20.o,tail5.data.o,ov_SC06_018_jr_801380E0.o,ov_SC06_018_o0c.o,tail6.data.o,ov_SC06_018_jr_8013F350.o,tail7.data.o,ov_SC06_018_jr_8013FFD8.o,tail8.data.o,ov_SC06_018_jr_80140608.o,tail9.data.o,ov_SC06_018_jr_8015444C.o,ov_SC06_018_jr_80154C24.o,ov_SC06_018_jr_801588CC.o,ov_SC06_018_jr_80159C84.o,tail10.data.o,ov_SC06_018_jr_8015A3C8.o,tail11.data.o,ov_SC06_018_jr_8015AE2C.o,tail12.data.o,ov_SC06_018_jr_8015C32C.o,tail13.data.o,ov_SC06_018_jr_8016AB6C.o,tail14.data.o,ov_SC06_018_jr_80171B4C.o,ov_SC06_018_jr_801734BC.o,tail15.data.o,ov_SC06_018_jr_801789AC.o,ov_SC06_018_jr_80178D40.o,tail16.data.o,ov_SC06_018_jr_8017A4AC.o,tail17.data.o,ov_SC06_018_jr_8017AE2C.o,ov_SC06_018_jr_8017C24C.o,ov_SC06_018_jr_80186270.o,tail18.data.o,ov_SC06_018_jr_80187AEC.o,tail19.data.o,ov_SC06_018_jr_8018FF98.o,ov_SC06_018_jr_8019059C.o,tail20.data.o,ov_SC06_018_jr_80191C50.o,tail21.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_SC06_018/ov_SC06_018.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
build/src/ov_SC06_018/ov_SC06_018_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
build/src/ov_SC06_018/ov_SC06_018_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
@@ -4296,6 +4299,7 @@ build/src/ov_SC06_018/ov_SC06_018_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (
build/src/ov_SC06_018/ov_SC06_018_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_SC06_018/ov_SC06_018_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
build/src/ov_SC06_018/ov_SC06_018_jr_8017C24C.o: JTBL_PADS := 0,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x38
build/src/ov_SC06_018/ov_SC06_018_jr_8019059C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x28
build/src/ov_SC06_018/ov_SC06_018_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
ov_SC06_018_CHECK_SHA := config/check.ov_SC06_018.sha
ov_SC06_018_SYMBOLS := config/symbols.ov_SC06_018.txt
@@ -4926,7 +4930,7 @@ ov_MAIN_012_ELF := $(ov_MAIN_012_OUT).elf
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,ov_MAIN_012_jr_80131340.o,tail2.data.o,ov_MAIN_012_jr_80135A4C.o,tail3.data.o,ov_MAIN_012_jr_80135EB0.o,tail4.data.o,ov_MAIN_012_jr_801380E0.o,tail5.data.o,ov_MAIN_012_jr_8013F350.o,tail6.data.o,ov_MAIN_012_jr_801549F8.o,ov_MAIN_012_jr_801555F4.o,tail7.data.o,ov_MAIN_012_jr_801594E8.o,ov_MAIN_012_jr_80159C84.o,tail8.data.o,ov_MAIN_012_jr_8015A3C8.o,tail9.data.o,ov_MAIN_012_jr_8016AE5C.o,tail10.data.o,ov_MAIN_012_jr_80171B4C.o,tail11.data.o,ov_MAIN_012_jr_801789AC.o,tail12.data.o,ov_MAIN_012_jr_8017CF3C.o,tail13.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
ov_MAIN_012_JTBL_INTERLEAVE := --order tail.data.o,ov_MAIN_012.o,ov_MAIN_012_jr_80131340.o,tail2.data.o,ov_MAIN_012_jr_80135A4C.o,tail3.data.o,ov_MAIN_012_jr_80135EB0.o,tail4.data.o,ov_MAIN_012_jr_801380E0.o,tail5.data.o,ov_MAIN_012_jr_8013F350.o,tail6.data.o,ov_MAIN_012_jr_801549F8.o,ov_MAIN_012_jr_801555F4.o,tail7.data.o,ov_MAIN_012_jr_801594E8.o,ov_MAIN_012_jr_80159C84.o,tail8.data.o,ov_MAIN_012_jr_8015A3C8.o,tail9.data.o,ov_MAIN_012_jr_8016AE5C.o,tail10.data.o,ov_MAIN_012_jr_80171B4C.o,tail11.data.o,ov_MAIN_012_jr_801789AC.o,tail12.data.o,ov_MAIN_012_jr_8017C3BC.o,tail13.data.o,ov_MAIN_012_jr_8017CA18.o,tail14.data.o,ov_MAIN_012_jr_8017CF3C.o,tail15.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
build/src/ov_MAIN_012/ov_MAIN_012.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14,+0xdc
build/src/ov_MAIN_012/ov_MAIN_012_jr_80131340.o: JTBL_PADS := 0,0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14,+0x2c
build/src/ov_MAIN_012/ov_MAIN_012_jr_80135A4C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
@@ -4937,6 +4941,7 @@ build/src/ov_MAIN_012/ov_MAIN_012_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (
build/src/ov_MAIN_012/ov_MAIN_012_jr_8015A3C8.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x40,+0x60
build/src/ov_MAIN_012/ov_MAIN_012_jr_80171B4C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
build/src/ov_MAIN_012/ov_MAIN_012_jr_801789AC.o: JTBL_PADS := 0,0,0,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18,+0x190,+0x220,+0x2b0
build/src/ov_MAIN_012/ov_MAIN_012_jr_8017C3BC.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38
build/src/ov_MAIN_012/ov_MAIN_012_jr_8017CF3C.o: JTBL_PADS := 0,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x28,+0x50
ov_MAIN_012_CHECK_SHA := config/check.ov_MAIN_012.sha
ov_MAIN_012_SYMBOLS := config/symbols.ov_MAIN_012.txt
+7 -1
View File
@@ -107,6 +107,8 @@ segments:
- [0x42d04, c, ov_MAIN_012_jr_8016AE5C]
- [0x499f4, c, ov_MAIN_012_jr_80171B4C]
- [0x50854, c, ov_MAIN_012_jr_801789AC]
- [0x54264, c, ov_MAIN_012_jr_8017C3BC]
- [0x548c0, c, ov_MAIN_012_jr_8017CA18]
- [0x54de4, c, ov_MAIN_012_jr_8017CF3C]
- [0x561e0, data, tail]
- [0x5abd0, .rodata, ov_MAIN_012] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
@@ -134,8 +136,12 @@ segments:
- [0x5b8b0, data, tail11]
- [0x5ba40, .rodata, ov_MAIN_012_jr_801789AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5bd04, data, tail12]
- [0x5be44, .rodata, ov_MAIN_012_jr_8017C3BC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5beb0, data, tail13]
- [0x5beb4, .rodata, ov_MAIN_012_jr_8017CA18] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5bee8, data, tail14]
- [0x5beec, .rodata, ov_MAIN_012_jr_8017CF3C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x5bf58, data, tail13]
- [0x5bf58, data, tail15]
- [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
+2
View File
@@ -121,6 +121,7 @@ segments:
- [0x52354, c, ov_SC01_005_jr_8017A4AC]
- [0x52cd4, c, ov_SC01_005_jr_8017AE2C]
- [0x541e8, c, ov_SC01_005_jr_8017C340]
- [0x569ec, c, ov_SC01_005_jr_8017EB44]
- [0x56c04, c, ov_SC01_005_jr_8017ED5C]
- [0x5a20c, data, tail]
- [0xa2d00, .rodata, ov_SC01_005] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
@@ -165,6 +166,7 @@ segments:
- [0xa3e20, .rodata, ov_SC01_005_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa3e34, .rodata, ov_SC01_005_jr_8017C340] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa3e54, data, tail18]
- [0xa435c, .rodata, ov_SC01_005_jr_8017EB44] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa4384, .rodata, ov_SC01_005_jr_8017ED5C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa43ac, data, tail19]
- [0xA5F08, bin, trailing] # final 1 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
+8 -2
View File
@@ -86,9 +86,11 @@ segments:
- [0x52cd4, c, ov_SC01_077_jr_8017AE2C]
- [0x58a0c, c, ov_SC01_077_jr_80180B64]
- [0x58ee4, c, ov_SC01_077_jr_8018103C]
- [0x59a8c, c, ov_SC01_077_jr_80181BE4]
- [0x59f84, c, ov_SC01_077_jr_801820DC]
- [0x5a110, c, ov_SC01_077_jr_80182268]
- [0x5ad24, c, ov_SC01_077_jr_80182E7C]
- [0x5b1cc, c, ov_SC01_077_jr_80183324]
- [0x5b998, c, ov_SC01_077_jr_80183AF0]
- [0x5ba54, c, ov_SC01_077_jr_80183BAC]
- [0x5bb9c, c, ov_SC01_077_jr_80183CF4]
@@ -145,14 +147,18 @@ segments:
- [0xb0fc0, data, tail17]
- [0xb1000, .rodata, ov_SC01_077_jr_8018103C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb1078, data, tail18]
- [0xb1098, .rodata, ov_SC01_077_jr_80181BE4] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb10ac, data, tail19]
- [0xb1128, .rodata, ov_SC01_077_jr_801820DC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb1148, .rodata, ov_SC01_077_jr_80182268] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb11a8, .rodata, ov_SC01_077_jr_80182E7C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb11c8, data, tail19]
- [0xb11c8, data, tail20]
- [0xb11e8, .rodata, ov_SC01_077_jr_80183324] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb1288, data, tail21]
- [0xb12a8, .rodata, ov_SC01_077_jr_80183AF0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb12c8, .rodata, ov_SC01_077_jr_80183BAC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb1308, .rodata, ov_SC01_077_jr_80183CF4] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xb1328, data, tail20]
- [0xb1328, data, tail22]
- [0xB29D4, bin, trailing] # final 3 bytes (EOF 0xB29D7 not word-aligned; spimdisasm drops
# a trailing partial word and a <4-byte `data` carve emits nothing,
# so use `bin` = raw .incbin, byte-exact). Word-aligned overlays omit this.
+1 -1
View File
@@ -165,7 +165,7 @@ segments:
- [0x9d23c, data, tail17]
- [0x9d240, .rodata, ov_SC03_089_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9d254, .rodata, ov_SC03_089_jr_8017CA80] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9d28c, data, tail18]
- [0x9d2a0, data, tail18]
- [0x9d2a8, .rodata, ov_SC03_089_jr_80185E50] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9d2c0, .rodata, ov_SC03_089_jr_80189168] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x9d2d4, data, tail19]
+1 -2
View File
@@ -166,9 +166,8 @@ segments:
- [0xa2da4, .rodata, ov_SC03_093_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa2db8, .rodata, ov_SC03_093_jr_8017D898] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa2e04, .rodata, ov_SC03_093_jr_801825B8] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa2e1c, data, tail18]
- [0xa2e34, .rodata, ov_SC03_093_jr_801859DC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xa2e48, data, tail19]
- [0xa2e48, data, tail18]
- [0xA4584, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
- [0xA4587] # 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
+3
View File
@@ -121,6 +121,7 @@ segments:
- [0x52354, c, ov_SC03_108_jr_8017A4AC]
- [0x52cd4, c, ov_SC03_108_jr_8017AE2C]
- [0x53d64, c, ov_SC03_108_jr_8017BEBC]
- [0x576e4, c, ov_SC03_108_jr_8017F83C]
- [0x58afc, data, tail]
- [0x77244, .rodata, ov_SC03_108] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x77320, .rodata, ov_SC03_108_jr_8012ACE0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
@@ -164,6 +165,8 @@ segments:
- [0x78364, .rodata, ov_SC03_108_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x78378, .rodata, ov_SC03_108_jr_8017BEBC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x78398, data, tail18]
- [0x783a0, .rodata, ov_SC03_108_jr_8017F83C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0x783b4, data, tail19]
- [0x7994C, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
- [0x7994F] # 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
+1 -2
View File
@@ -173,9 +173,8 @@ segments:
- [0xbd778, data, tail20]
- [0xbd7ec, .rodata, ov_SC04_018_jr_801878E8] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xbd844, .rodata, ov_SC04_018_jr_80188E1C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xbd864, data, tail21]
- [0xbd8a0, .rodata, ov_SC04_018_jr_8018CC40] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xbd8b8, data, tail22]
- [0xbd8b8, data, tail21]
- [0xBF9CC, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
- [0xBF9CF] # 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
+3 -1
View File
@@ -123,6 +123,7 @@ segments:
- [0x540f4, c, ov_SC06_018_jr_8017C24C]
- [0x5e118, c, ov_SC06_018_jr_80186270]
- [0x5f994, c, ov_SC06_018_jr_80187AEC]
- [0x67e40, c, ov_SC06_018_jr_8018FF98]
- [0x68444, c, ov_SC06_018_jr_8019059C]
- [0x69af8, c, ov_SC06_018_jr_80191C50]
- [0x6b430, data, tail]
@@ -171,8 +172,9 @@ segments:
- [0xab980, data, tail18]
- [0xab998, .rodata, ov_SC06_018_jr_80187AEC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xab9b0, data, tail19]
- [0xab9cc, .rodata, ov_SC06_018_jr_8018FF98] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xab9f4, .rodata, ov_SC06_018_jr_8019059C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xaba1c, data, tail20]
- [0xaba30, data, tail20]
- [0xaba4c, .rodata, ov_SC06_018_jr_80191C50] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
- [0xaba7c, data, tail21]
- [0xADA44, bin, trailing] # final 3 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
-130
View File
@@ -5826,133 +5826,3 @@ void func_8017C364(void) {
aD80115112_8017C364++;
}
}
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_801789AC", func_8017C3BC);
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_801789AC", func_8017CA18);
#include "common.h"
/* func_8017CBC8 (ov_MAIN_012 / jr_801789AC) — 188 ins, byte-exact vs
* asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_801789AC/func_8017CBC8.s
*
* Sprite/quad draw dispatcher: builds an OT chain for one "part list" entry.
*
* Idioms that were load-bearing here (feed these back into the cookbook):
* 1) `dim`/`dim2`/`dim3` are DELIBERATE copies of `flag`. The target keeps
* `flag` in $s7 and copies it into $s6 in each loop preheader and into $s0
* for the tail. A plain `x = flag;` written in the same basic block as its
* use is killed by cse; it survives only when a multi-pred label separates
* def from use. So: the loop-1 copy is written at the END of the outer
* body (loop.c hoists it into the preheader), the loop-2 copy is written in
* the preheader itself, and the tail copy needs a hard-register pin
* (`register s32 dim3 __asm__("$16")`) because nothing separates it from
* its uses. Same shape as the matched sibling func_8013FAF8 (ov_SC06_008),
* which also needed a pin for exactly this call pair.
* 2) `bp = sp18;` exists only to fix the ORDER of the two loop-1 preheader
* insns. loop.c emits hoisted invariants in body order; writing the
* sp18-relative store address as an explicit pointer makes `addiu $s5,$sp,0x18`
* the FIRST movable, so the `dim` copy lands after it (as in the target).
* 3) The `do { } while (0)` around the loop-1 call is a REGISTER-ALLOCATION
* lever, not dead syntax. flow.c weights REG_N_REFS by loop_depth; the
* extra (never-iterating) loop note gives `ot` 18 weighted refs instead of
* 16, which raises its global-alloc priority above `s` (21 refs / 159 insns)
* and lands the a0/a1 params in $s2/$s3 exactly as the target does.
* `mode` is hoisted out of the wrapper so `dim` does NOT get the same +1
* (that would swap $s5/$s6 between `bp` and `dim`).
* 4) Low half of sp60[0] uses `& 0xFFFF`, NOT a (u16) cast: the mask keeps the
* operands in SImode so both halves load with `lh`; a (u16) cast makes
* gcc-2.7.2 emit `lhu`.
*/
extern u16 D_8011511A;
extern u8 D_80182774[];
extern s32 *D_801826EC[];
extern s32 func_80024054(u8 *, u8 *);
extern s32 func_800D2650(s32, u8 *, s16, s16, s32, s32);
extern s32 func_800D27DC(s32, s32, void *, s16, s32);
extern s32 func_800D29F8(s32, s32, void *, s16, s32);
extern s32 func_8017CEB8(s32, s16, s16, s16, s32 *);
s32 func_8017CBC8(s32 ot, u8 *s, s16 c) {
u8 sp18[72];
s32 sp60[5];
s32 sp78[8];
s32 flag;
s32 dim;
s32 dim2;
register s32 dim3 __asm__("$16");
s32 t;
s16 i;
s16 k;
s32 *p;
u8 *bp;
s16 *q;
s32 r;
s32 mode;
if (c == 0) {
flag = 0;
} else {
flag = -(D_8011511A != c) & 0xFF;
}
t = *(s32 *)(s + 0x14);
if (t < 0) {
func_80024054((u8 *)t, sp18);
ot = func_800D2650(ot, sp18, *(s16 *)(s + 0x10), *(s16 *)(s + 0x12), 1,
flag ? 0x585858 : 0x808080);
} else {
p = D_801826EC[t];
for (k = 0; k < D_80182774[*(s32 *)(s + 0x14)]; k++) {
bp = sp18;
dim = flag;
for (i = 0; i < 5; i++) {
if (i == 0) {
sp60[0] = (((s16 *)p)[0] + *(s16 *)(s + 0x10)) & 0xFFFF |
((((s16 *)p)[1] + *(s16 *)(s + 0x12)) << 16);
} else {
*(s32 *)(bp + 0x48 + i * 4) = p[i];
}
}
mode = dim ? 3 : 2;
do {
ot = func_800D27DC(mode, ot, sp60, 1, 0);
} while (0);
p += 5;
}
}
i = 0;
q = *(s16 **)(s + 0x18);
dim2 = flag;
for (;;) {
r = func_8017CEB8(*(s32 *)(s + 0x1C), *(s16 *)s, c, i++, sp78);
if (r == 0) {
break;
}
if (r < 0) {
func_80024054((u8 *)r, sp18);
if (dim2 != 0) {
sp78[0] = 0x585858;
}
ot = func_800D2650(ot, sp18, q[0], q[1], 1, sp78[0]);
} else {
p = D_801826EC[r];
*p = (u16)q[0] | (q[1] << 16);
ot = func_800D27DC(dim2 ? 3 : 2, ot, p, 1, 0);
}
q += 2;
}
dim3 = flag;
return func_800D29F8(dim3,
func_800D27DC(dim3 != 0, ot, (void *)*(s32 *)(s + 4),
*(s16 *)(s + 0xC), 0),
(void *)*(s32 *)(s + 8), *(s16 *)(s + 0xE), 0);
}
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_801789AC", func_8017CEB8);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+57 -1
View File
@@ -4357,7 +4357,63 @@ s32 *func_8017DD28(s32 *out) {
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_8017CF3C", func_8017DF18);
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_8017CF3C", func_8017DF40);
#include "common.h"
/* 152-byte engine block, copied whole (struct assignment -> 9x16B block move + 8B tail).
* Uniquely suffixed: the host TU already sees `Blk152` from engine_types.h, and a C89
* re-typedef of a visible name is a redefinition error. Same layout, same codegen. */
typedef struct { u32 w[38]; } Blk152_8017DF40;
/* ALIGN-1 4-byte element => lwl/lwr + swl/swr (cookbook §160a); a u32[] loop is wrong. */
typedef struct { u8 b[4]; } Blk4_8017DF40;
extern u8 D_80078E78[]; /* live: 152-byte block (host TU declares this identically) */
extern u16 D_800A6588[]; /* live: u16[64] */
extern u8 D_800AE648[]; /* live: u8[64] */
extern u8 D_800BA1B8[]; /* live: u8[256] */
extern u8 D_800BA2B8[]; /* live: 4-byte struct[24], align 1 */
extern u8 D_8018581C[]; /* shadow: +0x000 */
extern u16 D_801858B4[]; /* shadow: +0x098 */
extern u8 D_80185934[]; /* shadow: +0x118 */
extern u8 D_80185974[]; /* shadow: +0x158 */
extern u8 D_80185A74[]; /* shadow: +0x258 */
/* Param is declared s32 by the host TU's file-scope prototype (:3695); the true test is
* 16-bit (`sll $a0,$a0,16 ; bnez`, no sra), so the truncation lives in the test instead. */
void func_8017DF40(s32 arg0) {
s16 i;
if ((s16)arg0 == 0) {
*(Blk152_8017DF40 *)D_80078E78 = *(Blk152_8017DF40 *)D_8018581C;
for (i = 0; i < 64; i++) {
D_800A6588[i] = D_801858B4[i];
}
for (i = 0; i < 64; i++) {
D_800AE648[i] = D_80185934[i];
}
for (i = 0; i < 256; i++) {
D_800BA1B8[i] = D_80185974[i];
}
for (i = 0; i < 24; i++) {
((Blk4_8017DF40 *)D_800BA2B8)[i] = ((Blk4_8017DF40 *)D_80185A74)[i];
}
} else {
*(Blk152_8017DF40 *)D_8018581C = *(Blk152_8017DF40 *)D_80078E78;
for (i = 0; i < 64; i++) {
D_801858B4[i] = D_800A6588[i];
}
for (i = 0; i < 64; i++) {
D_80185934[i] = D_800AE648[i];
}
for (i = 0; i < 256; i++) {
D_80185974[i] = D_800BA1B8[i];
}
for (i = 0; i < 24; i++) {
((Blk4_8017DF40 *)D_80185A74)[i] = ((Blk4_8017DF40 *)D_800BA2B8)[i];
}
}
}
INCLUDE_ASM("asm/ov_MAIN_012/nonmatchings/ov_MAIN_012_jr_8017CF3C", func_8017E22C);
@@ -4097,6 +4097,3 @@ s32 *func_8017E978(s32 *ot, Panel_8017E978 *w0, s16 idx) {
func_800D27DC(flag4 != 0, ot, w->f4, w->fC, 0),
w->f8, w->fE, 0);
}
INCLUDE_ASM("asm/ov_SC01_005/nonmatchings/ov_SC01_005_jr_8017C340", func_8017EB44);
File diff suppressed because it is too large Load Diff
+128 -1
View File
@@ -3277,7 +3277,134 @@ INCLUDE_ASM("asm/ov_SC01_005/nonmatchings/ov_SC01_005_jr_8017ED5C", func_8018178
INCLUDE_ASM("asm/ov_SC01_005/nonmatchings/ov_SC01_005_jr_8017ED5C", func_80181894);
INCLUDE_ASM("asm/ov_SC01_005/nonmatchings/ov_SC01_005_jr_8017ED5C", func_80181B00);
#include "common.h"
extern s32 func_800149E0(s32 a0);
extern s32 func_80014B10(s32 a0);
extern void func_8018203C(s32 a0, s32 a1);
extern void func_8012A828(s32 a0, void *a1);
extern void func_801820F8(s32 a0);
extern void func_8002D4C8(s32 a0, s32 a1);
extern void func_8012B260(s32 a0);
extern void RotMatrixYXZ(void *a0, void *a1);
extern void func_8004974C(void *a0, void *a1);
extern void ApplyMatrixSV(void *a0, void *a1, void *a2);
extern u8 D_801CDA10[];
extern s16 D_801C3880[];
extern s16 D_801C38D8[];
void func_80181B00(s32 a0) {
s32 m[8];
u16 sv[4];
s32 trig;
s32 held;
if (*(s16 *)(a0 + 0xFC) != 0 && *(u16 *)(a0 + 0x2) == 1) {
trig = func_800149E0(0);
held = func_80014B10(0);
} else {
trig = 0;
held = 0;
}
if (*(s16 *)(a0 + 0x10A) == 0) {
if (held & 0x1000) {
if ((s16)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) += 0x40) > 0x300) {
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0x300;
}
}
if (held & 0x4000) {
if ((s16)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) -= 0x40) < -0x300) {
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = -0x300;
}
}
if (held & 0x8000) {
if ((s16)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) -= 0x40) < -0x300) {
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) = -0x300;
}
}
if (held & 0x2000) {
if ((s16)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += 0x40) > 0x300) {
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) = 0x300;
}
}
} else {
if (*(s16 *)(a0 + 0x106) != 0 &&
((*(u16 *)(a0 + 0x72) & 0x4000) != 0 || *(s16 *)(a0 + 0x98) == 0)) {
func_8018203C(a0, 1);
func_8012A828(a0, D_801CDA10);
func_801820F8(a0);
*(s16 *)(a0 + 0x106) = 0;
}
if (held & 0x1000) {
if ((s16)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) += 0x40) > 0x380) {
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0x380;
}
}
if (held & 0x4000) {
if ((s16)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) -= 0x40) < -0x380) {
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = -0x380;
}
}
if (held & 0x8000) {
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) -= 0x40;
}
if (held & 0x2000) {
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += 0x40;
}
if (held & 0xC) {
if ((s16)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) += 0x80) > 0x1800) {
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x18) = 0x1800;
}
}
if (held & 0x3) {
if ((s16)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) -= 0x80) < 0x1000) {
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x18) = 0x1000;
}
}
if ((trig & 0x80) && *(s16 *)(a0 + 0x106) == 0) {
s16 snd;
func_8018203C(a0, 2);
func_8012A828(a0, D_801CDA10);
func_801820F8(a0);
*(s16 *)(a0 + 0x106) = 1;
snd = D_801C3880[*(s16 *)(a0 + 0x70)];
if (snd != 0) {
func_8002D4C8((u16)snd, 0);
}
}
if ((trig & 0x40) && *(s16 *)(a0 + 0x106) == 0) {
s16 snd;
func_8018203C(a0, 3);
func_8012A828(a0, D_801CDA10);
func_801820F8(a0);
*(s16 *)(a0 + 0x106) = 1;
snd = D_801C38D8[*(s16 *)(a0 + 0x70)];
if (snd != 0) {
func_8002D4C8((u16)snd, 0);
}
}
if (trig & 0x100) {
*(s32 *)(*(s32 *)(a0 + 0xD8) + 0x4) ^= 0x80000000;
}
}
{
s32 p = *(s32 *)(a0 + 0x20);
*(s16 *)(p + 0x1A) = *(s16 *)(p + 0x1C) = *(u16 *)(p + 0x18);
}
RotMatrixYXZ((void *)(*(s32 *)(a0 + 0x20) + 0x10), (void *)m);
func_8004974C((void *)m, (void *)(*(s32 *)(a0 + 0x20) + 0x34));
sv[0] = 0;
sv[1] = (*(s16 *)(a0 + 0x102) * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12;
sv[2] = 0;
ApplyMatrixSV((void *)(*(s32 *)(a0 + 0x20) + 0x34), (void *)sv, (void *)sv);
*(s16 *)(a0 + 0x6) = -sv[0];
*(s16 *)(a0 + 0xA) = (*(u16 *)(a0 + 0xFA) - 0x400) - sv[1];
*(s16 *)(a0 + 0xE) = -sv[2];
func_8012B260(a0);
}
extern void (*D_801C3A5C[])(void);
@@ -3575,7 +3575,3 @@ void func_80181B9C(s32 param_1) {
func_8012A828(param_1, &D_801B0D50);
*(s32 *)(param_1 + 0x1c) = 0x1e;
}
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077_jr_8018103C", func_80181BE4);
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077_jr_8018103C", func_80181F08);
File diff suppressed because it is too large Load Diff
-36
View File
@@ -3181,39 +3181,3 @@ void func_8018301C(s32 param_1)
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077_jr_80182E7C", func_8018308C);
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077_jr_80182E7C", func_80183324);
INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077_jr_80182E7C", func_80183834);
extern void func_8012E364();
void func_80183A50(void) {
func_8012E364();
}
extern s32 func_8012E470(s32);
extern void func_8012E4C8(s32);
void func_80183A70(s32 arg0) {
if (func_8012E470(arg0)) {
func_8012E4C8(arg0);
}
}
// @class: plumbing
// @stuck: none — MATCH expected (clean structural stub)
extern s32 func_8012BEE8(s32 a0);
extern void func_8012A828(s32 a0, void *a1);
extern unsigned char D_801B09D0;
void func_80183AA8(int param_1)
{
((void (*)(void))func_8012BEE8)();
if (*(int *)(param_1 + 0x1c) == 1) {
func_8012A828(param_1, &D_801B09D0);
}
return;
}
File diff suppressed because it is too large Load Diff
+206 -1
View File
@@ -3188,7 +3188,212 @@ DEFINE_func_80184B00() /* dedup: shared engine-core @0x80184B00 (src/shared) */
INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8018173C", func_80184B14);
INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8018173C", func_80184BD8);
#include "common.h"
typedef struct { s16 vx, vy, vz, pad; } SVEC_84BD8;
extern s32 D_801E873C;
extern s32 D_801E874C;
extern s32 D_801E8010;
extern u16 D_80126B66;
extern u16 D_800B99DC;
extern u8 D_8018B37C[];
extern u8 D_8018B358[];
extern u8 D_800AF648[];
extern void func_80185F8C(void);
extern void func_801852E4(s32 a0);
extern s32 func_8012DB84(void);
extern void func_8002D4C8(s32 a0, s32 a1);
extern s32 func_80185C48(s32 a0, s32 a1);
extern void func_8013C9C4(s32);
extern void func_8018623C(u16 arg0, u16 arg1);
extern void func_8018762C(s32 a0, void *a1);
extern void func_80187354(s32 a0);
extern s32 func_80185D58(s32 a0);
extern s32 func_8012C588(s32 a0, s32 a1);
extern void func_801824CC(void);
extern void func_8004914C(void *a0);
extern void func_800491AC(void *a0);
#define gte_ldv0(r0) __asm__ volatile ( \
"lwc2 $0, 0( %0 );" \
"lwc2 $1, 4( %0 )" \
: \
: "r"( r0 ) )
#define gte_rtps() __asm__ volatile ("nop;nop;rtps")
#define gte_stsz(r0) __asm__ volatile ( \
"swc2 $19, 0( %0 )" \
: \
: "r"( r0 ) \
: "memory" )
void func_80184BD8(s32 p) {
s32 sz[1];
s32 pad[6];
SVEC_84BD8 sv;
s32 q;
s32 q2;
s32 r;
s32 a;
s32 b;
s32 v;
s32 flag;
s32 c;
s16 t;
func_80185F8C();
func_801852E4(p);
if (D_801E873C == 0) {
q = *(s32 *)(p + 0x20);
*(s16 *)(q + 0x12) = *(u16 *)(q + 0x12) + D_801E874C;
if (*(s16 *)(p + 0xE) < (s32)(s16)D_80126B66 + 0x80) {
func_8012DB84();
func_8002D4C8(4, 0x4DF);
func_8002D4C8(4, 0x4E2);
D_801E8010 = 1;
}
if (func_80185C48(p, 1) != 0) {
*(s32 *)(p + 0x18) = 0xFFF46667;
*(s32 *)(p + 0x14) = 0xFFF60000;
*(s32 *)(p + 0x44) = 0;
*(s32 *)(p + 0x48) = 0x3000;
*(s32 *)(p + 0x48) = D_800B99DC + 0x3000;
*(s32 *)(p + 0x4C) = 0;
((void (*)(void *))func_8013C9C4)(D_8018B37C);
((void (*)(s32, s32))func_8018623C)(0x4D7, 0);
sv.vx = *(u16 *)(p + 0x6) - 0xE1;
sv.vy = *(u16 *)(p + 0xA) + 0x50;
sv.vz = *(u16 *)(p + 0xE);
func_8018762C(p, &sv);
sv.vx = *(u16 *)(p + 0x6) + 0xE1;
func_8018762C(p, &sv);
D_801E874C += 8;
func_80187354(p);
return;
}
if (func_80185D58(p) != 1) {
return;
}
*(s32 *)(p + 0x18) = 0xFFF4999A;
*(s32 *)(p + 0x14) = 0xFFF00000;
*(s16 *)(p + 0xDE) = 0;
*(s32 *)(p + 0x44) = 0;
*(s32 *)(p + 0x48) = 0x30000;
*(s32 *)(p + 0x4C) = 0;
*(s16 *)(p + 0x2) = *(u16 *)(p + 0x2) + 1;
return;
}
*(s32 *)(p + 0x1C) -= 1;
q2 = *(s32 *)(p + 0x20);
*(s16 *)(q2 + 0x12) = *(u16 *)(q2 + 0x12) + 0x80;
t = *(u16 *)(p + 0xDC) - 1;
*(s16 *)(p + 0xDC) = t;
if (t == 0) {
*(s16 *)(p + 0xDC) = (D_800B99DC & 3) + 1;
((void (*)(void *))func_8013C9C4)(D_8018B37C);
func_80187354(p);
if ((u16)(*(u16 *)(p + 0xE) + 0x14FF) < 0x29FF && *(s32 *)(p + 0x1C) < 0) {
func_8012C588(0x67, 0);
*(s32 *)(p + 0x1C) = 8;
}
}
if ((*(u16 *)(*(s32 *)(p + 0x20) + 0x12) & 0xF80) == 0x380) {
*(s32 *)(p + 0x18) = 0xFFF46667;
*(s32 *)(p + 0x14) = 0xFFE00000;
*(s32 *)(p + 0x48) = 0x80000;
*(s32 *)(p + 0x44) = 0;
*(s32 *)(p + 0x4C) = 0;
*(s16 *)(p + 0xDE) = 0x100;
*(s16 *)(p + 0x2) = *(u16 *)(p + 0x2) + 1;
return;
}
if (*(s16 *)(p + 0xE) < (s32)(s16)D_80126B66 + 0x80) {
func_8012DB84();
func_8002D4C8(4, 0x4DF);
func_8002D4C8(4, 0x4E2);
D_801E8010 = 1;
}
if (func_80185C48(p, 0) == 0) {
*(s32 *)(p + 0x14) = 0xFFE00000;
*(s16 *)(p + 0xDE) = 0;
*(s32 *)(p + 0x44) = 0;
*(s32 *)(p + 0x48) = 0x40000;
*(s32 *)(p + 0x4C) = 0;
*(s16 *)(p + 0x2) = *(u16 *)(p + 0x2) + 1;
return;
}
r = func_80185D58(p);
if (r == 1 || *(s16 *)(p + 0xDE) == 1) {
*(s32 *)(p + 0x18) = 0xFFF4999A;
*(s32 *)(p + 0x14) = 0xFFE00000;
*(s32 *)(p + 0x48) = 0x40000;
*(s16 *)(p + 0xDE) = 0;
*(s32 *)(p + 0x44) = 0;
*(s32 *)(p + 0x4C) = 0;
*(s16 *)(p + 0x2) = *(u16 *)(p + 0x2) + 1;
if ((u16)(*(u16 *)(p + 0xE) + 0x17BD) < 0x2BC2) {
((void (*)(s32, s32))func_8018623C)(0x4DD, 0);
}
((void (*)(s32, s32))func_8018623C)(0x4DF, 0x1000);
return;
}
if (r == 2 || *(s16 *)(p + 0xDE) == 2) {
*(s32 *)(p + 0x18) = 0;
*(s32 *)(p + 0x14) = 0;
*(s32 *)(p + 0x10) = 0;
*(s32 *)(p + 0x4C) = 0;
*(s32 *)(p + 0x48) = 0;
*(s32 *)(p + 0x44) = 0;
((void (*)(s32, s32))func_8018623C)(0x4D9, 0);
func_8002D4C8(4, 0x4DF);
func_8002D4C8(4, 0x4E2);
func_801824CC();
((void (*)(void *))func_8013C9C4)(D_8018B358);
*(s16 *)(p + 0x2) = *(u16 *)(p + 0x2) + 2;
return;
}
t = *(u16 *)(p + 0xF8) - 1;
*(s16 *)(p + 0xF8) = t;
if (t != 0) {
return;
}
*(s16 *)(p + 0xF8) = 8;
func_8004914C(D_800AF648);
func_800491AC(D_800AF648);
sv.vx = *(u16 *)(p + 0x6);
sv.vy = *(u16 *)(p + 0xA);
sv.vz = *(u16 *)(p + 0xE);
gte_ldv0(&sv);
gte_rtps();
gte_stsz(&sz[0]);
a = sz[0];
b = (a > 0x424) ? 0x424 : a;
sz[0] = b;
v = (b < 100) ? 100 : b;
c = (u16)(*(u16 *)(p + 0xE) + 0x17BD) < 0x2BC2;
sz[0] = v;
if (c) {
((void (*)(s32, s32))func_8018623C)(0x4E2, (0x7F - (v - 100) / 12) | 0x1000);
flag = 1;
} else {
flag = 0;
}
if (flag != *(s16 *)(p + 0xFA) && flag == 0) {
func_8002D4C8(4, 0x4E2);
}
*(s16 *)(p + 0xFA) = flag;
}
INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8018173C", func_8018512C);
+157 -2
View File
@@ -3498,7 +3498,103 @@ INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017DD0
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017DD84);
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8017DDC4);
#include "common.h"
/* 8-byte, align-4 pair record: the per-index slot pair at D_801D0120/D_801D0124 */
typedef struct {
s32 a; /* 0x00 -> D_801D0120 */
s32 b; /* 0x04 -> D_801D0124 */
} Pair8_8017DDC4;
/* 8-byte, align-2 record: forces move_by_pieces onto the lwl/lwr + swl/swr
* unaligned block-move path (cookbook §48-C2) for the 0x10..0x18 copy. */
typedef struct {
u16 x, y, z;
s16 w;
} Rec8_8017DDC4;
/* 16-byte stride table indexed by *(s16*)(obj+0x70) */
typedef struct {
s32 w[4];
} Rec16_8017DDC4;
extern Pair8_8017DDC4 D_801D0120[];
extern Rec16_8017DDC4 D_801A42B8[];
extern void func_8012C1B8(void);
extern void func_8012CAE4(void *a0);
extern void func_8001C214(s32 a0, s32 a1);
extern void func_80132784(s32 a0, s32 a1, u32 a2);
extern void func_8012B23C(void *a0);
extern void func_800484EC(s32 a0, s32 a1, s32 a2);
extern s32 rand(void);
extern s32 func_80132EF4(s32 a0, s32 a1);
extern s32 func_8012AD50(void *a0);
void func_8017DDC4(void *a0)
{
s32 v0;
s32 s1;
s32 t;
/* §162: fold the store AND the test into ONE expression so cc1 keeps both
* on the call's native $v0 instead of coalescing them into a fresh copy. */
if ((*(s32 *)((s32)a0 + 0x20) = ((s32 (*)(void))func_8012C1B8)()) == 0) {
func_8012CAE4(a0);
return;
}
s1 = *(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0xDC);
if (s1 != 0) {
t = *(s32 *)(s1 + 0x8);
if (t != 0) {
D_801D0120[*(s16 *)((s32)a0 + 0x70)].a =
((s32 *)t)[*(s16 *)((s32)a0 + 0x70)];
}
}
D_801D0120[*(s16 *)((s32)a0 + 0x70)].b = 0;
func_8001C214(*(s32 *)((s32)a0 + 0x20),
(s32)&D_801D0120[*(s16 *)((s32)a0 + 0x70)]);
if (*(s32 *)(s1 + 0xC) != 0) {
*(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x4) |= 0x1000000;
}
/* source order is DESCENDING here (0xE, 0xA, 0x6) — the emitted stores keep
* source order, and the target's are 0xE/0xA/0x6 with 0x6 in the delay slot. */
*(s16 *)((s32)a0 + 0xE) = 0;
*(s16 *)((s32)a0 + 0xA) = 0;
*(s16 *)((s32)a0 + 0x6) = 0;
func_80132784((s32)a0, *(s32 *)((s32)a0 + 0x64), *(u16 *)((s32)a0 + 0x70));
*(s16 *)((s32)a0 + 0x6) = *(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x48);
*(s16 *)((s32)a0 + 0xA) = *(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x4C);
*(s16 *)((s32)a0 + 0xE) = *(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x50);
*(Rec8_8017DDC4 *)(*(s32 *)((s32)a0 + 0x20) + 0x10) =
*(Rec8_8017DDC4 *)(*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0x20) + 0x10);
func_8012B23C(a0);
func_800484EC(*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0x20) + 0x34,
(s32)&D_801A42B8[*(s16 *)((s32)a0 + 0x70)],
(s32)a0 + 0x10);
*(s16 *)((s32)a0 + 0xFC) = rand() & 0xF0;
*(s16 *)((s32)a0 + 0xFE) = rand() & 0x1F0;
*(s16 *)((s32)a0 + 0x100) = rand() & 0x30;
v0 = func_80132EF4((s32)a0, 0x22);
if (v0 != 0) {
*(s16 *)(v0 + 0x34) = 0x4001;
*(s32 *)(v0 + 0x10) = *(s32 *)((s32)a0 + 0x10) >> 2;
*(s32 *)(v0 + 0x14) = *(s32 *)((s32)a0 + 0x14) >> 2;
*(s32 *)(v0 + 0x18) = *(s32 *)((s32)a0 + 0x18) >> 2;
}
*(s32 *)((s32)a0 + 0x1C) = 0x20;
func_8012AD50(a0);
}
extern void (*D_801A4308[])(void);
@@ -5084,7 +5180,66 @@ INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_8018226
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_80182318);
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_801823E8);
#include "common.h"
#include "/home/musashi/bfm-decomp/src/shared/engine_core.h" /* match_one-only: the real TU already includes this */
/* func_801823E8 -- ov_SC02_026 / ov_SC02_026_jr_8017C180
* Same TU declares this at line 4712 (extern void func_801823E8(s32 a0);) and
* calls it at line 4822. Callee set derived from already-matched siblings in
* THIS TU (§160g): func_8017FD58 (line 3739, Ent_8017FD58 loop-array idiom),
* func_8012CC88 (src/shared/engine_core.h DEFINE_func_8012CC88, the sp10/sp18
* SV3_8012CC88-from-0x3A/0x3E/0x42 pattern), and the ground-truth DEFINE_ bodies
* for func_8012BC60 / func_8012B6D4 / func_8012B0B4 / func_8012CEB0 / func_8012ADE4.
*/
extern u8 D_801202A0[];
extern s32 func_8012BC60(struct Vec *a0, struct Vec *a1);
extern s32 func_8012B6D4(s16 *a0, s16 *a1);
extern void func_8012B0B4(unsigned int *param_1, int param_2, int param_3);
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
extern void func_8012ADE4(u8 *a0);
void func_801823E8(s32 a0) {
Ent_8017FD58 *e;
s32 i;
s16 *mover;
s32 off;
unsigned int *offp;
s32 ang;
s32 v0;
SV3_8012CC88 sp10;
SV3_8012CC88 sp18;
e = (Ent_8017FD58 *)D_801202A0;
i = 0;
mover = (s16 *)(a0 + 4);
offp = (unsigned int *)&off;
for (; i < 0x60; i++, e++) {
if (e->f0 == 0x17F && a0 != (s32)e &&
func_8012BC60((struct Vec *)mover, (struct Vec *)&e->f4) < 0x1000) {
ang = func_8012B6D4(mover, (s16 *)&e->f4);
func_8012B0B4(offp, ang, 0x41);
sp18.vx = e->x;
sp18.vy = e->y;
sp18.vz = e->z;
sp18.vx += off;
sp18.vz += (off >> 16);
sp10.vx = *(u16 *)(a0 + 0x3A);
sp10.vy = *(u16 *)(a0 + 0x3E);
sp10.vz = *(u16 *)(a0 + 0x42);
v0 = func_8012CEB0((s32)&sp10, (s32)&sp18, 0);
if ((v0 & 0x2000) == 0) {
func_8012ADE4((u8 *)a0);
return;
}
*(s16 *)(a0 + 0x6) = sp18.vx;
*(s16 *)(a0 + 0xA) = sp18.vy;
*(s16 *)(a0 + 0xE) = sp18.vz;
return;
}
}
}
INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_80182550);
+280 -2
View File
@@ -3323,7 +3323,174 @@ void func_8017D784(void *a0) {
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8017D7C0);
#include "common.h"
/* Host TU (src/ov_SC02_041/ov_SC02_041_jr_8017BEBC.c) already has these three via
* ../shared/engine_core.h -> engine_types.h as SVECTOR (:997), MATRIX (:1168) and
* Vec32 (:1098) -- byte-identical layouts. Renamed here only because match_one
* compiles standalone with -Iinclude (engine_core.h is not on that path); on bank,
* drop these three typedefs and use the TU's own names. */
typedef struct { s16 vx, vy, vz, pad; } SV_8017D7C0; /* 8 bytes, align 2 */
typedef struct { s16 m[3][3]; s32 t[3]; } MTX_8017D7C0; /* 0x20 bytes, align 4 */
typedef struct { s32 vx, vy, vz, pad; } V32_8017D7C0; /* 16 bytes, align 4 */
/* ov_SC02_041 func_8017D7C0 -- 181 ins, zero-crack family exemplar (reach x4:
* ov_SC04_002:8017f19c, ov_SC04_004:8017f65c, ov_SC04_011:8017f340).
*
* Spawn-a-particle-burst routine:
* obj = actor->0x34; p = alloc(); actor->0x20 = p;
* if (p) { init p, force its "hidden" bit, copy the actor position into it,
* scale it from a table, jitter a rotation SVECTOR + a velocity
* Vec32 with rand(), RotMatrix + ApplyMatrix into the actor's
* velocity, then 9 more rand() shorts at actor+0x38 }
* else { func_80146C3C(actor) }
*
* Frame (0x60): sp+0x10 s16 buf[4] (func_80015978/func_80015954 position temp)
* sp+0x18 SVECTOR rot (8 bytes, align 2)
* sp+0x20 MATRIX m (0x20 bytes)
* sp+0x40 Vec32 vel (16 bytes, align 4)
* sp+0x50..0x5F saved s0/s1/s2/ra
* -> declaration order IS frame order (gcc-2.7.2 MIPS frame grows upward).
*/
extern void func_8001CF00(s32 a0);
extern void func_80015978(s32 a0, s32 *a1);
extern void func_80015954(s32 a0, s32 a1);
extern void func_801465C0(void);
extern void func_80146C3C();
extern void func_80146E90(s32 *a0, s32 a1);
extern void func_80049CAC(s32 a0, s32 a1);
extern void func_800484EC(s32 a0, s32 a1, s32 a2);
extern int rand(void);
extern SV_8017D7C0 D_801888FC[]; /* stride 8, align 2 -> lwl/lwr + swl/swr copy */
extern V32_8017D7C0 D_8018892C; /* 16 bytes, align 4 -> plain lw/sw copy */
extern u16 D_8018893C[]; /* stride 2 scale table */
void func_8017D7C0(s32 param_1) {
s16 buf[4];
SV_8017D7C0 rot;
MTX_8017D7C0 m;
V32_8017D7C0 vel;
s32 obj;
s32 p;
s16 *q;
s32 i;
u16 sc;
obj = *(s32 *)(param_1 + 0x34);
p = ((s32 (*)(void))func_801465C0)();
*(s32 *)(param_1 + 0x20) = p;
if (p != 0) {
func_8001CF00(p);
*(s32 *)(p + 0x4) |= 0x80000000;
func_80015978(obj + 4, (s32 *)buf);
func_80015954((s32)buf, param_1 + 4);
sc = D_8018893C[*(s32 *)(param_1 + 0x30)];
*(u16 *)(p + 0x18) = *(u16 *)(p + 0x1a) = *(u16 *)(p + 0x1c) = sc;
vel = D_8018892C;
rot = D_801888FC[*(s32 *)(param_1 + 0x2c)];
if (*(s32 *)(param_1 + 0x30) != 0) {
/* LEVER: the compound `+=` is load-bearing. Spelled out as
* `rot.vx = rot.vx - 0x200 + ((rand() & 0x3f) << 4);` gcc-2.7.2 folds
* the -0x200 onto the JITTER term (addiu $v0 after the sll) instead of
* onto the loaded field (addiu $v1 after the lhu) -- 9 mismatched ins.
* `a += jitter - 0x200` keeps `a` the accumulator and emits the target's
* lhu / sll / addiu $v1,-0x200 / addu $v1,$v0. See notes at the bottom. */
rot.vx += ((rand() & 0x3f) << 4) - 0x200;
rot.vy += ((rand() & 0x3f) << 4) - 0x200;
rot.vz += ((rand() & 0x3f) << 4) - 0x200;
vel.vx = ((rand() & 0x1f) - 0x10) << 16;
vel.vy = ((rand() & 0x1f) - 0x10) << 16;
vel.vz = ((rand() & 0x1f) - 0x10) << 16;
}
func_80049CAC((s32)&rot, (s32)&m);
func_800484EC((s32)&m, (s32)&vel, (s32)&vel);
*(s32 *)(param_1 + 0x10) = vel.vx;
*(s32 *)(param_1 + 0x14) = vel.vy;
*(s32 *)(param_1 + 0x18) = vel.vz;
q = (s16 *)(param_1 + 0x38);
i = 0;
*(s32 *)(param_1 + 0x4c) = ((rand() & 0x1f) - 0x10) * 11;
*(s32 *)(param_1 + 0x50) = ((rand() & 0x1f) - 0x10) * 11;
*(s32 *)(param_1 + 0x54) = ((rand() & 0x1f) - 0x10) * 11;
do {
i++;
*q++ = (rand() & 0x7f) - 0x40;
*q++ = (rand() & 0x7f) - 0x40;
*q++ = (rand() & 0x7f) - 0x40;
} while (i < 3);
func_80146E90((s32 *)param_1, 2);
*(s16 *)(param_1 + 0x2) = *(u16 *)(param_1 + 0x2) + 1;
} else {
((void (*)(s32))func_80146C3C)(param_1);
}
}
/* ---------------------------------------------------------------------------
* INTEGRATION SURFACE (§161c) -- host TU src/ov_SC02_041/ov_SC02_041_jr_8017BEBC.c
* Every decl above is either CHARACTER-IDENTICAL to a file-scope decl already in
* the host TU (agrees => free, per §161c) or entirely new (no conflict):
*
* AGREES with host file-scope (all < :2803, the first function definition):
* :119 extern void func_80015978(s32 a0, s32 *a1);
* :132 extern void func_801465C0(void); <- void return; the TU's own
* established workaround for the real s32 return is the cast-call at
* :4192 `iVar3 = ((int (*)(void))func_801465C0)();` -- reused here.
* :161 extern void func_80146E90(s32 *a0, s32 a1);
* :163 extern void func_80015954(s32 a0, s32 a1);
* :242 extern void func_800484EC(s32 a0, s32 a1, s32 a2);
* :1091 extern int rand(void); (:956 `s32 rand(void)` also at
* file scope; s32==int so the two already coexist)
* :1681 extern void func_80146C3C(); (:1699 adds the `(void)` form;
* both already coexist. Cast-call form copied from :3304.)
* :2643 extern void func_80049CAC(s32 a0, s32 a1);
*
* NEW, not declared anywhere in the host TU (no conflict possible):
* func_8001CF00 -- fleet-canon `extern void func_8001CF00(s32);`
* (ov_SC02_027_jr_8016AB6C.c:2418 and 4 more overlays)
* D_801888FC / D_8018892C / D_8018893C -- per-overlay data, contiguous:
* D_801888FC[] stride 8 (6 entries) -> D_8018892C (16B) -> D_8018893C[] u16.
* NOTE for the banker: none of the three is in config/symbols.ov_SC02_041.txt
* (15 lines, no 0x801888xx entries), so they arrive as splat auto-names --
* confirm before/after the whole-binary gate.
*
* TYPES: SV_/MTX_/V32_8017D7C0 are byte-identical restatements of engine_types.h
* SVECTOR(:997) / MATRIX(:1168) / Vec32(:1098). Prefer the engine_types names on
* bank (the host TU already pulls them in); the local typedefs exist only so
* match_one's standalone `-Iinclude` compile resolves them.
*
* WHY THE UNALIGNED COPY: `rot = D_801888FC[idx]` emits lwl/lwr + swl/swr, not
* lw/sw, because the array is `extern` so gcc uses TYPE_ALIGN = 2 (all-s16 struct)
* and its block-move takes MIN(src,dst) align < 4 => unaligned path. The sibling
* 16-byte `vel = D_8018892C` copy is plain lw/sw because Vec32 is all-s32 (align 4).
* The host TU's own carried decl layer already records this idiom verbatim:
* "8 bytes, align 2 -> lwl/lwr/swl/swr copy".
*
* OTHER LEVERS worth carrying to the 3 siblings (ov_SC04_002:8017f19c,
* ov_SC04_004:8017f65c, ov_SC04_011:8017f340), all of which are PURE h_seq copies:
* - `*(u16*)(p+0x18) = *(u16*)(p+0x1a) = *(u16*)(p+0x1c) = sc;` -- chained
* assignment stores RIGHT to LEFT (0x1c, 0x1a, 0x18), matching the target.
* - the 9-short tail is `*q++ =` three times inside a do-while, NOT q[0]/q[1]/q[2]
* with a `q += 3`: the target advances the pointer by 2 between stores (the
* addiu lands in each following jal's delay slot), which q[i] indexing cannot
* produce (it would emit sh 0/2/4($s0) + a single addiu 6).
* - the loop counter increments at the TOP of the body (`i = 0; do { i++; ... }
* while (i < 3);`), not the bottom -- a for-loop rotation puts the addiu after
* the last store instead of in the first jal's delay slot.
* - `((rand() & 0x1f) - 0x10) * 11` is left as a literal *11; gcc-2.7.2 expands
* it to sll1/addu/sll2/subu exactly as the target has it.
* --------------------------------------------------------------------------- */
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8017DA94);
@@ -5208,7 +5375,118 @@ INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_80181E1
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_80181FFC);
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_80182044);
#include "common.h"
/* func_80182044 — ov_SC02_041 / ov_SC02_041_jr_8017BEBC.c MATCH (142 ins)
*
* §160g SIBLING-FIRST provenance (nothing derived from the .s that could be copied):
* - the `sp10 / sp18 / sp18 = sp10; sp18.y += K; func_80133784(1, &sp10, (s32)&sp18)`
* 8-byte-vector block is copied VERBATIM from the banked sibling func_80189100
* (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:6330-6360), including the
* `{u16 x,y,z,w}` V8 layout (== engine_types.h:4534 V8_80189100). align-2 + size-8
* is what makes gcc emit the ULW/USW block move (lwl/lwr,lwl/lwr,swl/swr,swl/swr)
* instead of four lhu/sh pairs, and it is what keeps the two slots at sp+0x10/sp+0x18.
* - the `s32 *base = &D_80126B58;` INITIALISED LOCAL is copied from the banked
* func_8016F1C4 (src/ov_SC06_008/ov_SC06_008_jr_8016AB6C.c:3944). This is the whole
* reason $s1 gets lui/addiu %hi/%lo(D_80126B58) in the ENTRY block, ahead of every
* branch, and then serves 0x10/0x18/0x34 as base+offset: gcc-2.7.2 has no GCSE, so an
* address that is materialised before its first (conditional) use can only come from
* a declaration-with-initialiser. Spelling the three reads as bare D_80126B68/70/8C
* globals would give three separate lui/lw pairs instead.
* - the `extern void func_8012A828(s32 a0, void *a1);` + bare-array-arg call form is the
* TU's own spelling (TU:4571/4585/4602/4631/4783/5041/5075/5116).
*
* SHAPE NOTES
* - `if (func_8012CBA4(a0) & 0x6000) {...} else {...}` — the 0x6000 arm FALLS THROUGH,
* and sched2 fills the beqz delay slot with the `li $v0,2` that the else-arm needs for
* its first D_8011F730 compare. Inverting the test loses that.
* - the two `D_8011F730 == 2 / == 1` tests are spelled as two plain global reads; cse
* collapses them to ONE `lw $v1` because they sit on the same extended basic block.
* - `temp = *(s32*)(a0+0xD0); if (temp) { func_8012A828(a0,(void*)temp); ... }` — the
* value is loaded straight into $a1 and survives the beqz into the jal's argument.
*
* DECLARATION SURFACE (audited against the WHOLE destination TU, above AND below the
* splice at TU:5211, plus ../shared/engine_core.h — that TU expands ZERO DEFINE_ macros,
* so the header contributes no file-scope declaration here):
* D_80126B58 TU:55 `extern s32 D_80126B58;` <- AGREES verbatim
* D_8011F730 TU:83 `extern s32 D_8011F730;` <- AGREES verbatim
* func_8012A828 TU:4571 `extern void func_8012A828(s32 a0, void *a1);` <- AGREES verbatim
* func_80133784 TU:599/854 `extern s32 func_80133784(s32 a0, void *a1, s32 a2);`
* <- CONFORMED (the natural `void *a2` here CONFLICTS with the TU's `s32`);
* the disagreement is pushed to a zero-byte cast at the use site.
* func_8012CBA4 / func_8012A8E8 — NOT declared in the TU; the fleet-dominant spellings
* (1651x `extern void func_8012CBA4(s32 a0);`, 1457x
* `extern void func_8012A8E8(void);`) are used with use-site casts so the
* body stays compatible if a DEFINE_ macro or another region is ever spliced.
* func_80182D80 / func_80182F20 / D_801B5D9C / D_801B61D4 / D_80126B84 — declared NOWHERE
* in the TU or in any src/ TU, so these spellings are free.
* V8_80182044 — fresh typedef name; no clash in the TU, engine_types.h or engine_core.h.
* (It is layout-identical to engine_types.h:4534 V8_80189100, which IS visible
* in this TU via engine_core.h; on banking it may be replaced by that name.)
*/
typedef struct { u16 x, y, z, w; } V8_80182044;
extern s32 D_80126B58;
extern s32 D_80126B84;
extern s32 D_8011F730;
extern void func_8012A828(s32 a0, void *a1);
extern void func_8012A8E8(void);
extern void func_8012CBA4(s32 a0);
extern void func_80182D80(s32 a0);
extern s32 func_80182F20(s32 a0);
extern s32 func_80133784(s32 a0, void *a1, s32 a2);
void func_80182044(s32 a0) {
extern u8 D_801B5D9C[];
extern u8 D_801B61D4[];
V8_80182044 sp10;
V8_80182044 sp18;
s32 *base = &D_80126B58;
s32 temp;
if (*(u16 *)(a0 + 0x34) == 0 && D_80126B84 < -0x94000 &&
*(s16 *)(a0 + 0x98) != 0 && *(u8 **)(a0 + 0x90) != D_801B61D4) {
func_8012A828(a0, D_801B5D9C);
*(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
}
func_80182D80(a0);
if (((s32 (*)(s32))func_8012CBA4)(a0) & 0x6000) {
if (base[4] == 0 && base[6] == 0) {
if (func_80182F20(a0) == 0) {
*(u16 *)(a0 + 0x2) = 1;
}
} else if (*(u8 **)(a0 + 0x90) == D_801B61D4) {
temp = *(s32 *)(a0 + 0xD0);
if (temp != 0) {
func_8012A828(a0, (void *)temp);
*(s32 *)(a0 + 0xD0) = 0;
}
} else if (*(s16 *)(a0 + 0x98) == 0) {
((void (*)(s32))func_8012A8E8)(a0);
}
} else if (D_8011F730 == 2) {
*(s32 *)(a0 + 0xD0) = *(s32 *)(a0 + 0x90);
func_8012A828(a0, D_801B61D4);
} else if (D_8011F730 == 1) {
if (*(s32 *)(a0 + 0xD0) == 0) {
*(s16 *)(a0 + 0x98) = 0;
}
} else if (*(s16 *)(a0 + 0x98) != 0 && base[13] == 0) {
sp10.x = *(u16 *)(a0 + 0x6);
sp10.y = *(u16 *)(a0 + 0xA);
sp10.z = *(u16 *)(a0 + 0xE);
sp18 = sp10;
sp18.y += 0x10;
func_80133784(1, &sp10, (s32)&sp18);
*(u16 *)(a0 + 0x6) = sp18.x;
*(u16 *)(a0 + 0xA) = sp18.y;
*(u16 *)(a0 + 0xE) = sp18.z;
}
}
INCLUDE_ASM("asm/ov_SC02_041/nonmatchings/ov_SC02_041_jr_8017BEBC", func_8018227C);
+340 -2
View File
@@ -2895,7 +2895,180 @@ INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_801848E4", func_80185A0
INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_801848E4", func_80185B44);
INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_801848E4", func_80185EF8);
#include "common.h"
/* ---- integration surface (types taken from the host TU / engine_core.h) ---- */
extern s32 *D_80126B78; /* host TU L72 : extern s32 *D_80126B78; */
extern u16 D_80126B5E; /* host TU L1785: extern u16 D_80126B5E; */
extern u16 D_80126B62; /* host TU L1786: extern u16 D_80126B62; */
extern u16 D_80126B66; /* host TU L1787: extern u16 D_80126B66; */
extern u8 D_80126B5C; /* host TU L356 : extern u8 D_80126B5C; */
extern s32 D_80126B64; /* project-canonical decl */
extern void *D_801904F0[];
extern s32 rand(void);
extern s32 func_8004787C(s32 a0); /* host TU L2198 */
extern s32 func_80047948(s32 a0); /* host TU L2197 */
extern s32 func_8012B744(void *a0, void *a1); /* engine_core canonical */
extern s32 func_8012BA10(s32 a0, s32 a1); /* engine_core canonical */
extern void func_8012BE54(s32 a0); /* canonical void -> cast at use */
extern void func_8012CBA4(s32 a0); /* canonical void */
extern void func_8012A828(s32 a0, void *a1); /* host TU L3203 */
void func_80185EF8(s32 a0) {
s32 t;
s32 spd;
s32 anim;
s32 hit;
s32 hit2;
u16 sp[3];
t = ((*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF) -
(*(u16 *)((u8 *)D_80126B78 + 0x12) & 0xFFF)) & 0xFFF;
if ((u32)(t - 0x7C1) < 0x7F) {
anim = 1;
spd = 0;
} else if ((u32)(t - 0x101) >= 0xDFF) {
anim = 3;
spd = 8;
} else if (t < 0x701) {
anim = 7;
spd = 8;
} else if (t < 0x7C1) {
anim = 5;
spd = 4;
} else if (t < 0x900) {
anim = 4;
spd = 4;
} else {
anim = 6;
spd = 8;
}
sp[0] = D_80126B5E -
((func_8004787C(*(u16 *)((u8 *)D_80126B78 + 0x12) & 0xFFF) * 14) >> 8);
sp[1] = D_80126B62;
sp[2] = D_80126B66 -
((func_80047948(*(u16 *)((u8 *)D_80126B78 + 0x12) & 0xFFF) * 14) >> 8);
t = func_8012B744((void *)(a0 + 4), sp);
*(s32 *)(a0 + 0x10) = -((func_8004787C(t) * spd) << 5);
*(s32 *)(a0 + 0x18) = -((func_80047948(t) * spd) << 5);
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += func_8012BA10(a0, 4);
/* NOTE: written as nested ifs, NOT an `||` chain -- fold_range_test would
* otherwise collapse each pair into an unsigned HImode range test. */
hit = 1;
if (*(s16 *)&D_80126B5E < 0xF2) {
if (*(s16 *)&D_80126B5E >= -0x101) {
if (*(s16 *)&D_80126B66 < -0x106) {
hit = *(s16 *)&D_80126B66 < -0x4AA;
}
}
}
if (hit) {
anim = 0xE;
*(u16 *)(a0 + 0x34) = 0;
if (((s32 (*)(s32))func_8012BE54)(a0) < 0x1000) {
*(u16 *)(a0 + 0x2) = 0xB;
} else {
switch (rand() % 3) {
case 0:
*(u16 *)(a0 + 0x2) = 2;
break;
case 1:
*(u16 *)(a0 + 0x2) = 6;
break;
case 2:
*(u16 *)(a0 + 0x2) = 8;
break;
}
}
*(s32 *)(a0 + 0x10) = 0;
*(s32 *)(a0 + 0x18) = 0;
} else {
func_8012CBA4(a0);
*(s32 *)(a0 + 0x10) = 0;
*(s32 *)(a0 + 0x18) = 0;
if (*(s16 *)(a0 + 0x6) >= 0xF2) {
goto restore;
}
if (*(s16 *)(a0 + 0x6) < -0x101) {
goto restore;
}
if (*(s16 *)(a0 + 0xE) >= -0x106) {
goto restore;
}
if (*(s16 *)(a0 + 0xE) < -0x4AA) {
goto restore;
}
hit2 = 0;
goto tested;
restore:
*(s32 *)(a0 + 0x4) = *(s32 *)(a0 + 0x38);
*(s32 *)(a0 + 0x8) = *(s32 *)(a0 + 0x3C);
*(s32 *)(a0 + 0xC) = *(s32 *)(a0 + 0x40);
hit2 = 1;
tested:
if (hit2) {
*(u16 *)(a0 + 0x2) = 0xC;
*(u16 *)(a0 + 0x34) = 0;
anim = 8;
*(s32 *)(a0 + 0x10) = (*(s32 *)&D_80126B5C - *(s32 *)(a0 + 0x4)) / 32;
*(s32 *)(a0 + 0x18) = (D_80126B64 - *(s32 *)(a0 + 0xC)) / 32;
*(u16 *)(a0 + 0xDC) = 0;
*(u16 *)(a0 + 0x102) = 0;
*(u16 *)(a0 + 0xDE) = *(u16 *)(a0 + 0xA);
} else {
if (((s32 (*)(s32))func_8012BE54)(a0) <= 0x8FFF) {
anim = 0xE;
if (rand() & 1) {
*(u16 *)(a0 + 0x2) = 6;
} else {
*(u16 *)(a0 + 0x2) = 8;
}
*(u16 *)(a0 + 0x34) = 0;
if (((s32 (*)(s32))func_8012BE54)(a0) < 0x1000) {
anim = 0xE;
*(u16 *)(a0 + 0x2) = 0xB;
*(u16 *)(a0 + 0x34) = 0;
}
}
if (*(s16 *)(a0 + 0xE0) == *(s16 *)&D_80126B5E &&
*(s16 *)(a0 + 0xE2) == *(s16 *)&D_80126B66) {
s16 c;
c = *(u16 *)(a0 + 0x102) + 1;
*(s16 *)(a0 + 0x102) = c;
if (c >= 0x1E) {
*(u16 *)(a0 + 0x2) = 0xC;
*(u16 *)(a0 + 0x34) = 0;
anim = 8;
*(s32 *)(a0 + 0x10) =
(*(s32 *)&D_80126B5C - *(s32 *)(a0 + 0x4)) / 32;
*(s32 *)(a0 + 0x18) = (D_80126B64 - *(s32 *)(a0 + 0xC)) / 32;
*(u16 *)(a0 + 0xDC) = 0;
*(u16 *)(a0 + 0x102) = 0;
*(u16 *)(a0 + 0xDE) = *(u16 *)(a0 + 0xA);
}
} else {
*(u16 *)(a0 + 0x102) = 0;
}
*(u16 *)(a0 + 0xE0) = D_80126B5E;
*(u16 *)(a0 + 0xE2) = D_80126B66;
}
}
if (*(s16 *)(a0 + 0xFE) != anim) {
*(s16 *)(a0 + 0xFE) = anim;
func_8012A828(a0, D_801904F0[anim]);
}
}
INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_801848E4", func_801863B8);
@@ -2905,7 +3078,172 @@ INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_801848E4", func_801867F
INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_801848E4", func_80186A74);
INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_801848E4", func_80186C4C);
#include "common.h"
/* func_80186C4C — ov_SC03_014 / ov_SC03_014_jr_801848E4. MATCH 273/273.
* BYTE-IDENTICAL twin: ov_SC03_015 @ 0x80186C4C (same 273 ins, same D_ symbol
* addresses) — this one body matches BOTH overlays verbatim, no remap needed.
*
* Four levers, each measured against match_one:
*
* 1. THE ZERO-ARG func_8012C218. The early-out call at 80186C74 has a *nop*
* delay slot and no `move $a0,$s0` anywhere in its block, while every other
* call in the function sets $a0 explicitly. gcc always emits the arg copy
* when the callee takes one, and dbr would have pulled it into the jal slot,
* so the source call genuinely passes NOTHING. The host TU's file-scope decl
* is `extern void func_8012C218(void *a0);` (an arg-less call against it is a
* hard error), so it is spelled with the TU's own established cast idiom:
* `((void (*)(void))func_8012C218)();` (see TU L2943 for the same idiom).
* The SECOND call, in the &0x8000 arm, does take a0 and keeps the prototype.
*
* 2. THE $s0/$s1 PERM, SOLVED WITHOUT A PIN (§137). Written naively (a separate
* pseudo for &D_80191808 and another for the func_80143C74 result) global-alloc
* ranks the table address ABOVE the a0-copy: a0 -> $s1, table -> $s0, result ->
* $s0 — the exact mirror of the target. Pinning the a0-copy to $16 fixes the
* registers but COSTS an instruction: `register s32 a0 __asm__("$16"); a0=arg0;`
* leaves the parameter as a second live pseudo, and copy-prop then serves
* func_8012CBCC's argument straight out of the incoming $a0, deleting the
* `move $a0,$s0` the target has at 80186C88. The fix that costs nothing is to
* give the table address and the func_80143C74 result THE SAME variable `r`
* (their live ranges are disjoint — the table dies at the third func_8012D5E4).
* One pseudo instead of two drops its priority below the a0-copy, so a0 first-
* fits $s0 and r takes $s1 for both roles, exactly as the target does. A pin
* on the table to $17 works equally well; the merged variable is preferred as
* it adds no asm-register construct.
*
* 3. STATEMENT ORDER AS MULT-GAP SEED. -O2 schedules the statement FOLLOWING a
* multiply into the gap between that multiply's `mult` and its `mflo`. The
* target parks the `r->0x48 -= 0xC000` block (lui/lw/ori/addu/sw) inside the
* SECOND mult's gap (80186F4C..80186F5C), so in the source it must follow the
* r->0xC statement, not sit between r->0x4 and r->0xC. With it in the middle
* it lands in the FIRST mult's gap instead and every following index shifts.
*
* 4. ONE LOAD OF r->0xCC. Two literal `*(s16 *)(*(s32 *)(r + 0xCC) + ...)` stores
* re-load the pointer (the intervening store is may-alias, so CSE refuses);
* the target loads it once into $v1. Hoisting it into a local `c` is what
* makes the 273/275 instruction count come out.
*
* The `q = &D_80126B96; *q |= 0x4000;` pointer form (not a direct `D_80126B96 |=`)
* is the fleet-wide idiom for this global — it is what produces lui+addiu followed
* by `lhu 0($v1)` rather than a `%lo`-folded load. See ov_SC02_027_jr_8017D898.c
* L4527 and ov_SC03_099_jr_8017BEBC.c L6138.
*/
extern void func_8012C218(void *a0);
extern s32 func_8012CBCC(s32 a0);
extern s32 func_8012D5E4(s32 a0, s32 a1, s32 a2, s32 a3);
extern s32 func_80143C74(s32 a0, s32 a1);
extern s32 func_8004787C(s32 a0);
extern s32 func_80047948(s32 a0);
extern void func_800599B8();
extern s16 D_80191810;
extern s16 D_80191812;
extern s16 D_80191814;
extern s16 D_80191818;
extern s16 D_8019181A;
extern s16 D_8019181C;
extern s16 D_80191820;
extern s16 D_80191822;
extern s16 D_80191824;
extern u8 D_80191808[];
extern u8 D_80191828[];
extern u8 D_80191830[];
extern u8 D_80190FE8[];
extern u8 D_801907E8[];
extern u8 D_801917E8[];
void func_80186C4C(s32 a0) {
extern u16 D_80126B96;
u16 *q;
s32 r;
s32 t;
s32 c;
s16 sp10[3];
t = *(s32 *)(a0 + 0x1C) - 1;
*(s32 *)(a0 + 0x1C) = t;
if (t <= 0) {
((void (*)(void))func_8012C218)();
return;
}
if (func_8012CBCC(a0) & 0x8000) {
func_8012C218((void *)a0);
return;
}
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) =
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) + 0x80;
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x1A) =
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x1A) + 0x80;
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x1C) =
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x1C) + 0x80;
r = (s32)D_80191808;
sp10[0] = (D_80191810 * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12;
sp10[1] = (D_80191812 * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x1A)) >> 12;
sp10[2] = (D_80191814 * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x1C)) >> 12;
if (func_8012D5E4(a0, r, (s32)sp10, 0x30) != 0) {
q = &D_80126B96;
*q |= 0x4000;
}
sp10[0] = (D_80191818 * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12;
sp10[1] = (D_8019181A * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x1A)) >> 12;
sp10[2] = (D_8019181C * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x1C)) >> 12;
if (func_8012D5E4(a0, r, (s32)sp10, 0x30) != 0) {
q = &D_80126B96;
*q |= 0x4000;
}
sp10[0] = (D_80191820 * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12;
sp10[1] = (D_80191822 * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x1A)) >> 12;
sp10[2] = (D_80191824 * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x1C)) >> 12;
if (func_8012D5E4(a0, r, (s32)sp10, 0x30) != 0) {
q = &D_80126B96;
*q |= 0x4000;
}
r = func_80143C74(a0, 0);
if (r != 0) {
*(s32 *)(r + 0x4) =
*(s32 *)(r + 0x4) -
((func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) *
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 3);
*(s32 *)(r + 0xC) =
*(s32 *)(r + 0xC) -
((func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) *
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x1C)) >> 3);
*(s32 *)(r + 0x48) = *(s32 *)(r + 0x48) - 0xC000;
c = *(s32 *)(r + 0xCC);
*(s16 *)(c + 0x18) = 0x3000;
*(s16 *)(c + 0x1A) = 0x3000;
}
if (*(s32 *)(a0 + 0x1C) & 1) {
func_800599B8(D_80191828, D_80190FE8);
func_800599B8(D_80191830, D_801917E8);
if (r == 0) {
return;
}
*(s32 *)(r + 0x10) =
func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x180) << 7;
*(s32 *)(r + 0x18) =
func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x180) << 7;
} else {
func_800599B8(D_80191828, D_801907E8);
func_800599B8(D_80191830, D_801917E8);
if (r == 0) {
return;
}
*(s32 *)(r + 0x10) =
func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x180) << 7;
*(s32 *)(r + 0x18) =
func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x180) << 7;
}
}
INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_801848E4", func_80187090);
+125 -1
View File
@@ -5329,7 +5329,131 @@ INCLUDE_ASM("asm/ov_SC03_089/nonmatchings/ov_SC03_089_jr_8017CA80", func_8018438
INCLUDE_ASM("asm/ov_SC03_089/nonmatchings/ov_SC03_089_jr_8017CA80", func_801843E4);
INCLUDE_ASM("asm/ov_SC03_089/nonmatchings/ov_SC03_089_jr_8017CA80", func_801844C8);
#include "common.h"
/* func_801844C8 — ov_SC03_089 (ov_SC03_089_jr_8017CA80), 154 ins, jtbl_801C53E4 (5 entries,
* minval 0 / maxval 4 — `lhu` + `sltiu 5`, so the switch expression is UNSIGNED and neither
* §162a2's leading nor §162a1/§162a3's trailing empty-case tell applies).
*
* Decl provenance (§161c) — forms copied VERBATIM from the destination TU where it already
* declares the callee ABOVE this function's INCLUDE_ASM (src/…/ov_SC03_089_jr_8017CA80.c:5332):
* func_8002D4C8 TU:59 / 3984 / 4018 `extern void func_8002D4C8(s32 a0, s32 a1);` (visible)
* func_8012B2CC TU:2523 / 4913 `extern void func_8012B2CC(s32 a0);` (visible)
* func_8012B178 TU:5635 (BELOW) same canonical form, so it agrees, not conflicts
* func_80184B80 TU:5351 (BELOW) DEFINED `s32 func_80184B80(s32 arg0)` — agrees
* func_80184BAC TU:5356 (BELOW) INCLUDE_ASM only, no decl to conflict with
* func_8012CBF4 / func_8012B8E4 / func_8012BEE8 / func_8012B200 / func_8012B77C / D_801A3AA4
* are not declared anywhere in the host TU; the forms below are the project-canonical ones
* (ov_SC03_099_jr_8012ACE0.c:1688, :353, ov_SC03_099_jr_801380E0.c:272, …).
*
* THE SHAPE THAT COSTS THE MATCH — the shared `.L801846F4` tail is a CROSS-JUMP, not a `break`.
* Case 0 (both arms) and case 3 each end `lhu $v0,0x34; addiu $v0,$v0,1` and only the STORE
* `sh $v0,0x34($s0)` is shared. Spelling that with a switch-scope `s16 nv; … break;` + a single
* post-switch `*(s16*)(a0+0x34) = nv;` compiles to 152 ins / 113 mismatched: one shared pseudo
* makes case 3's `lhu` land in $v1 (`addu $2,$3,1`), which breaks jump.c's minimum=1 path
* (find_cross_jump(insn, JUMP_LABEL(insn), 1) — jump.c:1978) against case 3's trailing `addiu`,
* so the minimum=2 jump_chain path fires instead and welds case-0 arm1 into arm2 (a 3-insn tail
* at a new label) — a merge the target does not have. Written LONGHAND (each arm stores 0x34
* itself and `return`s), every arm gets its own single-block temp, all of them land in $v0, and
* the compiler makes exactly the target's merge. Cf. §162h's floor law read from the other side:
* here the source-level factoring is what has to be REMOVED. */
extern void func_8012CBF4(s32 a0); /* canonical `void`; $v0 is used in case 0 -> cast at the site */
extern s32 func_8012B8E4(s32 a0, s32 a1);
extern s32 func_8012BEE8(s32 a0);
extern void func_8012B200(u8 *a0);
extern void func_8002D4C8(s32 a0, s32 a1);
extern void func_8012B178(s32 a0, s32 a1);
extern void func_8012B2CC(s32 a0);
extern s32 func_8012B77C(s32 out, s32 from, s32 to);
extern void func_80184BAC(s32 out, s32 a1, s32 a2);
extern s32 func_80184B80(s32 arg0);
void func_801844C8(s32 a0) {
extern u8 D_801A3AA4[];
s32 sp10[4]; /* 0x10: the func_8012B77C "to" record — fields at +0x2/+0x6/+0xA */
s32 sp20[2]; /* 0x20: the 8-byte out buffer shared by func_80184BAC and func_8012B77C */
s32 t;
switch (*(u16 *)(a0 + 0x34)) {
case 0:
if (((s32 (*)(s32))func_8012CBF4)(a0) != 0) {
*(s32 *)(a0 + 0x1C) = 0x1E;
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0;
*(s16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
return;
} else {
if (*(s16 *)(a0 + 0x100) >= *(s16 *)(a0 + 0xA)) {
return;
}
*(s16 *)(a0 + 0xA) = *(s16 *)(a0 + 0x100);
*(s32 *)(a0 + 0x1C) = 0x1E;
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0;
*(s16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
return;
}
case 1:
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += func_8012B8E4(a0, 6);
if (func_8012BEE8(a0) == 0) {
return;
}
*(s16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
func_8012B200((u8 *)a0);
*(s32 *)(a0 + 0x1C) = 0x20;
func_8002D4C8(0x6FF, 0);
return;
case 2:
func_80184BAC((s32)sp20, a0, (s32)D_801A3AA4);
t = sp20[0];
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = t;
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t >> 16;
func_8012B178(a0, *(s32 *)(a0 + 0xE0) - 0x80000);
func_8012CBF4(a0);
if (func_80184B80(a0) != 1) {
if (func_8012BEE8(a0) == 0) {
return;
}
}
*(s16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
*(s16 *)((s32)sp10 + 0x2) = *(u16 *)(a0 + 0x88);
*(s16 *)((s32)sp10 + 0x6) = *(u16 *)(a0 + 0x8A);
*(s16 *)((s32)sp10 + 0xA) = *(u16 *)(a0 + 0x8C);
func_8012B77C((s32)sp20, a0 + 4, (s32)sp10);
t = sp20[0];
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = t;
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t >> 16;
func_8012B2CC(a0);
func_8012B178(a0, *(s32 *)(a0 + 0xE0) - 0x80000);
*(s32 *)(a0 + 0x1C) = 0x80;
return;
case 3:
func_8012CBF4(a0);
if (func_8012BEE8(a0) == 0) {
if (*(s16 *)(a0 + 0xA) >= *(s16 *)(a0 + 0x8A)) {
return;
}
}
*(s16 *)(a0 + 0xA) = *(u16 *)(a0 + 0x8A);
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0;
*(s32 *)(a0 + 0x1C) = 0x3C;
*(s16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
return;
case 4:
if (func_8012BEE8(a0) == 0) {
return;
}
/* fall through */
default:
*(s16 *)(a0 + 0x2) = 4;
return;
}
}
INCLUDE_ASM("asm/ov_SC03_089/nonmatchings/ov_SC03_089_jr_8017CA80", func_80184730);
+184 -1
View File
@@ -4550,7 +4550,190 @@ void func_801848CC(void *a0) {
}
INCLUDE_ASM("asm/ov_SC03_093/nonmatchings/ov_SC03_093_jr_801825B8", func_80184938);
#include "common.h"
extern s32 func_80132EF4(s32 a0, s32 a1);
extern s32 func_8004787C(s32 a0);
extern s32 func_80047948(s32 a0);
extern s32 rand(void);
void func_80184938(s32 a0, s32 a1) {
s32 p;
s32 i;
s32 t;
switch (a1) {
case 0:
i = 0;
do {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s32 *)(p + 0x10) = func_8004787C(i) << 8;
*(s32 *)(p + 0x18) = func_80047948(i) << 8;
*(u16 *)(p + 0xA) += 0x60;
}
i += 0x200;
} while (i < 0x1000);
break;
case 1:
i = 0;
do {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s32 *)(p + 0x10) = func_8004787C(i) << 8;
*(s32 *)(p + 0x14) = func_80047948(i) << 8;
*(u16 *)(p + 0xE) += 0x60;
}
i += 0x200;
} while (i < 0x1000);
break;
case 2:
i = 0;
do {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s32 *)(p + 0x10) = func_8004787C(i) << 8;
*(s32 *)(p + 0x14) = func_80047948(i) << 8;
*(u16 *)(p + 0xE) -= 0x60;
}
i += 0x200;
} while (i < 0x1000);
break;
case 3:
i = 0;
do {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s32 *)(p + 0x14) = func_8004787C(i) << 8;
*(s32 *)(p + 0x18) = func_80047948(i) << 8;
*(u16 *)(p + 0x6) += 0x60;
}
i += 0x200;
} while (i < 0x1000);
break;
case 4:
i = 0;
do {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s32 *)(p + 0x14) = func_8004787C(i) << 8;
*(s32 *)(p + 0x18) = func_80047948(i) << 8;
*(u16 *)(p + 0x6) -= 0x60;
}
i += 0x200;
} while (i < 0x1000);
break;
case 5:
t = *(s16 *)(a0 + 0xFC);
if (t == 1) {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s16 *)(p + 0x12) = 0x10;
*(u16 *)(p + 0xA) += 0x60;
*(u16 *)(p + 0xE) += 0x30;
*(u16 *)(p + 0x6) += rand() & 0x3F;
}
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s16 *)(p + 0x12) = -0x10;
*(u16 *)(p + 0xA) += 0x60;
*(u16 *)(p + 0xE) += 0x30;
*(u16 *)(p + 0x6) -= rand() & 0x3F;
}
} else if (t == 2) {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s16 *)(p + 0x12) = 0x10;
*(u16 *)(p + 0xA) += 0x60;
*(u16 *)(p + 0xE) -= 0x30;
*(u16 *)(p + 0x6) += rand() & 0x3F;
}
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s16 *)(p + 0x12) = -0x10;
*(u16 *)(p + 0xA) += 0x60;
*(u16 *)(p + 0xE) -= 0x30;
*(u16 *)(p + 0x6) -= rand() & 0x3F;
}
} else if (t == 3) {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s16 *)(p + 0x1A) = 0x10;
*(u16 *)(p + 0xA) += 0x60;
*(u16 *)(p + 0x6) += 0x30;
*(u16 *)(p + 0xE) += rand() & 0x3F;
}
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s16 *)(p + 0x1A) = -0x10;
*(u16 *)(p + 0xA) += 0x60;
*(u16 *)(p + 0x6) += 0x30;
*(u16 *)(p + 0xE) -= rand() & 0x3F;
}
} else if (t == 4) {
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s16 *)(p + 0x1A) = 0x10;
*(u16 *)(p + 0xA) += 0x60;
*(u16 *)(p + 0x6) -= 0x30;
*(u16 *)(p + 0xE) += rand() & 0x3F;
}
p = func_80132EF4(a0, 0x40);
if (p != 0) {
*(s16 *)(*(s32 *)(p + 0x20) + 0x18) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1A) = 0x7000;
*(s16 *)(*(s32 *)(p + 0x20) + 0x1C) = 0x7000;
*(s16 *)(p + 0x1A) = -0x10;
*(u16 *)(p + 0xA) += 0x60;
*(u16 *)(p + 0x6) -= 0x30;
*(u16 *)(p + 0xE) -= rand() & 0x3F;
}
}
break;
}
}
INCLUDE_ASM("asm/ov_SC03_093/nonmatchings/ov_SC03_093_jr_801825B8", func_80184F90);
-231
View File
@@ -3925,234 +3925,3 @@ TAIL_5DC:
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017F640);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017F788);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017F83C);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017FBD8);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017FC3C);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017FD08);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017FD64);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017FEE4);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8017FFD0);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_801802E0);
extern void func_80180764(s32 *a0);
extern s32 func_801809A0(s32 a0);
void func_8018032C(s32 *a0) {
func_80180764(a0);
func_801809A0((s32)a0);
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8018035C);
void func_801803E0(s32 param_1) {
extern void func_801808B4(void *a0);
extern s32 func_801809A0(s32 a0);
extern void func_8012DBD0(s32 a0, s32 a1, s32 a2, s32 a3);
extern s32 func_8012CC64(s32 a0, void *a1);
extern s32 func_8012CC1C(s32 a0, void *a1);
extern s32 func_8012CBA4(s32 a0);
extern void func_8012B23C(s32 a0);
extern void func_80131C78(s32 a0);
extern s32 func_80143B6C(s32 a0, s32 a1);
extern void func_80131E00(s32 a0, s32 a1);
extern s32 D_8019E704;
u8 bVar1;
s32 uVar3;
s32 pad[2];
if (0xf < *(s16 *)(param_1 + 0xa)) {
func_801808B4((void *)param_1);
return;
}
if ((*(s32 *)(param_1 + 0x10) != 0) || (*(s32 *)(param_1 + 0x18) != 0)) {
func_8012DBD0(param_1, 0x50,
*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x12) + 0x800, 0x1D);
}
bVar1 = *(u8 *)(param_1 + 0xc2);
switch (bVar1) {
case 0:
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) -= 0x100;
*(s32 *)(param_1 + 0x1c) += 1;
if (0x28 < *(s32 *)(param_1 + 0x1c)) {
goto LAB_80180730;
}
uVar3 = func_8012CC64(param_1, &D_8019E704);
if ((uVar3 & 0x4000) != 0) {
goto LAB_80180644;
}
if ((uVar3 & 0x2000) != 0) {
if ((uVar3 & 0xff) == 0x1a) {
goto LAB_8018066C;
}
*(u8 *)(param_1 + 0xc2) = 2;
func_80143B6C(param_1, 1);
*(s32 *)(param_1 + 0x14) = 0xFFF30000;
*(s32 *)(param_1 + 0x1c) = 0;
}
goto LAB_80180740;
case 2: {
s32 saved14;
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) -= 0x100;
*(s32 *)(param_1 + 0x1c) += 1;
if (0x28 < *(s32 *)(param_1 + 0x1c)) {
goto LAB_80180730;
}
saved14 = *(s32 *)(param_1 + 0x14);
uVar3 = func_8012CC64(param_1, &D_8019E704);
if ((uVar3 & 0x4000) != 0) {
goto LAB_80180644;
}
if ((uVar3 & 0x2000) != 0) {
if ((uVar3 & 0xff) == 0x1a) {
goto LAB_8018066C;
}
func_80143B6C(param_1, 1);
*(s32 *)(param_1 + 0x14) = saved14;
*(u8 *)(param_1 + 0xc2) = 3;
*(s32 *)(param_1 + 0x1c) = 0;
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = 0;
}
goto LAB_80180740;
}
case 3:
*(s32 *)(param_1 + 0x10) = *(s32 *)(param_1 + 0x10) * 15 / 16;
*(s32 *)(param_1 + 0x18) = *(s32 *)(param_1 + 0x18) * 15 / 16;
if ((*(u8 *)(param_1 + 0xc3) & 1) == 0) {
goto CASE3_CC64;
}
uVar3 = func_8012CC1C(param_1, &D_8019E704);
if ((uVar3 & 0x6000) != 0) {
goto CASE3_TAIL;
}
goto LAB_80180730;
CASE3_CC64:
uVar3 = func_8012CC64(param_1, &D_8019E704);
if ((uVar3 & 0x4000) == 0) {
goto CASE3_NO4000;
}
LAB_80180644:
func_8012B23C(param_1);
*(u8 *)(param_1 + 0xc2) = 4;
goto LAB_80180740;
CASE3_NO4000:
if ((uVar3 & 0x2000) == 0) {
goto CASE3_TAIL;
}
if ((uVar3 & 0xff) != 0x1a) {
goto CASE3_SETFLAG;
}
LAB_8018066C:
func_801808B4((void *)param_1);
return;
CASE3_SETFLAG:
*(u8 *)(param_1 + 0xc3) = *(u8 *)(param_1 + 0xc3) | 1;
CASE3_TAIL:
if ((*(u32 *)(param_1 + 0x1c) & 3) == 3) {
func_80143B6C(param_1, 1);
}
*(s32 *)(param_1 + 0x1c) += 1;
if (*(s32 *)(param_1 + 0x1c) < 0x11) {
goto LAB_80180740;
}
if ((uVar3 & 0x6000) == 0) {
goto LAB_80180730;
}
goto CASE34_TAIL;
case 4:
uVar3 = func_8012CBA4(param_1);
if ((uVar3 & 0x2000) == 0) {
goto CASE4_COUNTER;
}
CASE34_TAIL:
func_80131C78(param_1);
goto LAB_80180740;
CASE4_COUNTER:
if ((*(u32 *)(param_1 + 0x1c) & 3) == 3) {
func_80143B6C(param_1, 1);
}
*(s32 *)(param_1 + 0x1c) += 1;
if (*(s32 *)(param_1 + 0x1c) < 0x3d) {
goto LAB_80180740;
}
goto LAB_80180730;
default:
goto LAB_80180740;
}
LAB_80180730:
func_80131E00(param_1, 0xd);
return;
LAB_80180740:
func_801809A0(param_1);
return;
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_80180764);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_801807C8);
void func_80180814(void *a0) {
s32 v1 = *(s32 *)((s32)a0 + 0x20);
*(s32 *)((s32)a0 + 0x1C) = 0x1E;
*(s16 *)((s32)a0 + 0x5C) = 0;
*(s16 *)(v1 + 0x10) = 0;
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_8018082C);
extern void func_80180A84(void *a0);
extern s32 func_8002A04C(struct S *a0);
extern void func_801808B4(void *a0);
void func_8018087C(void *a0) {
func_80180A84(a0);
func_8002A04C((struct S *)a0);
func_801808B4(a0);
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_801808B4);
extern void func_80016714(void *a0, s32 a1);
extern void func_8012C098(void);
void func_80180968(s32 param_1) {
((void (*)(s32 *, s32))func_80016714)(*(s32 *)(param_1 + 0xd0), 0x38);
((void (*)(s32))func_8012C098)(param_1);
}
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_801809A0);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_80180A84);
INCLUDE_ASM("asm/ov_SC03_108/nonmatchings/ov_SC03_108_jr_8017BEBC", func_80180B7C);
File diff suppressed because it is too large Load Diff
+172 -1
View File
@@ -4634,4 +4634,175 @@ void func_801819C4(void *a0) {
}
INCLUDE_ASM("asm/ov_SC03_117/nonmatchings/ov_SC03_117_jr_8017BEBC", func_80181A30);
#include "common.h"
/* func_80181A30 (ov_SC03_117, ov_SC03_117_jr_8017BEBC) — MATCH (148 ins)
*
* Tapered-beam / laser quad renderer. Builds a 4-vertex SVECTOR quad in local
* space (x = 0 .. arg0->len, y = -/+ half-width, the near half-width at 0x18 and
* the far one at 0x1A), rotates it with the caller's angle triple (0x08) through
* func_80049CAC + func_80017E8C, allocates ONE 0x24-byte POLY_G4 out of
* func_80010A08, projects the quad straight into the packet's four xy slots with
* RotTransPers4, and links the packet into the current double-buffer OT with the
* inline PSY-Q addPrim pair. If arg0->flags (0x1C) has bit 30, it also emits a
* 1-word 0xE1000200 DR_TPAGE prim carrying the semi-transparency mode
* ((flags >> 23) & 0x60) and chains that in front of the poly.
*
* FRAME 0x88 = 0x28 outgoing args (RotTransPers4 takes 10) + v[4] (0x20) +
* mtx (0x20) + opz/flag (8) + 6 saved regs (0x18). Locals are declared in
* increasing-address order, so v/mtx/opz/flag land at 0x28/0x48/0x68/0x6C.
*
* LEVERS (each byte-checked against asm/.../func_80181A30.s)
*
* - `ot` is computed BEFORE the `len == 0` early return: sched1 never moves an
* insn across a bb boundary, and the target has the whole
* lui/lhu/lui/addiu/sll run plus `addu $s4,$v0,$v1` (the beqz delay slot)
* ahead of the branch. Computing it after the guard costs 5 insns of drift.
*
* - `(otz << 2) + (u32)ot`, NOT `ot + otz`: gcc keeps the written operand order
* for the `addu`, and the target is `addu $s0, $v0, $s4` (offset first).
* Same reason `&D_800A6610[idx << 14]` gives `addu $s4, $v0, $v1`.
*
* - `mp` (a pointer local bound to &mtx) is what puts the matrix address in a
* callee-saved register ($s0) and turns both call-site setups into `addu
* $aN,$s0,$zero` moves. Passing &mtx directly re-materialises
* `addiu $aN,$sp,0x48` at each site. The mtx.t[] stores stay sp-relative
* because they are written through the array, not through mp.
*
* - Every `*(u16 *)(arg0 + N)` / `*(u32 *)(arg0 + N)` is spelled out at each
* use instead of being cached in a local: the quad stores take the address of
* v[], and poly is a heap pointer, so gcc cannot disambiguate them from the
* arg0 loads and re-loads each one — which is exactly the target's two
* `lhu 0x18($s2)`, two `lhu 0x1A($s2)`, two `lw 0x10($s2)`, two
* `lw 0x14($s2)`. `len` IS a local (one `lhu 0x6($s2)`, three uses).
*
* - `u16` reads + `>> 1`: `lhu` then `srl` (combine rewrites the ashiftrt to
* lshiftrt because the zero_extend proves the sign bit clear), then `negu`.
*
* - `otz` is u32 so the 0x1000 bound test emits `sltiu`, and the `+ 1` is a
* separate statement AFTER the flag test so dbr can steal it for the `bnez`
* delay slot (the target keeps `addu $a0,$v0,$zero` and `addiu $a0,$a0,1` as
* two insns; `ret + 1` in one expression folds them into one `addiu`).
*
* - THE TAIL CLUSTER (the last 9 mismatches). Two facts decide it:
* (a) `q[3] = 1` (byte 3) OVERLAPS the word at q[0], so sched sees a real
* memory dependence and the `lw 0($v0)` MUST be written after the sb —
* reading `*(u32 *)q` before it inverts the dep into an anti-edge and
* drags the load above `sb`/`lw 0x1C($s2)` (2 mismatches, var_e).
* (b) With the load after the sb, its dest is a single-set pseudo, so
* `adjust_priority`'s BIRTHING BOOST (sched.md §1.7) raises it to
* 0x7f000001, it wins every tie the moment it is ready, and it sinks
* past `or`/`sw 4($v0)` (9 mismatches). The target has it competing
* normally at priority 2 and winning the T-16 tie against the `ori`
* only on `potential_hazard` (memory beats ALU).
* `register u32 qt __asm__("$4")` fixes BOTH the boost and the allocation in
* one zero-byte edit: it is the whole residual. (A dead
* `__asm__ volatile("":"=r"(qt))` boost-kill also reorders correctly but
* leaves the $a0/$a1 pair swapped — 5 mismatches; sharing ONE temp across
* both addPrim halves kills the boost too but makes it a global allocno that
* loses $v1 in the FIRST addPrim — 7 mismatches. The pin alone is minimal.)
*
* DECLARATIONS / integration surface: `func_80049CAC` and `D_800B9A02` are
* spelled VERBATIM as the destination TU already has them at file scope
* (ov_SC03_117_jr_8017BEBC.c L2643 and L2464/L2466), so they merge silently.
* `D_800A6610`, `func_80010A08`, `func_80017E8C` and `RotTransPers4` have NO
* file-scope declaration anywhere in that TU, so they are block-scoped here to
* keep the blast radius on the rest of the TU at zero. The two local typedefs
* do not collide with any name in the TU.
*/
typedef struct { s16 vx, vy, vz, pad; } SV_1A30;
typedef struct { s16 m[3][3]; s32 t[3]; } MTX_1A30; /* 0x20 bytes */
void func_80181A30(s16 *arg0)
{
extern u8 D_800A6610[];
extern short D_800B9A02;
extern void func_80049CAC(s32 a0, s32 a1);
extern void *func_80010A08(s32);
extern void func_80017E8C(void *);
extern s32 RotTransPers4(void *, void *, void *, void *,
s32 *, s32 *, s32 *, s32 *, s32 *, s32 *);
SV_1A30 v[4]; /* sp+0x28 */
MTX_1A30 mtx; /* sp+0x48 */
s32 opz; /* sp+0x68 */
s32 flag; /* sp+0x6C */
u32 *ot;
u32 *otp;
u8 *poly;
u8 *q;
void *mp;
u16 len;
u32 otz;
register u32 qt __asm__("$4"); /* §17 pin — kills the birthing boost AND
keeps the $a0/$a1 pair in target order */
ot = (u32 *)&D_800A6610[(*(u16 *)&D_800B9A02) << 14];
len = *(u16 *)(arg0 + 3);
if (len == 0) {
return;
}
v[0].vx = 0;
v[0].vy = -(*(u16 *)(arg0 + 0xC) >> 1);
v[0].vz = 0;
v[1].vx = 0;
v[1].vy = *(u16 *)(arg0 + 0xC) >> 1;
v[1].vz = 0;
v[2].vx = len;
v[2].vy = -(*(u16 *)(arg0 + 0xD) >> 1);
v[2].vz = 0;
v[3].vx = len;
v[3].vy = *(u16 *)(arg0 + 0xD) >> 1;
v[3].vz = 0;
mp = &mtx;
func_80049CAC((s32)(arg0 + 4), (s32)mp);
mtx.t[0] = arg0[0];
mtx.t[1] = arg0[1];
mtx.t[2] = arg0[2];
poly = (u8 *)func_80010A08(0x24);
*(u32 *)(poly + 0x04) = *(u32 *)(arg0 + 8);
*(u32 *)(poly + 0x0C) = *(u32 *)(arg0 + 8);
*(u32 *)(poly + 0x14) = *(u32 *)(arg0 + 0xA);
*(u32 *)(poly + 0x1C) = *(u32 *)(arg0 + 0xA);
poly[3] = 8; /* setlen(poly, 8) */
poly[7] = 0x38; /* setcode POLY_G4 */
func_80017E8C(mp);
otz = RotTransPers4(&v[0], &v[1], &v[2], &v[3],
(s32 *)(poly + 0x08), (s32 *)(poly + 0x10),
(s32 *)(poly + 0x18), (s32 *)(poly + 0x20),
&opz, &flag);
if ((flag & 0xFFFFEFFF) != 0) {
return;
}
otz = otz + 1;
if (otz >= 0x1000) {
return;
}
otp = (u32 *)((otz << 2) + (u32)ot);
/* addPrim(otp, poly) */
*(u32 *)poly = (*(u32 *)poly & 0xFF000000) | (*otp & 0xFFFFFF);
*otp = (*otp & 0xFF000000) | ((u32)poly & 0xFFFFFF);
if (*(u32 *)(arg0 + 0xE) & 0x40000000) {
poly[7] |= 2; /* semi-transparent */
q = (u8 *)func_80010A08(8);
q[3] = 1; /* setlen(q, 1) */
qt = *(u32 *)q;
*(u32 *)(q + 4) = ((*(u32 *)(arg0 + 0xE) >> 23) & 0x60) | 0xE1000200;
/* addPrim(otp, q) */
*(u32 *)q = (qt & 0xFF000000) | (*otp & 0xFFFFFF);
*otp = (*otp & 0xFF000000) | ((u32)q & 0xFFFFFF);
}
}
+522 -2
View File
@@ -3090,7 +3090,7 @@ extern void func_80139954(void);
extern void func_80139A68(s32 a0, u16 a1);
extern s16 func_8014168C(s16 a0);
extern void func_80188778(void);
extern s32 func_80189540(s32 a0, s16 a1);
extern s32 func_80189540(s16 a0, s16 a1);
extern s16 func_80189E54(s32 a0);
extern void func_801878E8(void);
extern s16 D_801B9414[];
@@ -3277,7 +3277,527 @@ s32 func_80188E1C(s32 param_1, s32 param_2) {
INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_80188E1C", func_80189214);
INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_80188E1C", func_80189540);
/* func_80189540 — tier 3 (compiler-internals). STATE: MATCH (551/551).
*
* ==== WAVE-3 RE-VERIFICATION (2026-08-11) ====
* Re-gated against the CURRENT carve
* asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_80188E1C/func_80189540.s
* -> MATCH (551 ins). Two edits were needed vs the archived backlog copy:
* (1) SIGNATURE. The archived copy had been "fixed" to `s32 arg0` (to agree
* with the host TU's file-scope prototype); that costs exactly -2 ins:
* the target's `addiu a0,a0,-1; sll 16; sra 16; sltiu 0xF` switch-index
* range check is the HImode re-extension of a `short` parameter after the
* minval subtract. With `s32` gcc emits `addiu; sltiu` only (549 ins).
* The first parameter IS `s16`. -> integration: the host TU's
* src/ov_SC04_018/ov_SC04_018_jr_80188E1C.c:3093
* `extern s32 func_80189540(s32 a0, s16 a1);` must become `(s16, s16)`
* or the TU dies with a HARD "conflicting types" (byte-probed).
* (2) SCOPE of Rec / D_801E7774. The host TU already carries a BLOCK-scope
* `extern s32 *D_801E7774[];` (:3162) inside another function. A
* FILE-scope `extern Rec *D_801E7774[];` here is a HARD "conflicting
* types" error; the same decl at BLOCK scope is only a
* "type mismatch with previous external decl" WARNING (both byte-probed).
* So the Rec typedef + the D_801E7774 decl now live inside `case 11`.
* Codegen is unchanged — still MATCH at 551.
* Every other extern in this file was diffed against the host TU: all agree
* (func_8002D4C8/800291B4/800291A0/80189E54/800D0F8C/800D0EC4/800D0F0C/
* 800D0FE0/800D128C/80029124/80029514/8017ADE8/80139A68, D_801E7030,
* D_801E76FC, D_801E76F4, D_801E77B8, D_800A6586, D_8010EDEE, D_8010EDF2,
* D_80115126, D_80115148, D_801E7700, D_801E3CEC, D_80115112, D_801EC928)
* or are absent from the host TU entirely (D_8011511A, D_8011514C/4E,
* D_8010EDEC, D_8010EDF1, D_801E778C, D_801E96C8, D_801B9420, D_801E3E1C,
* D_801E9664, D_801E92E0, D_801E7794, D_801E96A4, func_80186E24,
* func_80189E14, func_80139A44).
* ==== end wave-3 note ====
*
* Overlay ov_SC04_018 (byte-identical twin ov_SC04_019), carve region
* ov_SC04_018_jr_801878E8 (551 ins). NB the prompt's asm path said
* `jr_8017AE2C`; the real carve is `jr_801878E8`:
* asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_801878E8/func_80189540.s
*
* ---- TIER-3 CRACKS (the 4 residual ins -> 0), both from reading vanilla
* tools/reference/gcc-2.7.2/ sources. GENERALIZABLE — cookbook fodder. ----
*
* T3-A (was idx 255/256, case 10 `move s0,s1` vs `sra` order — S2-boost class):
* ROOT CAUSE chain: (1) the RTL dump showed the order is GENERATION order, not
* a sched tie: cse folds the (s16) arg extension's `sra` INTO the a0-load
* position (the original sra insn dies), splitting the sll/sra pair around the
* statement-positioned copy. (2) The target needs the copy SUNK between
* `sra` and the a1-copy — only sched1's birthing boost (sched.c:2469
* birthing_insn_p: pattern SET(REG,..), REG_N_SETS(dest)==1) does that, and a
* `register __asm__("$16")` pin kills it (hard $16 is multi-set function-wide).
* (3) Plain-unpinning instead DELETES the copy: local-alloc combine_regs
* (local-alloc.c:1722) ties a SET(reg,reg) copy whose source dies there
* (byte-seen: 550 ins, copy gone).
* LEVER: unpin w10 AND write the copy as an asm-move
* __asm__("addu %0,%1,$zero" : "=r"(w10) : "r"(b10));
* — an asm SET is NOT a SET(reg,reg), so combine_regs cannot tie it, yet its
* PATTERN is still SET(REG, asm_operands), so birthing_insn_p BOOSTS it →
* it sinks to just before its first consumer (the a1-copy) = target position;
* global-alloc hands the call-crossing pseudo $16 (first callee-saved in
* order; $16 free — slot dead at the sll once the copy sinks). Net-zero
* ref-count on b10 (the asm read replaces the copy read) → no K2 ripple.
*
* T3-B (was idx 133/135, case 14 lbu dest $s1-vs-$v0 — cse from_plus class):
* ROOT CAUSE: cse.c:5577 fold_rtx `from_plus` association: for
* (PLUS reg const) it does lookup_as_function(reg, PLUS) in reg's class and
* combines the constants (c14 = n14+0x62 → lbu_temp+0x63), so the +1 chain
* must be hidden — but the in-place `n14=tbl[i]; n14=n14+1` hides it by
* making the load dest BE $s1 (wrong lbu dest). lookup_as_function validates
* entries with exp_equiv_p(...,validate=1) — reg_tick staleness of ANY reg
* inside the expr kills the entry.
* LEVER: name the load temp, keep the one-statement +1 (right lbu dest), and
* stale THE TEMP (not n14) with a dead-output non-volatile re-tie:
* t14 = D_801E77B8[i14]; n14 = t14 + 1;
* __asm__("" : "=r"(t14) : "0"(t14)); c14 = n14 + 0x62;
* cse (both passes) re-SETs t14 → reg_tick[t14]++ → (plus t14 1) fails
* validation → NO fold; then FLOW deletes the dead-output asm BEFORE
* combine/sched/regalloc ever see it (cse_expr.md §2 boundary #2) → zero
* downstream ripple. (Re-tie on n14 itself instead: 4 mism — it ripples the
* later sll temp's allocation. A "0"-tied t14→n14 asm-copy: +1 ins — reload
* materializes the $17 copy because t14 first-fits into the lbu scratch.)
*
* ---- tier-2 provenance below (levers L1-L8 still load-bearing) ----
* Case-body SOURCE ORDER is the asm's block layout order:
* {1,2,4,6}, 3, 5, 12, 13, 14, 10, 7, 8, 15, 11 (9 + out-of-range = default)
*
* ---- the levers that closed this, in the order they mattered ----
* L1 CROSS-JUMP TAIL PLACEMENT (-8 ins). The shared `func_8002D4C8(0x472,0);
* return 0;` error tail is an EXPLICIT label (`bad472`) at the very END of
* the function, reached by `goto`. gcc-2.7.2's jump.c keeps the
* PHYSICALLY-LAST copy of a merged tail; only a last copy that is a bare
* `li a0,0x472` block lets the "jump around jump" inversion turn the four
* `beq/bne …; li a0; j tail` triples into single conditional branches to
* .L80189DA8. Writing the call literally at each site instead cross-jumped
* into case 3's body and cost 4x2 instructions.
* L2 `u8`-RETURN BLOCKS THE AND-FOLD. `extern u8 ((u8 (*)(s32))func_800291B4)(s32)` (NOT
* `s32` + an explicit `& 0xFF`). With `s32`+mask, combine folds
* `(and (and x 0xff) 0xf0)` -> `(and x 0xf0)` and the second `andi` reads
* the raw call result; the zero_extend from a QImode return does not fold,
* so the target's `andi $s0,$v0,0xFF; andi $v1,$s0,0xF0` survives.
* (Byte-proven in .run/s46/casc/micro2.c variant a2.)
* L3 FRAME KNOB. Target frame is 0x38 (vars=16); ours computes vars=8, so an
* 8-byte unreferenced local array is carried. It emits NO code but fixes
* all 11 prologue/epilogue offsets. This is the one honest GUESS in the
* file — the real cause of the target's extra 8 bytes of `vars` is unknown.
* L4 ADDRESS-IN-A-REGISTER for the D_8011514C/D_80115142 pair: a plain
* `u8 *q = &D_8011514C` is constant-folded into 4 separate `lui/%lo`; the
* asm launder `__asm__("" : "=r"(q) : "0"(&D_8011514C))` forces `la` =
* lui+addiu and the target's `0($a1)` / `-0xA($a1)` displacements.
* L5 DIVISOR from the magic constant: 0x66666667 + `sra 2` is /10, not /5
* (0x66666667 + `sra 1` would be /5). So case 14 is `x * 9 / 10`.
* L6 REGISTER PINS (cookbook §17/§72). gcc's global.c allocno priority is
* refs/live-length, which consistently gave OUR earlier-born value $s0
* where the target gives it to the later-born one. Pinning splits the tie.
* Pins are per-switch-arm so their live ranges are disjoint by control flow;
* within an arm every pinned pair was checked for range overlap (the one
* real hazard, `slot`/`w10` both on $16, is separated by the `sl16` temp so
* `slot` is dead before `w10` is born — verified in the emitted asm).
* L7 SCHEDULING BARRIER: `__asm__ __volatile__("")` between the volatile
* reload and the `->unk4` read in case 11's .L80189CFC path stops gcc's
* sched from hoisting `lw ...,4(...)` into the load-delay slot (that single
* barrier took the diff 58 -> 5).
* L8 The `.L80189D80` tail (`func_8002D4C8(0x45D,0); D_80115112++;`) is also
* an explicit label (`tail45D`) for the same reason as L1.
*
* ---- former tier-2 residual (SOLVED by T3-A/T3-B above) ----
* idx 133/135 case 14 lbu dest -> T3-B (stale-the-temp re-tie)
* idx 255/256 case 10 move/sra order -> T3-A (asm-move + boost sink)
*/
/* ---- functions ---- */
extern void func_8002D4C8(s32, s32);
extern s32 func_800291B4(s32);
extern void func_800291A0(s32, s32);
extern void func_80186E24(void);
extern s16 func_80189E54(s32);
extern void func_80189E14(s32);
extern s32 func_800D0F8C(s32);
extern s32 func_800D0EC4(void);
extern void func_800D0F0C(s32, s32);
extern int func_800D0FE0(int);
extern void func_800D128C(s32, s32);
extern void func_80029124(s32, s32);
extern void func_80029514(s32);
extern s32 func_8017ADE8(s32);
extern void func_80139A44(s32, s32);
extern void func_80139A68(s32, u16);
/* ---- data ---- */
extern u16 D_8011511A;
extern s16 D_801E7030;
extern s16 D_8011514E;
extern u8 *D_801E76FC;
extern s16 D_800A6586[];
extern u8 D_8011514C;
extern u8 D_801E77B8[];
extern u8 *D_801E76F4;
extern s16 D_8010EDEC; /* record +0x0, s16 (12-byte stride) */
extern s16 D_8010EDEE; /* record +0x2, s16 */
extern u8 D_8010EDF1; /* record +0x5, u8 */
extern u8 D_8010EDF2; /* record +0x6, u8 */
extern s16 D_80115126;
extern u8 D_80115148[];
extern s16 D_801E778C;
extern s32 D_801E96C8;
extern s32 D_801E7700;
extern void (*D_801E3CEC[])(void);
extern s8 D_801B9420[];
extern s32 D_801E3E1C[];
extern s32 D_801E9664;
extern u16 D_80115112;
extern s32 D_801EC928;
extern s32 D_801E92E0;
extern s16 D_801E7794;
extern s32 D_801E96A4;
#define REC_S16(base, idx) (*(s16 *)((u8 *)&(base) + (s32)(idx) * 0xC))
#define REC_U16(base, idx) (*(u16 *)((u8 *)&(base) + (s32)(idx) * 0xC))
#define REC_U8(base, idx) (*(u8 *)((u8 *)&(base) + (s32)(idx) * 0xC))
s32 func_80189540(s16 arg0, s16 arg1)
{
/* frame knob: the target's frame is 0x38 (vars=16); ours is vars=8 without
* this 8-byte unreferenced local. Emits no code. */
s32 unused_[2];
switch (arg0) {
case 1:
case 2:
case 4:
case 6:
if (arg1 == 2) {
return -1;
}
func_8002D4C8(0x46F, 0);
D_8011511A = arg1 + 1;
return 0;
case 3:
if (arg1 == 2) {
return -1;
}
D_8011511A = 2;
func_8002D4C8(0x46F, 0);
return 0;
case 5:
if (arg1 == 1) {
D_801E7030 = 1;
func_8002D4C8(0x474, 0);
return -1;
}
if (arg1 == 3) {
return -1;
}
func_8002D4C8(0x46F, 0);
if (arg1 != 0) {
D_8011511A = arg1;
} else {
D_8011511A = 2;
}
return 0;
case 12:
D_8011511A = 3;
D_8011514E = 0;
func_8002D4C8(0x46F, 0);
return 0;
case 13:
{
register s32 f13 __asm__("$16");
register s32 i13 __asm__("$17");
register s32 c13 __asm__("$18");
register u8 *q __asm__("$5");
s16 d;
i13 = D_801E76FC[arg1];
c13 = i13 + 0x62;
f13 = ((u8 (*)(s32))func_800291B4)(c13);
if ((f13 & 0xF0) != 0x80) {
goto bad472;
}
if (func_80189E54(-D_800A6586[i13]) != 0) {
L801896C8:
func_80189E14(3);
goto bad472;
}
func_800291A0(c13, f13 | 0x40);
func_80186E24();
__asm__ __volatile__("" : "=r"(q) : "0"(&D_8011514C));
d = (s8)q[0] - (s8)q[-0xA];
if (d >= 6) {
q[-0xA] = q[0] - 5;
} else if (d < 0) {
q[-0xA] = q[0];
}
func_80189E14(1);
func_8002D4C8(0x5EE, 0);
return 0;
}
case 14:
{
register s32 f14 __asm__("$16");
s32 i14;
register s32 n14 __asm__("$17");
s32 t14;
s32 c14;
i14 = arg1;
t14 = D_801E77B8[i14];
n14 = t14 + 1;
__asm__("" : "=r"(t14) : "0"(t14)); /* stales (plus t14 1) in cse; dead output -> deleted by flow */
c14 = n14 + 0x62;
f14 = ((u8 (*)(s32))func_800291B4)(c14);
if ((f14 & 0xF0) != 0xC0) {
goto bad472;
}
func_80189E54(D_800A6586[n14] * 9 / 10);
func_800291A0(c14, f14 & 0xBF);
func_80186E24();
D_801E77B8[i14] = 0xFF;
func_80189E14(4);
func_8002D4C8(0x5EE, 0);
return 0;
}
case 10:
{
s32 b10 = D_801E76F4[arg1];
s32 m10;
s32 w10;
__asm__ __volatile__("" : "=r"(m10) : "0"(b10));
if (m10 < 0x6F) {
register s16 slot __asm__("$16");
register s16 sraw __asm__("$2");
s16 val;
s16 x;
if (m10 == 0xA) {
if (func_800D0F8C(0xA) != 0) {
goto bad472;
}
}
sraw = ((s16 (*)(void))func_800D0EC4)();
slot = sraw;
if (sraw == 0) {
func_80189E14(2);
func_8002D4C8(0x45F, 0);
return 0;
}
x = D_801E778C;
if (x != 0) {
if (D_80115126 == 0) {
val = REC_S16(D_8010EDEC, b10) * (100 - x) / 100;
} else {
val = REC_U16(D_8010EDEC, b10) - x;
}
} else {
val = REC_U16(D_8010EDEC, b10);
}
if (func_80189E54(-val) != 0) {
func_80189E14(3);
func_8002D4C8(0x472, 3);
return 0;
}
func_8002D4C8(0x5EE, 0);
__asm__("addu %0,%1,$zero" : "=r"(w10) : "r"(b10));
func_800D0F0C(slot, w10);
if (w10 == 0xA) {
func_80186E24();
}
} else {
if (func_80189E54(-REC_S16(D_8010EDEC, m10)) != 0) {
goto L801896C8;
}
func_800D128C(b10, 0);
}
func_80189E14(1);
return 0;
}
case 7:
{
s32 c7;
s32 k7;
s32 a7;
L801899B0:
c7 = (s32)arg1 + 0x2F;
k7 = ((u8 (*)(s32))func_800291B4)(c7);
if (k7 == 0) {
goto bad472;
}
a7 = REC_S16(D_8010EDEE, k7);
if (a7 == 0 || D_80115126 != REC_U8(D_8010EDF2, k7)) {
func_80189E14(5);
goto bad472;
}
func_80189E54(a7);
((void (*)(s32))func_800D0FE0)(c7);
if (k7 == 0xA) {
func_80186E24();
}
func_80189E14(4);
func_8002D4C8(0x5EE, 0);
return 0;
}
case 8:
{
s32 k8;
register s32 f8 __asm__("$2");
register s32 g8 __asm__("$16");
register s32 t8 __asm__("$2");
register s32 cv __asm__("$2");
s32 p8;
register u16 *c __asm__("$3");
if ((*(u8 *)D_80115148) != 0) {
goto L801899B0;
}
k8 = ((u8 (*)(s32))func_800291B4)((s32)arg1 + 0x2F);
if (k8 == 0) {
goto bad472;
}
f8 = REC_S16(D_8010EDEC, k8);
if (f8 >= 0) {
D_801E7700 = (s32)&D_801E96C8;
goto bad472;
}
__asm__ __volatile__("" : "=r"(g8) : "0"(f8));
t8 = g8 & 0x4000;
if (t8 != 0) {
p8 = ((s32 *)D_801E3CEC)[k8];
} else {
p8 = D_801E3E1C[(REC_U8(D_8010EDF1, k8) - 0x14) >> 1];
}
D_801E7700 = (s32)&D_801E9664;
func_80139A44(p8, 0);
c = &D_80115112;
cv = *c;
cv = cv + 1;
*c = cv;
return 0;
}
case 15:
{
register u16 f15 __asm__("$16");
register s32 t15 __asm__("$2");
s32 c15;
s32 k15;
s32 n15;
c15 = (s32)arg1 + 0x2F;
k15 = ((u8 (*)(s32))func_800291B4)(c15);
f15 = REC_U16(D_8010EDEC, k15);
n15 = REC_U8(D_8010EDF1, k15);
t15 = f15 & 0x4000;
if (t15 != 0) {
s32 m15;
__asm__ __volatile__("" : "=r"(m15) : "0"(n15));
func_80029124(m15, 1);
((void (*)(s32))func_800D0FE0)(c15);
D_801E7030 = n15 - 0x1C;
if (m15 != 0x1F) {
return 0;
}
func_80029514(0x64);
func_80029124(0xEB, 1);
func_80029124(0x91, 1);
func_800291A0(0xCE, 1);
return 0;
}
func_800D0F0C(c15, n15);
return 0;
}
case 11:
{
typedef struct Rec {
s32 unk0;
s32 unk4;
s32 unk8;
void (*unkC)(void);
} Rec;
extern Rec *D_801E7774[];
Rec **pp;
Rec *r;
Rec **pp2;
register s32 dv __asm__("$2");
Rec **base;
Rec *r2;
s32 t;
s32 u;
if (D_80115126 == 4) {
if ((*(u8 *)D_80115148) == 0) {
s32 i11 = arg1;
if (D_801E7774[i11] != 0) {
goto bad472;
}
if (func_80189E54(D_801B9420[i11]) != 0) {
goto L801896C8;
}
D_801E7700 = (s32)&D_801EC928;
D_80115112 = D_80115112 + 1;
((void (*)(s32, s32))func_80139A68)((s16)(arg1 + 1), 0);
func_8002D4C8(0x5EE, 0);
return 0;
}
base = D_801E7774;
pp = &base[arg1];
r = *pp;
if (r == 0) {
goto bad472;
}
if (r->unk4 == 0) {
goto bad472;
}
D_801E7700 = r->unk4;
if (r->unkC != 0) {
r->unkC();
}
((void (*)(s32))func_8017ADE8)((*pp)->unk8);
goto tail45D;
}
base = D_801E7774;
pp2 = &base[arg1];
r2 = *pp2;
if (r2 == 0) {
goto bad472;
}
t = (*(Rec * volatile *)pp2)->unk8;
__asm__ __volatile__("");
D_801E7700 = r2->unk4;
((void (*)(s32))func_8017ADE8)(t);
u = D_801E7700;
D_801E7794 = 0;
if (u == (s32)&D_801E92E0) {
D_801E7794 = 1;
}
if (u == (s32)&D_801E96A4) {
D_801E7794 = 2;
}
tail45D:
func_8002D4C8(0x45D, 0);
dv = D_80115112;
dv = dv + 1;
D_80115112 = dv;
return 0;
}
}
goto done;
bad472:
func_8002D4C8(0x472, 0);
done:
return 0;
}
INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_80188E1C", func_80189DDC);
+44 -1
View File
@@ -4415,7 +4415,50 @@ fail:
}
INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_80180128);
extern s32 D_80126B60;
extern void func_8012B1B4(s32 a0, s32 a1);
extern void func_8012CBCC(s32 a0);
extern s32 func_8017EC48(s32 a0, s32 a1);
extern s32 func_8012B8E4(s32 arg0, s32 arg1);
void func_80180128(s32 a0)
{
s32 sp10[3];
if (*(s32 *)(a0 + 8) >= D_80126B60 - 0x200000) {
if (*(s32 *)(a0 + 0x48) >= 0) {
*(s32 *)(a0 + 0x48) = -0x8000;
*(s32 *)(a0 + 0x14) = *(s32 *)(a0 + 0x14) >> 1;
}
} else {
if (D_80126B60 - 0x180000 >= *(s32 *)(a0 + 8)) {
if (*(s32 *)(a0 + 0x48) <= 0) {
*(s32 *)(a0 + 0x48) = 0x8000;
*(s32 *)(a0 + 0x14) = *(s32 *)(a0 + 0x14) >> 1;
}
}
}
*(s32 *)(a0 + 0xDC) = *(s32 *)(a0 + 0xDC) >> 1;
sp10[0] = 0;
sp10[1] = 0;
sp10[2] = *(s32 *)(a0 + 0xDC);
func_8012B1B4(a0, (s32)sp10);
func_8012CBCC(a0);
func_8017EC48(a0, 0x51);
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) += func_8012B8E4(a0, 0x10);
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) &= 0xFFF;
*(u16 *)(a0 + 0x100) -= 1;
if (*(s16 *)(a0 + 0x100) == 0) {
*(s16 *)(a0 + 2) = 3;
*(u16 *)(a0 + 0x100) = 5;
*(s32 *)(a0 + 0x1C) = 0;
}
}
INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_8018025C);
+57 -1
View File
@@ -6602,7 +6602,63 @@ void func_80183CDC(s32 param_1) {
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_80183DA4);
extern s32 func_8012B608(s32 a0, s32 a1, s32 a2);
extern void func_8012B178(s32 a0, s32 a1);
extern s32 func_8018765C(s32 a0);
extern void func_801877E4(s32 a0);
extern s32 func_8012BDBC(s32 a0, s32 a1);
extern s32 func_8012BCCC(s32 a0);
extern s32 func_8012BEE8();
extern s32 rand(void);
void func_80183DA4(s32 param_1)
{
register s32 p __asm__("$17") = param_1;
s32 r;
s32 s0;
register s32 s2 __asm__("$18");
*(u16 *)(*(s32 *)(p + 0x20) + 0x12) += func_8012B608(*(s16 *)(*(s32 *)(p + 0x20) + 0x12), *(s32 *)(p + 0xE8), 8);
func_8012B178(p, 0xFFFB0000);
*(u32 *)(p + 0xE0) &= 0xFFFFFFBF;
if (func_8018765C(p) == 0) {
func_801877E4(p);
}
r = func_8012BDBC(p, 0x300);
if (r != 0) {
r = func_8012BCCC(p);
if (r < 0x100000) {
*(s16 *)(p + 2) = 4;
return;
}
} else {
r = func_8012BCCC(p);
if (r < 0x4000) {
*(s16 *)(p + 2) = 0xF;
return;
}
}
if ((*(u32 *)(p + 0xE0) & 0x40) != 0) {
return;
}
if (func_8012BEE8(p) == 0) {
return;
}
s0 = rand() % 1024;
s2 = *(s32 *)(p + 0xE8);
if ((rand() & 1) == 0) {
r = s2 - s0;
} else {
r = s2 + s0;
}
*(s32 *)(p + 0xE8) = r;
*(s32 *)(p + 0x1C) = (rand() % 64) + 0x80;
}
+191 -5
View File
@@ -5565,7 +5565,197 @@ void func_8018E5DC(void *arg) {
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018E9BC);
#include "common.h"
/* func_8018E9BC — ov_SC06_018 / ov_SC06_018_jr_80187AEC
*
* §160g STEP 0 HIT, in the DESTINATION TU ITSELF: func_8018E5DC
* (src/ov_SC06_018/ov_SC06_018_jr_80187AEC.c:5416, banked MATCH, 248 ins) is a
* near-verbatim template. Shared VERBATIM: the 0x60 gate + 0x1D snapshot, the
* 0x78/0x60 decrement (AND form), the 0x82&1 finisher, the C8/C9 pokes, the
* three func_8012C658 triple-spawns, both 8-iteration spawn loops (0x281/0x23),
* the RTP_SND block (&D_800AF648 $a0-pin idiom, 0x9F/0x13F, 0x77/0xEF, /0xA0),
* and the 0x76<0 else arm (0x8800/0x60/0xC1/0xC2).
*
* TWO DELTAS vs E5DC:
* (1) the triple-spawn constants: 0x12 is +4 here (E5DC has -4), and 0x1A
* runs -4 / 0 / +4. This changes WHICH constant CSEs: E5DC shared -4
* across 0x12+0x1A of block 1; here block 1's three constants are all
* distinct (4, -0x10, -4 -> $v0 reused serially) while block 3 shares
* +4 across 0x12+0x1A (-> $v1, with -0x10 in $v0). Byte-confirmed
* against the target at 8018EAFC / 8018EB2C / 8018EB58.
* (2) an EXTRA guard block between the second spawn loop and the RTP stores:
* h = *(s32*)(p+0x64); if (*(s16*)(h+0x36) == *(s16*)(p+0xFC))
* *(s32*)(h+0xCC) = 0; The target loads 0x64 ONCE into $a0 and reuses
* that base for the 0xCC store, so it must be a variable, not two loads.
*
* §76 LEVER (inherited from E5DC's @stuck, and reinforced here): the three
* spawn pointers AND this new 0x64 base are ONE function-scope variable `t`,
* not four block-scope pseudos. Reuse is what makes the allocno GLOBAL, and
* global is what makes block 1's forced $a0 (its constants monopolise $v0)
* bind blocks 2, 3 and the 0x64 block — all four are $a0 in the target. Four
* separate block-local pseudos each re-run local-alloc and take $v1 (lower in
* REG_ALLOC_ORDER).
*
* Regalloc target (identical to E5DC): p pinned $s1, spawn-ptr `iv` on $s0,
* loop counter $s2, the hoisted constant 2 on $s3.
*
* @class: regalloc-order
*/
extern s32 rand(void);
extern void func_8016AA50(s32, s32);
extern s32 func_8016B428(s32);
extern void func_80019064(void *);
extern void func_8002A520(int);
extern void func_8002A790(int);
extern void func_8002D4C8(s32, s32);
extern s32 func_8012C658(s32, s32, s32);
extern s32 func_8012C588(s32, s32);
extern u8 *func_8012913C(s32);
extern void func_8012C218(void *);
extern void func_8004914C(void *a0);
extern void func_800491AC(void *a0);
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
extern u8 D_801D1210;
void func_8018E9BC(void *arg) {
extern u8 D_800AF648;
/* L5: slot offsets are exact only through ONE struct (see the TU's other
RTP_SND sites) — rv at sp+0x10, sxy at sp+0x18, z sp+0x1C, flag sp+0x20. */
struct {
s16 rv[4]; /* sp+0x10 */
u16 sxy[2]; /* sp+0x18 */
s32 z; /* sp+0x1C */
s32 flag; /* sp+0x20 */
} L;
register u8 *p __asm__("$17"); /* $s1 */
s32 e;
s32 i;
s32 iv;
s32 t;
p = (u8 *)arg;
e = *(u8 *)(p + 0x5E);
if (*(s16 *)(p + 0x60) != 0) {
if (e == 0x1D) {
*(u16 *)(p + 0x82) = 0;
*(u16 *)(p + 0x7C) = *(u16 *)(p + 0x06);
*(u16 *)(p + 0x7E) = *(u16 *)(p + 0x0A);
*(u16 *)(p + 0x80) = *(u16 *)(p + 0x0E);
}
{
s32 dec;
s32 q = *(s32 *)(p + 0x78);
if (q != 0 && *(s16 *)(p + 0x60) != 0) {
dec = ((s32)*(s16 *)(p + 0x60) * (s32)*(s16 *)(q + 0x30)) >> 12;
if (dec < 1) dec = 1;
} else {
dec = *(s16 *)(p + 0x60);
}
*(u16 *)(p + 0x76) = *(u16 *)(p + 0x76) - dec;
((void (*)(void *, s32))func_8016AA50)(p, dec);
}
if (*(u16 *)(p + 0x82) & 1) {
((void (*)(void *))func_8016B428)(p);
func_80019064(&D_801D1210);
}
}
if (e != 0x1D) {
if (*(u8 *)(p + 0xC8)) func_8002A520(p);
if (*(u8 *)(p + 0xC9)) func_8002A790(p);
}
if (*(s16 *)(p + 0x76) < 0) {
t = func_8012C658(0x33, 3, (s32)p);
if (t != 0) {
*(s16 *)(t + 0x12) = 4;
*(s16 *)(t + 0x16) = -0x10;
*(s16 *)(t + 0x1A) = -4;
}
t = func_8012C658(0x33, 2, (s32)p);
if (t != 0) {
*(s16 *)(t + 0x12) = 4;
*(s16 *)(t + 0x16) = -0x10;
*(u16 *)(t + 0x1A) = 0;
}
t = func_8012C658(0x32, 2, (s32)p);
if (t != 0) {
*(s16 *)(t + 0x12) = 4;
*(s16 *)(t + 0x16) = -0x10;
*(s16 *)(t + 0x1A) = 4;
}
i = 0;
do {
iv = ((s32 (*)(s32, void *))func_8012C588)(0x281, p);
if (iv != 0) {
*(s32 *)(iv + 0x1C) = 2;
*(u16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10;
*(u16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10);
*(u16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10;
}
i++;
} while (i < 8);
i = 0;
do {
iv = (s32)func_8012913C(0x23);
if (iv != 0) {
s32 r;
s32 sv;
r = rand();
*(u16 *)(iv + 0x06) = *(u16 *)(p + 0x06) + (r & 0x3F) - 0x20;
r = rand();
*(u16 *)(iv + 0x0A) = *(u16 *)(p + 0x0A) - (r & 0x3F) - 0x20;
r = rand();
sv = *(u16 *)(p + 0x0E);
*(s32 *)(iv + 0x18) = 0;
*(s32 *)(iv + 0x14) = 0;
*(s32 *)(iv + 0x10) = 0;
*(u16 *)(iv + 0x0E) = sv + (r & 0x3F) - 0x20;
r = rand();
*(u16 *)(iv + 0x34) = (r & 0x17FF) + 0x1800;
}
i++;
} while (i < 8);
t = *(s32 *)(p + 0x64);
if (*(s16 *)(t + 0x36) == *(s16 *)(p + 0xFC)) {
*(s32 *)(t + 0xCC) = 0;
}
L.rv[0] = *(s32 *)(*(s32 *)(p + 0x20) + 0x48);
L.rv[1] = *(s32 *)(*(s32 *)(p + 0x20) + 0x4C);
L.rv[2] = *(s32 *)(*(s32 *)(p + 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.rv, (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 x = (s16)L.sxy[0];
s32 ax;
ax = x;
if (x < 0) {
ax = -x;
}
ax = ((0xA0 - ax) * 0x7F) / 0xA0;
func_8002D4C8(0xB32, (ax | 0x1000) & 0xFFFF);
}
func_8012C218((void *)p);
} else {
*(u16 *)(p + 0x5C) = 0x8800;
*(u16 *)(p + 0x60) = 0;
*(u8 *)(p + 0xC1) = 0;
*(u8 *)(p + 0xC2) = 0x10;
}
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018EDB8);
@@ -5914,7 +6104,3 @@ void func_8018F694(void)
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018FE0C);
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80187AEC", func_8018FF98);
File diff suppressed because it is too large Load Diff
+462 -2
View File
@@ -3043,8 +3043,468 @@ L80191000:
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8019059C", func_80191020);
#include "common.h"
/* §161c: the call site passes NO argument (the target sets up no $a0 — the param lives in $s0
and is never moved), yet the fleet-dominant spelling is `void func_8012B23C(s32 a0)`. The
K&R form (34 fleet uses) is the only one that both permits the 0-arg call AND stays
COMPATIBLE with the prototyped form if this TU ever gains one. */
extern void func_8012B23C();
extern void func_8012B1B4(s32 a0, s32 a1);
extern s32 rand(void);
extern void func_8004914C(void *a0);
extern void func_800491AC(void *a0);
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
extern s32 func_8004787C(s32 a0);
extern s32 func_80047948(s32 a0);
extern void func_8002D4C8(s32 a0, s32 a1);
extern u8 D_800AF648;
extern u8 D_801D1200[];
void func_80191020(s32 a0) {
struct {
s16 v[3]; /* sp+0x10 */
s16 pad; /* sp+0x16 */
u16 sxy[2]; /* sp+0x18 */
s32 z; /* sp+0x1C */
s32 flag; /* sp+0x20 */
} L;
if (*(s16 *)(a0 + 0xFC) != *(s16 *)(*(s32 *)(a0 + 0x64) + 0x36)) {
*(s16 *)(a0 + 2) = 5;
*(s16 *)(a0 + 0x34) = 0;
func_8012B23C();
func_8012B1B4(a0, (s32)D_801D1200);
*(s16 *)(a0 + 0x16) = (rand() & 3) - 0x1B;
*(s16 *)(a0 + 0xA) = *(u16 *)(a0 + 0xA) - 0x38;
*(s16 *)(a0 + 0xFC) = (rand() & 0xFF) - 0x80;
*(s16 *)(a0 + 0xFE) = (rand() & 0xFF) - 0x80;
*(s16 *)(a0 + 0x100) = (rand() & 0xFF) - 0x80;
*(s32 *)(a0 + 0x1C) = 0x3C;
return;
}
switch (*(u16 *)(a0 + 0x34)) {
case 0:
if (*(s32 *)(a0 + 0x1C) != 0) {
*(s32 *)(a0 + 0x1C) = *(s32 *)(a0 + 0x1C) - 1;
*(s16 *)(a0 + 0xA) = *(u16 *)(a0 + 0xA) - 4;
return;
}
*(s32 *)(a0 + 0x1C) = 0x14;
*(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48);
L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C);
L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50);
/* $a0-pinned scopes: rematerialise &D_800AF648 (lui/addiu) before EACH call */
{ 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 sx; /* screen X, then REUSED as the pan field */
register s32 av __asm__("$5"); /* |X| */
s32 vol;
sx = (s16)L.sxy[0];
av = sx;
if (sx < 0) {
av = -sx;
}
vol = ((0xA0 - av) * 0x7F) / 0xA0;
/* sched1 otherwise hoists the PAN multiply ahead of this one */
__asm__("" : "=r"(vol) : "0"(vol));
sx = (sx + 0xA0) / 0x14;
if (sx == 0x10) {
sx = 0xF;
}
sx = sx << 8; /* in place, so reorg can steal it into the bne delay slot */
func_8002D4C8(0x9E5, (vol | (0x3000 | sx)) & 0xFFFF);
}
return;
case 1:
if (*(s32 *)(a0 + 0x1C) != 0) {
*(s32 *)(a0 + 0x1C) = *(s32 *)(a0 + 0x1C) - 1;
*(s32 *)(a0 + 4) =
*(s32 *)(a0 + 4) - (func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) << 5);
*(s32 *)(a0 + 0xC) =
*(s32 *)(a0 + 0xC) - (func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) << 5);
return;
}
*(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
return;
case 2:
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0x20;
if (*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) != 0x380) {
return;
}
*(u16 *)(a0 + 0x34) = *(u16 *)(a0 + 0x34) + 1;
return;
}
}
#include "common.h"
/* func_80191320 - ov_SC06_018 / ov_SC06_018_jr_8019059C (470 ins, MATCH)
*
* 5-state jr-dispatch tick for the 0x318 boss-effect entity that func_8019059C
* drives (jtbl_801D3B74, `lhu 0x34 ; sltiu ...,5` => minval 0 / maxval 4, and
* BOTH jtbl edges are real bodies, so neither empty-case construction of
* cookbook 161a/162a1 applies here).
*
* pre-switch: if (+0x100 != owner(+0x64)->+0x36) tear the child down and
* fall into the shared func_8012C218 exit.
* case 0: seed a free slot of the 32-entry x 0x10 particle table D_801D57F0,
* tick the +0xE2 countdown, then spawn the child (+0xCC).
* case 1: raise the child, poll func_8012BEE8, advance state + SFX 0x9B9.
* case 2: two func_8018F060 draws, a func_80133784 hit test, spawn 0x23.
* case 3/4: same draws + optional func_80143C74 spray with two rand() kicks.
* post: func_8018F694, then a 4-byte align-1 copy into D_801D59F0.
*
* LEVERS (all byte-measured on the way to MATCH):
*
* (1) 160a x3 - every lwl/lwr+swl/swr pair is an ALIGN-1 STRUCT ASSIGNMENT
* (Blk4_80191320 / Blk8_80191320). emit_block_move takes the TYPE's
* alignment, so a u8[4]/u8[8] struct forces the unaligned form on BOTH
* sides even when one side is a 4-aligned stack slot.
*
* (2) THE LOOP IS ONE POINTER, NOT TWO. The target walks D_801D57F0 with two
* registers 6 apart ($a3 = p, $a2 = p+6) and it is tempting to write two
* pointers `p` and `q = p + 6`, both `+= 0x10`. That gives TWO bivs and
* 4 induction registers (+4 ins). The truth is ONE biv + ONE combine_givs
* group: the MIPS unaligned-move patterns print `swl base+3 / swr base+0`
* off a SINGLE MEM, so the two block moves contribute the addresses p+0
* and p+8 only -- p+0 is the bare biv (never a giv, loop.c:4200 needs
* add_val != 0) and stays on $a3 together with `p[0]`, while p+1/p+2/p+4/
* p+5/p+6/p+8/p+0xC/p+0xE all combine at the LAST address giv in source
* order, `p[6]`, giving $a2 = p+6 with offsets -5..+8. Write every access
* as p[k] off one pointer and the register file falls out.
*
* (3) 162b1 per-arm decision for the merged `+0x34 += 1` tail. cases 0/2/3 end
* with `t = *(u16*)(a+0x34); ...; *(u16*)(a+0x34) = t + 1;` written
* LONGHAND; cross_jump merges them into the LAST-emitted copy (case 3's),
* which is exactly where the target's .L801918A8 sits (162g). It only
* merges if all three copies use the SAME hard register, and that needs
* THREE SEPARATE locals (t34a/t34b/t34c): one shared function-scope temp
* is a multi-block pseudo, so global_alloc gets it AFTER local_alloc has
* handed $v0 to the `8`/`0x1E` constant, and the tail comes out on $v1.
*
* (4) case 1's `addu $v1,$v0,$zero` is the MEMORY RE-READ form. Writing
* `s32 t = *(s16*)(e+0x18); if (t < 0x500) ... t + 0xC0` is one insn
* SHORT: cse keeps the value in one pseudo and no copy is needed. Reading
* *(s16*)(e+0x18) twice makes cse fold the second load onto a value that
* must survive the `slti` clobbering $v0, so the copy appears. It also
* costs 8 bytes of frame (see the pad note).
*
* (5) 162f-adjacent SCHEDULING: three loads in the target are hoisted above a
* store and gcc will not do it from the natural spelling -- name them.
* `tmp = *(u16*)(a+0xE)` before the `| 0x50000000`, `tmp2 = *(u16*)(a+0xE0)`
* before the 0x3001 store, and `t34d = *(u16*)(a+0x34) + 1` before the
* 0xE6 store. Each is worth 1 gas nop / a register swap.
*
* (6) THE ALIAS PAIR (new, and the last 3 bytes). sched.c:869 output_dependence
* drops a store-store dependence only when one MEM is (MEM_IN_STRUCT_P &&
* varying address && mode != QImode) and the other is (!MEM_IN_STRUCT_P &&
* fixed address). The preheader has exactly that pair -- the owner counter
* `+0x64 -> +0x1C` and the colour word at 0x34($sp) -- and it decides
* whether `sw $a0,0x34($sp)` is priority 1 (scheduled before
* `addiu $v0,$v0,1`, the target) or priority 3 (scheduled last, wrong).
* BOTH halves are load-bearing: the counter must be an ARRAY_REF
* (`((s32*)owner)[7]`, MEM_IN_STRUCT_P=1) and the colour store must be an
* INDIRECT_REF (`*(u32*)((u8*)col + 4)`, MEM_IN_STRUCT_P=0). Spelling the
* counter `*(s32*)(owner + 0x1C)` or the colour `col[1]` each leaves 3
* mismatched; only the pair reaches 0. No permutation of the 5 preheader
* statements (all 120 measured) can substitute for it.
*
* (7) FRAME (162i): vars = 0x38. sp10/sp18/sp20/sp28 are 8-byte SVECTORs at
* 0x10/0x18/0x20/0x28; `col[2]` is BLKmode so it is 8-ALIGNED at 0x30 and
* the colour word lands at 0x34 (a plain scalar would be pushed past every
* BLKmode decl instead). `pad1[2]` + the 8-byte temp that lever (4)'s
* re-read form allocates make up the rest. Neither pad is referenced.
*
* INTEGRATION (52b / 161c): every callee decl below is byte-identical to the
* host TU src/ov_SC06_018/ov_SC06_018_jr_8019059C.c where that TU declares one
* (func_80016714 L431, func_8001CD9C L1820, func_8002D4C8 L59, func_8012F214
* L2653, func_80133784 L600, func_8012F038 L333, func_8012C218 L2721,
* func_8018F694 L2751, rand L958) -- the arguments are cast at the call sites
* instead. func_8012C194 / func_8012BEE8 / func_8018F060 / func_8012D5E4 /
* func_80132EF4 / func_80143C74 and every D_ symbol are undeclared in that TU.
*
* FAMILY (reach x3, all 470 ins / 0x758, identical shape) - mechanical remap:
* ov_SC06_018 func_80191320 | ov_SC06_032 func_80191070 | ov_SC06_033 func_8018D05C
* D_801D57F0 (32x0x10 tbl) | D_801D0DC0 | D_801D0C40
* D_801D59F0 (4-byte) | D_801D0FC0 | D_801D0E40
* D_801D3B1C | D_801CF0F0 | D_801CF1AC
* D_801D3B14 | D_801CF0E8 | D_801CF1A4
* jtbl_801D3B74 | jtbl_801CF148 | jtbl_801CF204
* func_8018F060 (draw) | func_8018EDB0 | func_8018AD9C
* func_8018F694 (post) | func_8018F3E4 | func_8018B3D0
* Everything else (D_80126B96 + the 8012xxxx/8001xxxx engine callees, rand) is
* shared verbatim across all three.
*
* CARVE NOTE for banking: jtbl_801D3B74 currently lives in the tail20 DATA
* segment (config/splat.ov_SC06_018.yaml, [0xaba1c, data, tail20]). Banking
* this body makes cc1 emit its own 5-word .rodata table, so the
* ov_SC06_018_jr_8019059C .rodata carve must grow 0xab9f4->0xaba1c into
* 0xab9f4->0xaba30 (5 words, from the `sltiu ...,5` bound per 162a - NOT the
* 6-word dlabel span; the trailing 0x00000000 at 0x801D3B88 is separate data).
*/
typedef struct { u8 b[4]; } Blk4_80191320;
typedef struct { u8 b[8]; } Blk8_80191320;
typedef struct { s16 vx, vy, vz, pad; } SV_80191320;
extern void func_80016714(void *a0, s32 a1);
extern s32 func_8012C194(void);
extern void func_8001CD9C(int, void *);
extern s32 func_8012BEE8(s32 a0);
extern void func_8002D4C8(s32 a0, s32 a1);
extern void func_8018F060(s32 param_1, u32 param_2, u16 *param_3, u32 param_4);
extern s32 func_8012D5E4(s32 a0, s32 a1, s32 a2, s32 a3);
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
extern s32 func_80133784(s32 a0, void *a1, s32 a2);
extern void func_8012F038(int param_1, short *param_2, short *param_3);
extern s32 func_80132EF4(s32 a0, s32 a1);
extern s32 func_80143C74(s32 a0, s32 a1);
extern s32 rand(void);
extern void func_8012C218(void *a0);
extern void func_8018F694(void);
extern u8 D_801D57F0[];
extern u8 D_801D59F0;
extern u8 D_801D3B14[];
extern u8 D_801D3B1C[];
extern u16 D_80126B96;
void func_80191320(s32 arg0) {
s32 h;
s32 e;
s32 e2;
u16 tmp;
u16 tmp2;
u16 t34d;
u16 t34a;
u16 t34b;
u16 t34c;
s16 hn0;
s16 hn4;
s32 cnt;
u8 *p;
u8 *src;
s32 i;
s32 c;
u16 *v;
SV_80191320 sp10;
SV_80191320 sp18;
SV_80191320 sp20;
SV_80191320 sp28;
u32 col[2];
s32 pad1[2];
if (*(s16 *)(arg0 + 0x100) != *(s16 *)(*(s32 *)(arg0 + 0x64) + 0x36)) {
h = *(s32 *)(arg0 + 0xCC);
if (h != 0) {
func_80016714((void *)h, 0x38);
}
goto kill;
}
switch (*(u16 *)(arg0 + 0x34)) {
case 0:
((s32 *)*(s32 *)(arg0 + 0x64))[7] = ((s32 *)*(s32 *)(arg0 + 0x64))[7] + 1;
src = (u8 *)(arg0 + 0xDC);
*(u32 *)((u8 *)col + 4) = 0x4040FF;
p = D_801D57F0;
i = 0;
do {
i++;
if (*(s16 *)(p + 0xE) == 0) {
*(Blk8_80191320 *)(p + 8) = *(Blk8_80191320 *)src;
*(Blk4_80191320 *)p = *(Blk4_80191320 *)((u8 *)col + 4);
c = p[0] >> 3;
p[4] = c;
if (c == 0) {
p[4] = 1;
}
c = p[1] >> 3;
p[5] = c;
if (c == 0) {
p[5] = 1;
}
c = p[2] >> 3;
p[6] = c;
if (c == 0) {
p[6] = 1;
}
break;
}
p += 0x10;
} while (i < 0x20);
hn0 = *(u16 *)(src + 6) - 0x100;
*(s16 *)(src + 6) = hn0;
if (hn0 == 0) {
e = func_8012C194();
if (e != 0) {
*(s32 *)(arg0 + 0xCC) = e;
func_8001CD9C(e, &D_801D59F0);
*(u16 *)(e + 8) = *(u16 *)(arg0 + 6);
*(u16 *)(e + 0xA) = *(u16 *)(arg0 + 0xA);
tmp = *(u16 *)(arg0 + 0xE);
*(s32 *)(e + 4) = *(s32 *)(e + 4) | 0x50000000;
*(u16 *)(e + 0x18) = *(u16 *)(e + 0x1A) = 0x80;
*(u16 *)(e + 0x2C) = 0xC006;
*(u16 *)(e + 0xC) = tmp;
}
t34a = *(u16 *)(arg0 + 0x34);
*(s32 *)(arg0 + 0x1C) = 8;
*(u16 *)(arg0 + 0x34) = t34a + 1;
}
break;
case 1:
((s32 *)*(s32 *)(arg0 + 0x64))[7] = ((s32 *)*(s32 *)(arg0 + 0x64))[7] + 1;
e = *(s32 *)(arg0 + 0xCC);
if (*(s16 *)(e + 0x18) < 0x500) {
*(s16 *)(e + 0x18) = *(s16 *)(e + 0x18) + 0xC0;
*(u16 *)(e + 0x1A) = *(u16 *)(e + 0x1A) + 0xC0;
}
if (func_8012BEE8(arg0) != 0) {
*(u16 *)(arg0 + 0x102) = 0;
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
func_8002D4C8(0x9B9, 0);
}
break;
case 2:
v = (u16 *)(arg0 + 0xE4);
((s32 *)*(s32 *)(arg0 + 0x64))[7] = ((s32 *)*(s32 *)(arg0 + 0x64))[7] + 1;
func_8018F060(arg0, 0, v, 0x81818);
func_8018F060(arg0, 1, v, 0x204040);
sp10.vx = sp10.vy = 0;
sp10.vz = -*(u16 *)(arg0 + 0xE4);
sp18.vx = sp18.vy = 0;
sp18.vz = -*(u16 *)(arg0 + 0xE6);
if (func_8012D5E4(arg0, (s32)&sp10, (s32)&sp18, 0x96) != 0) {
D_80126B96 = 0x4018;
}
sp10.vx = sp10.vy = 0;
sp10.vz = -*(u16 *)(arg0 + 0xE6);
*(u16 *)(arg0 + 0xE6) = *(u16 *)(arg0 + 0xE6) + 0x40;
sp18.vx = sp18.vy = 0;
sp18.vz = -*(u16 *)(arg0 + 0xE6);
func_8012F214(arg0, (s32)&sp10, (s32)&sp20);
func_8012F214(arg0, (s32)&sp18, (s32)&sp28);
if (func_80133784(0x11, &sp20, (s32)&sp28) != 0) {
func_8012F038(*(s32 *)(arg0 + 0x20) + 0x34, (short *)&sp28, (short *)&sp20);
t34d = *(u16 *)(arg0 + 0x34) + 1;
*(u16 *)(arg0 + 0xE6) = -sp20.vz;
*(u16 *)(arg0 + 0x34) = t34d;
*(u16 *)(arg0 + 0xDC) = sp28.vx;
*(u16 *)(arg0 + 0xDE) = sp28.vy;
*(u16 *)(arg0 + 0xE0) = sp28.vz;
e2 = func_80132EF4(arg0, 0x23);
if (e2 != 0) {
*(u16 *)(e2 + 6) = *(u16 *)(arg0 + 0xDC);
*(u16 *)(e2 + 0xA) = *(u16 *)(arg0 + 0xDE);
tmp2 = *(u16 *)(arg0 + 0xE0);
*(u16 *)(e2 + 0x34) = 0x3001;
*(u16 *)(e2 + 0xE) = tmp2;
*(u16 *)(*(s32 *)(e2 + 0x20) + 0x2C) = 0xC008;
*(s32 *)(*(s32 *)(e2 + 0x20) + 4) = *(s32 *)(*(s32 *)(e2 + 0x20) + 4) | 0x50000000;
}
*(s32 *)(arg0 + 0x1C) = 0x1E;
*(u16 *)(arg0 + 0x102) = 1;
break;
}
if (*(s16 *)(arg0 + 0xE6) < 0x800) {
break;
}
t34b = *(u16 *)(arg0 + 0x34);
*(s32 *)(arg0 + 0x1C) = 0x1E;
*(u16 *)(arg0 + 0x34) = t34b + 1;
break;
case 3:
v = (u16 *)(arg0 + 0xE4);
((s32 *)*(s32 *)(arg0 + 0x64))[7] = ((s32 *)*(s32 *)(arg0 + 0x64))[7] + 1;
func_8018F060(arg0, 0, v, 0x81818);
func_8018F060(arg0, 1, v, 0x204040);
sp10.vx = sp10.vy = 0;
sp10.vz = -*(u16 *)(arg0 + 0xE4);
sp18.vx = sp18.vy = 0;
sp18.vz = -*(u16 *)(arg0 + 0xE6);
if (*(s16 *)(arg0 + 0x102) != 0) {
func_8012F214(arg0, (s32)&sp18, (s32)&sp28);
e = func_80143C74(arg0, 0);
if (e != 0) {
*(u16 *)(e + 6) = sp28.vx;
*(u16 *)(e + 0xA) = sp28.vy;
*(u16 *)(e + 0xE) = sp28.vz;
*(s32 *)(e + 0x10) = ((rand() & 0x7F) - 0x40) << 12;
*(s16 *)(e + 0x16) = -0x10;
*(s32 *)(e + 0x18) = ((rand() & 0x7F) - 0x40) << 12;
}
}
if (func_8012D5E4(arg0, (s32)&sp10, (s32)&sp18, 0x96) != 0) {
D_80126B96 = 0x4018;
}
cnt = *(s32 *)(arg0 + 0x1C) - 1;
*(s32 *)(arg0 + 0x1C) = cnt;
if (cnt == 0) {
e = *(s32 *)(arg0 + 0xCC);
if (e != 0) {
func_80016714((void *)e, 0x38);
t34c = *(u16 *)(arg0 + 0x34);
*(s32 *)(arg0 + 0xCC) = 0;
*(u16 *)(arg0 + 0x34) = t34c + 1;
}
}
break;
case 4:
v = (u16 *)(arg0 + 0xE4);
func_8018F060(arg0, 0, v, 0x81818);
func_8018F060(arg0, 1, v, 0x204040);
sp10.vx = sp10.vy = 0;
sp10.vz = -*(u16 *)(arg0 + 0xE4);
sp18.vx = sp18.vy = 0;
sp18.vz = -*(u16 *)(arg0 + 0xE6);
if (*(s16 *)(arg0 + 0x102) != 0) {
func_8012F214(arg0, (s32)&sp18, (s32)&sp28);
e = func_80143C74(arg0, 0);
if (e != 0) {
*(u16 *)(e + 6) = sp28.vx;
*(u16 *)(e + 0xA) = sp28.vy;
*(u16 *)(e + 0xE) = sp28.vz;
*(s32 *)(e + 0x10) = ((rand() & 0x7F) - 0x40) << 12;
*(s16 *)(e + 0x16) = -0x10;
*(s32 *)(e + 0x18) = ((rand() & 0x7F) - 0x40) << 12;
}
}
if (func_8012D5E4(arg0, (s32)&sp10, (s32)&sp18, 0x96) != 0) {
D_80126B96 = 0x4018;
}
hn4 = v[0] + 0x40;
v[0] = hn4;
if (hn4 < *(s16 *)(v + 1)) {
break;
}
kill:
func_8012C218((void *)arg0);
return;
}
func_8018F694();
if (D_801D59F0 == 0xFF) {
*(Blk4_80191320 *)&D_801D59F0 = *(Blk4_80191320 *)D_801D3B1C;
} else {
*(Blk4_80191320 *)&D_801D59F0 = *(Blk4_80191320 *)D_801D3B14;
}
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8019059C", func_80191320);
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8019059C", func_80191A78);
+384 -2
View File
@@ -3097,9 +3097,391 @@ void func_80191C50(s32 _arg0) {
XFERLAST(0xD4)
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80191C50", func_80192768);
#include "common.h"
/* func_80192768 — ov_SC06_018 / ov_SC06_018_jr_80191C50 (254 ins)
*
* Boss "defeat / finale" tick for the 0x318-class entity driven by the
* already-MATCHED TU neighbours func_80191C50 and func_80192F64.
*
* state 0 : arm the 0x1E-frame timer, st++
* state 1 : every frame spawn a 0x23 spark (func_8012913C) at a random
* offset around the boss and play 0xAD7; when the timer runs
* out, st++ and release the +0xCC child (flag |= 1, y-vel,
* anim 2), then clear +0xCC.
* state 2 : if the owner (+0x6C)[0xF4] is set -> the big finale: sound
* 0xAD6, three func_8012C658 props (0x33/3, 0x33/2, 0x32/2),
* eight func_8012C588(0x281) debris with rand()-driven pos/vel,
* func_8002A04C(self), stamp the owner's +0xCC child, then
* free the owner and self.
* otherwise: reload the 0x20 display record from D_801D233C
* preserving its +0x12 yaw, set +0xAE = -1, st++.
* always : tail-call ((void (*)(s32))func_8018D654)(self).
*
* @class: none — MATCH (254 ins), iteration 6.
*
* @lever (NEW, generalizable — fold's split_tree REASSOCIATION and how to
* defeat it): `(x - K) - r` and `x - (r + K)` are the SAME source-level
* value but NOT the same codegen, and gcc-2.7.2 canonicalises BOTH into
* `x - (r + K)` — `fold-const.c:3736` "EXPR is (VAR+CON) +- ARG1 ...
* otherwise return VAR +- (ARG1 +- CON)", reached through `split_tree`
* (`fold-const.c:882`). The target here wants the UN-reassociated
* `(x - K) - r` (`lhu; addiu -K; ...; subu rem`). Neither operand order
* produces it — they are mutual inverses and both land on `x - (r + K)`.
* THE LEVER: `split_tree` only strips conversions that DO NOT CHANGE THE
* MACHINE MODE (`fold-const.c:891`), so wrapping the inner subtraction in a
* HImode cast — `(u16)(*(u16 *)(e + 6) - 0x30) - rand() % 320` — leaves a
* NOP_EXPR at the top, `split_tree` returns 0, and the reassociation is
* skipped. The zero-extend costs nothing: the value is consumed by an `sh`,
* so combine's `force_to_mode` drops it. A/B-verified against 6 spellings.
*
* @lever (store order is pinned by MAY-ALIAS, not by taste): the three
* `*(s32 *)(e + 0x10/0x14/0x18) = 0` stores must come AFTER the
* `*(u16 *)(e + 0xE) = *(u16 *)(arg0 + 0xE) - 0x28` load in source. A load
* off `$s1` and a store off `$s0` cannot be disambiguated by
* `memrefs_conflict_p` (different base regs), so sched cannot lift the `lhu`
* over them — writing the zeros first pushed the `lhu 0xE` down, cost the
* 3 fillers of its load-delay and emitted a `nop` (+1 ins). Two stores off
* the SAME base with different constant offsets ARE disambiguated, which is
* why the `sh 0xE` still floats down into the `jal rand` delay slot.
*
* @lever (§76 allocno CLASS): the three `func_8012C658` results and the
* `func_8012C588` loop result are DIFFERENT variables (`p` vs `e`). Merged
* into one, the live range spans the rand()-loop, `calls_crossed > 0` forces
* callee-saved and all four land in $s0; split, `p` is call-crossing-free
* and lands in $a0 (first free in REG_ALLOC_ORDER) as the target has it.
*
* @lever (the +0xCC child is loaded TWICE in source): the target spends an
* extra `addu $s0, $v0, $zero` in the `beqz` delay slot — i.e. it tests the
* raw load in $v0 and copies it into the loop's `e` ($s0). `e = *(...);
* if (e != 0)` loads straight into $s0 (-1 ins). Testing the EXPRESSION and
* re-reading it inside the guard gives CSE a copy insn, which is the target.
*
* @lever (negative constants through a u16 lvalue): `*(u16 *)(x) = -3` emits
* `ori $v0,$zero,0xFFFD` (the constant is converted to u16 FIRST); the
* target's `addiu $v0,$zero,-0x3` needs an `s16` lvalue. Five stores here.
*
* @lever (§162 cross-jump, the `minimum=1` fall-through path): the +0x76
* select is an IF/ELSE WITH TWO `sh` STORES, not a ternary. Both spellings
* give the same 6 instructions, but the ternary keeps one live value across
* the join, so the `2` for +0x5E overlaps it and takes $v1; written as two
* stores, cross_jump merges the 1-insn `sh` tail (`jump.c:1978`, one side
* falls through so a 1-insn suffix is enough) and the value serially reuses
* $v0 — which is the only thing that keeps `addiu $v0,$zero,0x2` BELOW
* `sh $v0,0x76($s0)`, by anti-dependency. 4 mismatches -> MATCH.
*
* @lever (the shared `st++` tail is COMPILER tail-merge, write it longhand):
* `.L80192B34` is a 2-insn `addiu/sh` block entered by a forward `j` from
* case 0 and by fall-through from case 2's else arm, with the `lhu 0x34`
* DUPLICATED in each predecessor. sched2 runs BEFORE the cross-jump pass
* (`toplev.c:3104` vs `:3140`), so each arm's `lhu` is scheduled up into its
* own block first and only the 2-insn suffix survives the merge. Writing
* the increment once at a shared label would have put the `lhu` in the
* merged block and cost a `nop`.
*/
extern u8 *func_8012913C(s32);
extern s32 rand(void);
extern void func_8002D4C8(s32 a0, s32 a1);
extern s32 func_8012C658(s32 a0, s32 a1, s32 a2);
extern s32 func_8012C588(s32 a0, s32 a1);
extern void func_8002A04C(s32 a0);
extern void func_8012C218(void *a0);
extern void func_8001C214(s32 a0, void *a1);
extern void func_8018D654(void*);
extern u8 D_801D233C[];
void func_80192768(s32 arg0) {
s32 e;
s32 p;
s32 i;
s32 t;
switch (*(u16 *)(arg0 + 0x34)) {
case 0:
*(s32 *)(arg0 + 0x1C) = 0x1E;
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
goto end;
case 1:
*(u8 *)(arg0 + 0xC2) = 0xA;
e = ((s32 (*)(s32))func_8012913C)(0x23);
if (e != 0) {
*(u16 *)(e + 6) = *(u16 *)(arg0 + 6) - rand() % 224 + 0x10;
*(u16 *)(e + 0xA) = *(u16 *)(arg0 + 0xA) - rand() % 320;
*(u16 *)(e + 0xE) = *(u16 *)(arg0 + 0xE) - 0x28;
*(s32 *)(e + 0x18) = 0;
*(s32 *)(e + 0x14) = 0;
*(s32 *)(e + 0x10) = 0;
*(u16 *)(e + 0x34) = (rand() & 0x17FF) + 0x1800;
func_8002D4C8(0xAD7, 0);
}
t = *(s32 *)(arg0 + 0x1C) - 1;
*(s32 *)(arg0 + 0x1C) = t;
if (t == 0) {
e = *(s32 *)(arg0 + 0xCC);
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
if (e != 0) {
*(u16 *)(e + 0x5C) = *(u16 *)(e + 0x5C) | 1;
if (*(s32 *)(*(s32 *)(arg0 + 0x6C) + 0xF4) == 0) {
*(s16 *)(e + 0x76) = -0x1F4;
} else {
*(s16 *)(e + 0x76) = -0x3E8;
}
*(u16 *)(e + 0x5E) = 2;
*(s32 *)(arg0 + 0xCC) = 0;
}
}
goto end;
case 2:
if (*(s32 *)(*(s32 *)(arg0 + 0x6C) + 0xF4) != 0) {
func_8002D4C8(0xAD6, 0);
p = func_8012C658(0x33, 3, arg0);
if (p != 0) {
*(s16 *)(p + 0x12) = -3;
*(s16 *)(p + 0x16) = -0x10;
*(s16 *)(p + 0x1A) = -4;
*(u16 *)(p + 6) = *(u16 *)(p + 6) - 0x140;
}
p = func_8012C658(0x33, 2, arg0);
if (p != 0) {
*(u16 *)(p + 0x12) = 3;
*(s16 *)(p + 0x16) = -0x10;
*(s16 *)(p + 0x1A) = -4;
*(u16 *)(p + 6) = *(u16 *)(p + 6) - 0x140;
}
p = func_8012C658(0x32, 2, arg0);
if (p != 0) {
*(u16 *)(p + 0x12) = 0;
*(s16 *)(p + 0x16) = -0x10;
*(s16 *)(p + 0x1A) = -4;
*(u16 *)(p + 6) = *(u16 *)(p + 6) - 0x140;
}
i = 0;
do {
e = func_8012C588(0x281, arg0);
if (e != 0) {
*(s32 *)(e + 0x1C) = 2;
*(u16 *)(e + 6) = (u16)(*(u16 *)(e + 6) - 0x30) - rand() % 320;
*(u16 *)(e + 0xA) = (u16)(*(u16 *)(e + 0xA) - 0x20) - rand() % 256;
*(u16 *)(e + 0x12) = (rand() & 0x1F) - 0x10;
*(u16 *)(e + 0x16) = -((rand() & 0xF) + 0x10);
*(u16 *)(e + 0x1A) = (rand() & 0x1F) - 0x10;
}
i += 1;
} while (i < 8);
func_8002A04C(arg0);
if (*(s32 *)(*(s32 *)(arg0 + 0x6C) + 0xCC) != 0) {
e = *(s32 *)(*(s32 *)(arg0 + 0x6C) + 0xCC);
*(s16 *)(e + 0x76) = -0x3E8;
*(u16 *)(e + 0x5E) = 2;
*(u16 *)(e + 0x5C) = *(u16 *)(e + 0x5C) | 1;
}
func_8012C218(*(void **)(arg0 + 0x6C));
func_8012C218((void *)arg0);
goto end;
}
i = *(s16 *)(*(s32 *)(arg0 + 0x20) + 0x12);
func_8001C214(*(s32 *)(arg0 + 0x20), D_801D233C);
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12) = i;
*(s16 *)(arg0 + 0xAE) = -1;
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
goto end;
default:
goto end;
}
end:
((void (*)(s32))func_8018D654)(arg0);
}
#include "common.h"
/* func_80192B60 — ov_SC06_018 / TU ov_SC06_018_jr_80191C50 (257 ins)
*
* A 3-state boss-death / effect tick. Same actor family as its already-MATCHED
* TU neighbours func_80191C50 (:2880) and func_80192F64 (:3167); the spawn
* idioms are lifted verbatim from the byte-proven siblings
* func_8018E188 (src/ov_SC06_018/ov_SC06_018_jr_80187AEC.c:5255) — the $s1
* arg pin, the 0x281 particle burst, the 0x23 debris spawn;
* func_80180CA8 (src/ov_SC06_008/ov_SC06_008_jr_8017C294.c:4742) — the
* triple func_8012C658 spawn + func_8002A04C/func_8012C218 tail.
*
* state 0 : arm the 0x1E countdown, st++
* state 1 : one 0x23 debris spawn scattered around self + sound 0xAD7; when the
* countdown hits 0, st++ and slam the +0xCC child (-1000 or -500 into
* +0x76 depending on the +0x64 owner's +0xF4 flag), then drop it.
* state 2 : if the owner's +0xF4 flag is set -> the full death burst (sound
* 0xAD6, three func_8012C658 attachments, an 8x 0x281 particle burst,
* func_8002A04C, slam the owner's +0xCC child, free owner + self);
* else swap in the D_801D233C/D_801D11F0 animation pair (preserving
* the object's rot.y), set +0xAE = -1 and st++.
* always : tail func_8018D654(self).
*
* @class: none — MATCH (257 ins), iteration 6.
*
* @lever (§162 cross-jump direction as a source-shape oracle): the -1000/-500
* select is NOT a temp. A temp (`t = -1000; if (!flag) t = -500;`) is live
* from before the +0xF4 load, so it CONFLICTS with the load's allocno, is
* pushed to $v1, and that in turn lets sched2 hoist `lhu 0x5C` above
* `sh 0x76` (+4 wrong ins). Writing BOTH arms as full stores lets the final
* jump pass cross-jump the identical tails (sh 0x76 downwards), which is what
* puts the constant in the branch delay slot AND lets the value share $v0
* with the flag it was tested from. (`t` reused as the flag variable itself
* also matches — same allocno, same reason.)
*
* @lever (fold's PLUS/MINUS re-association is source-form INVARIANT): five
* spellings of `x + 0x30 + rand()%0x140` (parenthesised, operands swapped,
* constant folded into either side) all emit `x + (r%0x140 + 0x30)` — fold
* canonicalises before expand, so re-ordering the operands is USELESS here.
* The target's `(x + 0x30) + r%0x140` only appears once the constant add is
* its OWN statement on its OWN temp, which requires the rand() result to be
* hoisted into a temp first (otherwise the `lhu` lands before the `jal`, and
* a load can never be scheduled back across a call). Same for the -0x20.
*
* @lever (§76 allocno CLASS): the three func_8012C658 results and the
* 0x281/0x23/+0xCC pointers must be DIFFERENT locals. `e` never crosses a
* call -> $a0 (first free in REG_ALLOC_ORDER); `iv` spans the rand() calls in
* the burst loop -> calls_crossed > 0 -> the callee-saved $s0 that every other
* use of it then coalesces onto. One shared variable puts all of them in $s0.
*
* @lever (the second +0xCC child is loaded TWICE): `iv = load; if (iv)` emits
* `lw $s0` directly; the target tests the load and re-reads it inside the arm,
* so CSE leaves a live `addu $s0, $v0, $zero` that fills the beqz delay slot
* (+1 ins — this was the entire length drift).
*/
extern s32 rand(void);
extern u8 *func_8012913C(s32);
extern void func_8002D4C8(s32, s32);
extern s32 func_8012C658(s32, s32, s32);
extern s32 func_8012C588(s32 a0, s32 a1);
extern void func_8002A04C(s32 a0);
extern void func_8012C218(void *a0);
extern void func_8001C214(s32, void *);
extern void func_8012A828(s32, void *);
extern void func_8018D654(void *);
extern u8 D_801D233C[];
extern u8 D_801D11F0[];
void func_80192B60(void *arg) {
register u8 *p __asm__("$17");
s32 e;
s32 iv;
s32 i;
p = (u8 *)arg;
switch (*(u16 *)(p + 0x34)) {
case 0:
*(s32 *)(p + 0x1C) = 0x1E;
*(u16 *)(p + 0x34) = *(u16 *)(p + 0x34) + 1;
break;
case 1:
*(u8 *)(p + 0xC2) = 0xA;
iv = (s32)func_8012913C(0x23);
if (iv != 0) {
*(u16 *)(iv + 0x06) = *(u16 *)(p + 0x06) + rand() % 0xE0 + 0x10;
*(u16 *)(iv + 0x0A) = *(u16 *)(p + 0x0A) - rand() % 0x140;
{
s32 sv = *(u16 *)(p + 0x0E);
*(s32 *)(iv + 0x18) = 0;
*(s32 *)(iv + 0x14) = 0;
*(s32 *)(iv + 0x10) = 0;
*(u16 *)(iv + 0x0E) = sv - 0x28;
}
*(u16 *)(iv + 0x34) = (rand() & 0x17FF) + 0x1800;
func_8002D4C8(0xAD7, 0);
}
*(s32 *)(p + 0x1C) = *(s32 *)(p + 0x1C) - 1;
if (*(s32 *)(p + 0x1C) == 0) {
iv = *(s32 *)(p + 0xCC);
*(u16 *)(p + 0x34) = *(u16 *)(p + 0x34) + 1;
if (iv != 0) {
if (*(s32 *)(*(s32 *)(p + 0x64) + 0xF4) != 0) {
*(s16 *)(iv + 0x76) = -1000;
} else {
*(s16 *)(iv + 0x76) = -500;
}
*(u16 *)(iv + 0x5E) = 2;
*(u16 *)(iv + 0x5C) = *(u16 *)(iv + 0x5C) | 1;
*(s32 *)(p + 0xCC) = 0;
}
}
break;
case 2:
if (*(s32 *)(*(s32 *)(p + 0x64) + 0xF4) != 0) {
func_8002D4C8(0xAD6, 0);
e = func_8012C658(0x33, 3, (s32)p);
if (e != 0) {
*(s16 *)(e + 0x12) = -3;
*(s16 *)(e + 0x16) = -0x10;
*(s16 *)(e + 0x1A) = -4;
*(u16 *)(e + 0x06) = *(u16 *)(e + 0x06) + 0x140;
}
e = func_8012C658(0x33, 2, (s32)p);
if (e != 0) {
*(s16 *)(e + 0x12) = 3;
*(s16 *)(e + 0x16) = -0x10;
*(s16 *)(e + 0x1A) = -4;
*(u16 *)(e + 0x06) = *(u16 *)(e + 0x06) + 0x140;
}
e = func_8012C658(0x32, 2, (s32)p);
if (e != 0) {
*(s16 *)(e + 0x12) = 0;
*(s16 *)(e + 0x16) = -0x10;
*(s16 *)(e + 0x1A) = -4;
*(u16 *)(e + 0x06) = *(u16 *)(e + 0x06) + 0x140;
}
i = 0;
do {
iv = func_8012C588(0x281, (s32)p);
if (iv != 0) {
*(s32 *)(iv + 0x1C) = 2;
{
s32 rr = rand();
s32 xx = *(u16 *)(iv + 0x06) + 0x30;
*(u16 *)(iv + 0x06) = xx + rr % 0x140;
}
{
s32 rr = rand();
s32 yy = *(u16 *)(iv + 0x0A) - 0x20;
*(u16 *)(iv + 0x0A) = yy - rr % 0x100;
}
*(u16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10;
*(u16 *)(iv + 0x16) = -((rand() & 0xF) + 0x10);
*(u16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10;
}
i++;
} while (i < 8);
func_8002A04C((s32)p);
if (*(s32 *)(*(s32 *)(p + 0x64) + 0xCC) != 0) {
iv = *(s32 *)(*(s32 *)(p + 0x64) + 0xCC);
*(s16 *)(iv + 0x76) = -1000;
*(u16 *)(iv + 0x5E) = 2;
*(u16 *)(iv + 0x5C) = *(u16 *)(iv + 0x5C) | 1;
}
func_8012C218(*(void **)(p + 0x64));
func_8012C218(p);
break;
}
i = *(s16 *)(*(s32 *)(p + 0x20) + 0x12);
func_8001C214(*(s32 *)(p + 0x20), D_801D233C);
func_8012A828((s32)p, D_801D11F0);
*(u16 *)(*(s32 *)(p + 0x20) + 0x12) = i;
*(s16 *)(p + 0xAE) = -1;
*(u16 *)(p + 0x34) = *(u16 *)(p + 0x34) + 1;
break;
}
func_8018D654(p);
}
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_80191C50", func_80192B60);
#include "common.h"