fix(phase-29): ENGINE_SHB — the carried-#define gap that capped func_80165CA0 at ×3

- CAUSE (measured, not guessed): the 132 extend failures were `undefined reference to 'SHB'` --
  a LINK error, not a type conflict. SHB is not a symbol; it is a file-scope
  `#define SHB(x) __asm__(...)` sign-extension barrier. A body's preamble can carry `#define`s
  as well as `extern`s, but extraction lifts only the externs -- so the `#define` was left behind
  in the source overlay. In ov_SC01_077 it sits literally BETWEEN the two carried externs and the
  instantiation:
      extern s32 D_8011D030;
      extern s32 D_80126728;
      #define SHB(x) __asm__ __volatile__("" : "=r"(x) : "0"(x))
      DEFINE_func_80165CA0()
  The other 132 overlays DO define SHB -- ~300 lines further down the file (stub @4462 vs
  #define @4781 in ov_SC01_001), i.e. BELOW the splice point, so the preprocessor never expands
  it and cc1 emits a call to an undeclared `SHB`. Pure ORDERING; nothing was missing.
- Also explains why the 3 current members are EXACTLY the 3 files carrying the __volatile__ SHB
  spelling: that define is the function's own preamble, still sitting above its instantiation.
- FIX: engine_core.h owns the barrier as ENGINE_SHB (distinct name, so the overlays' own SHB --
  which exists in BOTH a volatile and a non-volatile spelling -- can never collide), and
  DEFINE_func_80165CA0's 7 uses now call it. Volatile form: what the 3 banked members compile
  with today. The body is now self-contained wherever it is instantiated.
- BYTE-GATED the full existing blast radius: ov_SC01_077 d19c9580 · ov_SC01_000 9052dc0e ·
  ov_SC07_006 7ca772be -- all BYTE-IDENTICAL.
- This is the dedup_propagate counterpart of Phase-27's family_remap._carry_macros (§75b).
This commit is contained in:
Drew T
2026-07-25 13:04:15 -06:00
parent 1f9289f790
commit 364ddd7055
+20 -7
View File
@@ -7,6 +7,19 @@
#include "common.h"
#include "engine_types.h" /* shared engine struct/union types (§14c struct follow-up) */
/* ENGINE_SHB — the sign-extension barrier some shared bodies were matched with (§75b).
* A body's preamble may carry file-scope `#define`s as well as `extern`s, but extraction lifts
* only the externs, so a `#define` left behind in the source overlay makes the macro compile
* ONLY where that overlay's define happens to be in scope ABOVE the splice point. func_80165CA0
* was capped at ×3 by exactly that: its `#define SHB` sits between its two externs and its
* instantiation, and the other 132 overlays define SHB only ~300 lines further down the file.
* Owning it here (under a distinct name, so the overlays' own SHB — which exists in BOTH a
* volatile and a non-volatile spelling — can never collide) makes the body self-contained.
* Volatile form: that is what the 3 banked members compile with today. */
#ifndef ENGINE_SHB
#define ENGINE_SHB(x) __asm__ __volatile__("" : "=r"(x) : "0"(x))
#endif
#define DEFINE_func_80128EA8() \
void func_80128EA8(s32 a0, s32 a1, s32 a2) { \
*(s32 *)(a1 + 0x0) = a2; /* sw a2, 0x0(a1) */ \
@@ -28061,19 +28074,19 @@
} while (i < 0x1e); \
i = 0; off = 0; \
do { \
base = (s32)&D_8011D030; SHB(base); \
base = (s32)&D_8011D030; ENGINE_SHB(base); \
a1 = off + base; \
p = *(short **)(a1 + 0x20); \
if (p != 0) { \
s32 q2; \
if ((u16)*p == 1) { \
v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(p + 0x24) = v; \
v = *(short *)(a1 + 0xa); p[5] = v; SHB(v); *(int *)(p + 0x26) = v; \
w = *(short *)(a1 + 0xe); p[6] = w; v = p[0x16] | 1; SHB(w); p[0x16] = v; *(int *)(p + 0x28) = w; \
v = *(short *)(a1 + 6); p[4] = v; ENGINE_SHB(v); *(int *)(p + 0x24) = v; \
v = *(short *)(a1 + 0xa); p[5] = v; ENGINE_SHB(v); *(int *)(p + 0x26) = v; \
w = *(short *)(a1 + 0xe); p[6] = w; v = p[0x16] | 1; ENGINE_SHB(w); p[0x16] = v; *(int *)(p + 0x28) = w; \
} else if ((q2 = *(int *)(p + 0x1a)) != 0) { \
v = *(short *)(a1 + 6); p[4] = v; SHB(v); *(int *)(q2 + 0x14) = v; \
v = *(short *)(a1 + 0xa); p[5] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x18) = v; \
v = *(short *)(a1 + 0xe); p[6] = v; q2 = *(int *)(p + 0x1a); SHB(v); *(int *)(q2 + 0x1c) = v; \
v = *(short *)(a1 + 6); p[4] = v; ENGINE_SHB(v); *(int *)(q2 + 0x14) = v; \
v = *(short *)(a1 + 0xa); p[5] = v; q2 = *(int *)(p + 0x1a); ENGINE_SHB(v); *(int *)(q2 + 0x18) = v; \
v = *(short *)(a1 + 0xe); p[6] = v; q2 = *(int *)(p + 0x1a); ENGINE_SHB(v); *(int *)(q2 + 0x1c) = v; \
} else { \
p[4] = *(short *)(a1 + 6); p[5] = *(short *)(a1 + 0xa); p[6] = *(short *)(a1 + 0xe); \
} \