mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-27 10:38:46 -04:00
c2a3f6ad79
Compiler-neutral tier-selection policy extracted from the mis-named
overlay_sljit.{c,h} into NEW overlay_backend.{c,h} (OverlayBackend enum +
resolve/name/active). overlay_sljit.{c,h} is now just the deprecated emitter.
New tcc tier. gcc and tcc run the IDENTICAL pipeline (recompiler -> C ->
compiler -> DLL -> loader); only the compiler binary differs, so both map to the
autocompile-spawn provider (code_provider.c) and the COMMAND is chosen by the
resolved backend (main.cpp). compile_overlays.py gains --compiler gcc|tcc: tcc
writes a separate tcc/ cache namespace, BOM-strips the C + a copy of the include
headers (tcc 0.9.27 can't skip a UTF-8 BOM), and uses tcc's built-in linker.
Backends (overlay_backend): auto (gcc if a gcc TOOLCHAIN is present, else tcc --
was sljit), gcc, tcc, auto-no-gcc (dev/test: force tcc even with gcc present, to
exercise the toolchain-less user path), sljit (DEPRECATED, gated off, lowest).
Priority: static > gcc shard > tcc shard > sljit(off) > interp. The loader scans
gcc/ then tcc/ and dedups by region+crc (filename) so a gcc shard always wins a
tie.
Self-contained tcc: with no explicit overlay_autocompile_cmd_tcc, the runtime
CONSTRUCTS the tcc command from a toolchain bundled beside the exe
(<exe>/overlay_toolchain/: embedded python + tcc + recompiler + compile_overlays.py
+ runtime headers) -- no system python or gcc needed. config_loader gains
overlay_autocompile_cmd_tcc (a dev override). autocompile cmd buffers enlarged for
the constructed path-heavy command.
Compilation stays OFF the dispatch/render thread (off-process autocompile
subprocess, same model as gcc); the main thread only spawns it and dlopens the
finished DLL.
Validated: MMX6 with overlay_backend=auto-no-gcc fills the tcc/ namespace live
from the bundled toolchain and plays through save-load + gameplay -- the exact
path the sljit tier softlocked on. The gcc path is untouched.
Runtime-only, no regen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
67 lines
2.7 KiB
C
67 lines
2.7 KiB
C
/* overlay_backend.c — compiler-neutral overlay tier-selection policy.
|
|
* See overlay_backend.h. Moved out of overlay_sljit.c (which is now just the
|
|
* deprecated sljit emitter): deciding gcc vs tcc vs sljit is not sljit's job. */
|
|
|
|
#include "overlay_backend.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
static OverlayBackend s_active = OVERLAY_BACKEND_AUTO;
|
|
static int s_resolved = 0;
|
|
static char s_last_msg[256];
|
|
|
|
static void backend_log(const char *fmt, ...) {
|
|
va_list ap; va_start(ap, fmt);
|
|
vsnprintf(s_last_msg, sizeof(s_last_msg), fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
const char *overlay_backend_name(OverlayBackend b) {
|
|
switch (b) {
|
|
case OVERLAY_BACKEND_GCC: return "gcc";
|
|
case OVERLAY_BACKEND_SLJIT: return "sljit";
|
|
case OVERLAY_BACKEND_TCC: return "tcc";
|
|
case OVERLAY_BACKEND_AUTO_NO_GCC: return "auto-no-gcc";
|
|
default: return "auto";
|
|
}
|
|
}
|
|
|
|
static OverlayBackend parse_backend(const char *s, OverlayBackend dflt) {
|
|
if (!s || !*s) return dflt;
|
|
if (!strcmp(s, "gcc")) return OVERLAY_BACKEND_GCC;
|
|
if (!strcmp(s, "sljit")) return OVERLAY_BACKEND_SLJIT;
|
|
if (!strcmp(s, "tcc")) return OVERLAY_BACKEND_TCC;
|
|
if (!strcmp(s, "auto-no-gcc")) return OVERLAY_BACKEND_AUTO_NO_GCC;
|
|
if (!strcmp(s, "auto")) return OVERLAY_BACKEND_AUTO;
|
|
return dflt;
|
|
}
|
|
|
|
OverlayBackend overlay_backend_resolve(const char *cfg, int gcc_toolchain_available) {
|
|
/* Precedence: env PSX_OVERLAY_BACKEND > game.toml [runtime] overlay_backend
|
|
* (cfg) > AUTO. Tier order is static > gcc > tcc > (sljit, deprecated/off) >
|
|
* interp. AUTO prefers gcc when a gcc TOOLCHAIN is actually present (a dev /
|
|
* production box), else tcc (the bundled toolchain-free user fallback).
|
|
* AUTO_NO_GCC forces the tcc branch even when gcc IS present — it simulates a
|
|
* toolchain-less user box on a dev machine (gcc shards still LOAD via the
|
|
* loader; only the gap-fill compiler is forced to tcc). */
|
|
OverlayBackend want = parse_backend(getenv("PSX_OVERLAY_BACKEND"),
|
|
parse_backend(cfg, OVERLAY_BACKEND_AUTO));
|
|
OverlayBackend eff = want;
|
|
if (want == OVERLAY_BACKEND_AUTO)
|
|
eff = gcc_toolchain_available ? OVERLAY_BACKEND_GCC : OVERLAY_BACKEND_TCC;
|
|
else if (want == OVERLAY_BACKEND_AUTO_NO_GCC)
|
|
eff = OVERLAY_BACKEND_TCC;
|
|
|
|
s_active = eff;
|
|
s_resolved = 1;
|
|
backend_log("backend resolved: want=%s effective=%s (gcc_toolchain=%d)",
|
|
overlay_backend_name(want), overlay_backend_name(eff),
|
|
gcc_toolchain_available);
|
|
return eff;
|
|
}
|
|
|
|
OverlayBackend overlay_backend_active(void) { return s_active; }
|