3 Commits
Author SHA1 Message Date
l 8f5b5a7596 emitter: retire legacy_instructions.h; inline the cursor accessors
Two related removals, and one optimisation that fell out of the second.

The cursor accessors go. xGetPtr(), xSetPtr() and
xGetAlignedCallTarget() were macros over x86Ptr, kept -- per their own
comment -- against a future change of storage scheme that never came
in fifteen years; xGetAlignedCallTarget() did no alignment at all, it
was the cursor under a misleading name. 23 files now read and assign
x86Ptr directly.

legacy_instructions.h goes with them. Its jump half (J8Rel/J32Rel and
the JE8/JMP32/... macros over them, plus x86SetJ8/J32/J32A) duplicated
what the C89 core already does with xe_fwd_jcc8/32 and xe_fwd_set8/32:
145 call sites across iFPU, iFPUd, iMMI, iR5900Branch, iR3000Atables
and iR3000A convert mechanically. Its SSE half -- eight
SSE*_XMM_to_XMM wrappers -- had exact xe_* equivalents already, same
prefix and opcode.

Four things needed more than a rename, and they are the reason this is
one commit rather than a sed:

  * x86SetJ32A padded to a 16-byte boundary with NOPs before patching.
    The core had no equivalent, so xe_fwd_set32_aligned is new rather
    than the alignment being quietly dropped.
  * The branch bookkeeping was typed u32* because the legacy API
    returned that; the C89 slot is e_u8*. recDoBranchImm's signature,
    recSetBranchEQ/L's returns, _setupBranchTest's function-pointer
    parameter (now a Jcc code) and ~20 locals follow.
  * JNS8 mapped to a condition the enum does not spell: there is no
    Jcc_NotSigned, the member is Jcc_Unsigned = 0x9. Mapped explicitly
    with a comment, since it reads like a typo otherwise.
  * The SSE wrappers were stored in function-pointer tables
    (recComOpXMM_to_XMM in iFPU, recFPUOpXMM_to_XMM in iFPUd). Macros
    have no address, so the tables become switches -- and since op is
    a constant at every call site, that removes an indirect call from
    the recompiler's emit path and lets the emission inline. That is
    the optimisation: the tables were costing a call to save nothing.

tests/emitter/newbind.cpp oracled the eight C wrappers; it now oracles
the macros the recompilers actually call, which is the better test
anyway, and the reference tree drops its include of the deleted
header.

Verification: gates 36/36 in both configurations, byte suites green
(95,692 + 112,118 + 27,337, zero divergent -- the newbind figure is
unchanged because the same 8x16x16 cases are still covered, through
the macros now), Tekken and the 2048 ELF clean at 3000 real-BIOS
frames, and all four JIT region hashes identical to the previous
build. 145 jump sites and two dispatch tables rewritten with no
change to a single emitted byte.
2026-08-21 06:41:44 +02:00
l 17d4885c1d emitter: C89 core by default; reference headers out of common/emitter; legacy jumps as macros
Three changes, one intent: bare `make` and bare cmake now build the C89
emitter with nothing to specify, and common/emitter contains only the six
headers the recompilers actually use (c89emit.h, x86emitter.h, x86types.h,
instructions.h, legacy_instructions.h, x86emitter_shim.h).

Default flip. Makefile gains `C89_EMITTER ?= 1` -- set BEFORE the
Makefile.common include, because the source exclusion there reads it. The
first attempt set it next to the CXXFLAGS append at line 839, after the
include: the define applied but the exclusion never fired, and the build
went on linking reference objects it no longer needed. Caught by `make -n`
grep: a bare plan now names zero reference objects, a C89_EMITTER=0 plan
names all eight. CMake's option defaults to ON with the same semantics
(-DC89_EMITTER=OFF for the reference).

Reference headers. internal.h, legacy_internal.h and the thirteen-header
implement/ tree move to tests/emitter/reference beside the sources that
need them. internal.h now includes the implement set itself -- it is the
reference implementation's own root and must be self-sufficient; x86types.h
includes them only under the reference configuration, for the extern
declarations in instructions.h's #else branches. The three G*Type operator
enums move into x86types.h: recompilers name their values, which makes them
API, not implementation. iR5900-32.cpp's MOVQ-workaround include of
internal.h was already reference-gated and is repointed. cmake's installed-
header list is repointed too (the stale entries failed configure).

Legacy jump API. The fourteen rel8/rel32 wrappers become macros over two
static helpers (J8Rel, J32Rel), matching the C89 core's idiom. The helpers
are static -- internal linkage per TU -- so there is no header-linkage
subtlety left to get wrong, where the previous inline definitions carried
one. The speculative conditional mode initially drafted into J32Rel was
removed before commit: only the unconditional form has callers.

The legacy SSE C-API wrappers (SSE_MINSS_XMM_to_XMM and friends) now emit
through E_SSE_RR directly instead of hopping through the C++ shim objects.
Their constants are proven end-to-end in newbind: reference function vs
C89 macro across all register pairs, 2,048 cases within the 110,070 total.

Verified: six suites green, switchover identical, both compile gates 31/31
in both configurations, bare make links at 11,351,104 bytes with zero
reference encoder symbols and boots, cmake configure passes in both
configurations. The cmake three-target build has not completed in this
container (cmake 4 needs -DCMAKE_POLICY_VERSION_MINIMUM=3.5 for the
vendored cpuinfo; GL dev packages were also missing) -- it needs one run on
a normally-provisioned machine. C89_EMITTER=0 static: the gates and suites
compile and byte-verify that configuration; its last full link ran two
commits ago unchanged.
2026-08-18 08:21:02 +02:00
l e2a6f32b08 emitter: move the reference sources to tests/emitter/reference and exclude them from the switched build
common/emitter is now headers-only. The eight reference .cpp files move via
git mv to tests/emitter/reference, beside the oracles that compare against
them; their includes are repointed to project-relative paths. Both build
systems change together: Makefile.common lists them from the new path under
ifneq (C89_EMITTER, 1), and CMake gains a C89_EMITTER option (top-level)
with the same exclusion in common/CMakeLists.txt.

The exclusion flushed out three dependency classes the previous builds had
hidden, because until now the reference objects always linked:

  x86Ptr / g_xmmtypes   lived in x86emitter.cpp; now C++17 inline
                        thread_local definitions in x86types.h
  legacy jump API       JMP8/JZ8/.../JMP32 -- raw byte writers shared by
                        both emitters, moved verbatim inline into
                        legacy_instructions.h with explicit `inline`
                        (__fi is empty on MinGW and cannot carry ODR
                        linkage for header definitions)
  legacy SSE wrappers   SSE_MINSS_XMM_to_XMM etc., used by the FPU
                        recompilers: defined under the flag at global
                        scope in legacy_instructions.h over the bound
                        xMIN/xMAX/xADD/xSUB objects. The first attempt
                        put them inside namespace x86Emitter, where the
                        callers could not see them; the compile gate
                        caught it.

Verification from the new layout: all six byte suites green (423,556 cases
total), switchover identical, both compile gates 31/31 in both configs --
the gate now compiles the relocated reference sources too. Clean switched
static build links at 11,351,104 bytes (343 KB smaller than with the
reference compiled in), contains zero reference encoder symbols by nm, and
boots. Clean default static build from the new source location links at
11,114,392 bytes and boots.

CMake status, stated plainly: configure was exercised to the point of
failing on this container's missing OpenGL dev packages -- an environment
gap upstream of anything this patch touches. The C89_EMITTER option and
source-list edits are structurally parallel to the Makefile changes that
did pass end-to-end, but a cmake build of common, pcsx2 and pcsx2_libretro
has not completed here and still needs a run on a machine with GL headers.
2026-08-18 07:09:09 +02:00