Commit Graph

1385 Commits

Author SHA1 Message Date
MechaCat02
4670afbeb5 [Audit] --audit-r3-dump-bytes: dump N bytes at r3 when probe fires
AUDIT-059 round 15 — diagnostic. New cvar `audit_jit_prolog_r3_bytes`
(default 64 = existing behaviour, capped at 256, rounded up to 16B
multiple) controls how many bytes are dumped at host(r3) when the
audit_jit_prolog_pc probe fires. Set to 80 to capture audit-051's
stack-local struct at sub_82452DC0's r31+96.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-12 15:43:23 +02:00
MechaCat02
87e4a67b61 [Audit] JIT-prolog: optional audit_jit_prolog_mem_dump chain (3 levels)
Round-14 of AUDIT-2BF (singleton-dump). Pairs with xenia-rs'
--audit-mem-read-hex to emit one comparable XELOGKERNEL line resolving
the bctrl target at sub_822F1AA8+0x90 (PC 0x822F1B4C):

  [0x828E1F08]        -> singleton instance ptr
  [singleton+0]       -> vtable
  [vtable+0]          -> vtable[0]  (= first virtual method, bctrl tgt)
  [vtable+24]         -> vtable[24] (= slot 6, silph chain target)

Two complementary hooks:

1. src/xenia/cpu/backend/x64/x64_emitter.cc: extend
   AuditLogJitPrologArgs. New cvar `audit_jit_prolog_mem_dump` (uint32).
   When non-zero and an `audit_jit_prolog_pc` fire happens, the host
   side dereferences the VA 3 levels deep and emits one
   AUDIT-MEM-READ line in the same format ours emits. Defensive
   per-level null + VA-range checks.

2. src/xenia/kernel/kernel_state.cc: one-shot dump in
   EmulateCPInterruptDPC of the same chain (hard-coded to
   0x828E1F08). Useful when audit_jit_prolog_pc isn't set; fires the
   first time the CP interrupt path runs (after the singleton ctor
   has had time to populate).

Read-only. Both gates default-off; no impact when cvars unset.
~65 LOC total across the two files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-12 15:43:23 +02:00
MechaCat02
81d3eb056b [Audit] round 9: generalize JIT-entry probe to PC-configurable cvar
Replace the round-7 hardcoded `current_guest_function_ == 0x824F7800`
gate with a runtime cvar `audit_jit_prolog_pc` (uint32, 0 = disabled).
The cvar names the guest entry PC at which the x64 emitter inserts a
CallNative to the prolog probe; the probe now dumps the active PC in
each log line so multiple instrumentation campaigns can share output.

Renames `audit_log_sub824F7800_args` (cvar) and `AuditLogSub824F7800Args`
(host function) — the round-7 sub_824F7800-specific cvar and function
are deleted, not left dormant. The `audit_handle_lifecycle` cvar and
its existing AUDIT-HLC probe sites in xboxkrnl_threading.cc /
kernel_state.cc are untouched.

Validated by audit-059 round 9: with `--audit_jit_prolog_pc=0x821B55D8`
the silph WorkerCtx-init chain entry fires 1× in canary at tid=6
lr=0x82172D8C (call site at sub_82172BA0+0x1E8 `bctrl`, the virtual
dispatch through vtable slot 6 that statically-blind xref-walkers
cannot enumerate).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-12 15:43:23 +02:00
MechaCat02
94115aba1c [Audit] round 7: JIT-entry probe for sub_824F7800 args
Adds cvar audit_log_sub824F7800_args (off by default). When set, the x64
JIT emits one CallNative to AuditLogSub824F7800Args at the start of the
JIT-compiled body of guest function 0x824F7800 (silph::WorkerCtx ctor's
immediate caller per audit-058). The hook reads r3..r10, LR, and 64
bytes at host(r3) from PPCContext and writes them to XELOGKERNEL.

The hook is placed *after* the JIT prolog (stack push, GUEST_RET_ADDR /
GUEST_CALL_RET_ADDR setup, optional trace-functions block) and *before*
the first HIR body instruction, so r3..r10 and lr in PPCContext still
reflect the caller's args (no LOAD/STORE_CONTEXT has executed yet inside
the callee). The compile-time gate `current_guest_function_ == 0x824F7800`
makes this a zero-cost no-op for all other functions and a single extra
CallNative for the one target.

Audit-059 round 7 probe captures r3..r10 + LR for a-prime synthetic
replay of sub_824F7800 from a host hook in xenia-rs. Run with:
--audit_handle_lifecycle=true --audit_log_sub824F7800_args=true

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-12 15:43:23 +02:00
Gliniak
9588ce244d [CPU/X64] Preserve NaN bit during float->double, double->float conversion
Probably this should be moved to ppc_emit_memory level instead of being x86-64 specific

Was AI used in this change: Yes
2026-06-29 22:50:14 +02:00
Michael Oliver
0f281b6cb6 [CPU] fix vector store tests 2026-06-22 10:03:14 +02:00
Gliniak
72ce130971 [CPU] Xbox360 cache line is always 128 bytes
Fixes: 4E4D07E0 & 4E4D083D
2026-06-14 13:38:01 +02:00
Michael Oliver
30ac9d7be6 [CPU] fix correct partial vector stores
Replace the x64 STVL/STVR lowering with explicit byte stores that preserve the
guest-visible vector byte order.

The previous vector shuffle/blend path could write incorrect bytes for partial
vector stores, which broke optimized guest memcpy implementations using
stvlx/stvrx for unaligned heads and tails. In 4156081C this corrupted skinned
model render command data and eventually caused render-thread crashes.

Add regression coverage for StoreVectorLeft/StoreVectorRight across common
unaligned offsets, plus a memcpy-head style case matching the affected guest
instruction pattern.
2026-06-11 21:14:23 +02:00
Gliniak
c5113acb9c [CPU] XexModule: Removed unused class member 2026-05-26 22:56:37 +02:00
Guilhem Massol
f3086cfced [Compilation] Fix Clang 23 2026-05-12 22:45:56 +02:00
Gliniak
74f34818e7 [Lint] Added InsertBraces to linter to unify codebase to one standard 2026-05-08 18:54:50 +02:00
Wunkolo
8e1b286578 [x64] Add GFNI and AVX512VBMI optimizations for VECTOR_SHL(Int8)
Uses `{v}gf2p8mulb` as a general int8-multiplication instruction to do
variable Int8 bit-shifts.
Uses `{v}gf2p8affineqb` in the case that all of the shift values are the same.

Based on this original PR I had made to Xenia:
https://github.com/xenia-project/xenia/pull/2247
and this little write-up I did on this method:
https://wunkolo.github.io/post/2020/11/gf2p8affineqb-int8-shifting/
2026-04-23 22:07:39 +02:00
Adrian
73e3caa5e1 [CPU] Disable instruction info cache if context promotion is disabled
Fixed XMA writing to unknown registers when context promotion is disabled.
2026-04-19 20:51:12 +02:00
Gliniak
049a55f036 [CPU/Posix] Fixed crash caused by calling mmap on empty file 2026-04-19 20:21:24 +02:00
Herman S.
4acda223db [CPU] Remove ATOMIC_EXCHANGE opcode (dead code) 2026-04-08 00:05:29 +09:00
Wunkolo
c383d049ec [CPU] Implement AND+NOT folding into AND_NOT
Detect dependent `AND` and `NOT` IR sequences and combine them into a
singular `AND_NOT` opcode. The later dead-code-elimination-pass will
get rid of the left-over `NOT` opcode if nothing else uses it.
This gets quite a good amount of hits in some of the titles I've tested.

Also updates unit tests with additional data-types and ensures that
`And(..., Not())` returns the same result as `AndNot(...)`
2026-04-01 01:55:04 +09:00
Herman S.
d2c8ca675e [A64] Use ARM64 bitmask immediates for AND/OR/XOR with constants 2026-03-31 18:21:22 +09:00
Herman S.
84b05bd20a [A64] Skip software denormal flushing when FPCR.FZ handles inputs
Depends on hardware support, detected and runtime and controllable
via a64_extension_mask bit 1.
2026-03-31 18:21:21 +09:00
Herman S.
02ea71ed51 [A64] Replace RSQRT CallNativeSafe with direct blr calls 2026-03-31 18:21:21 +09:00
Herman S.
06f56a20ea [A64] Inline V128 bit-shifts with NEON, remove C helper thunks 2026-03-31 18:21:21 +09:00
Herman S.
2fc5aca628 [A64] Optimizations for DIV, MUL_HI, SWIZZLE, LOAD_VECTOR_SHL/SHR
- DIV_I32/I64 and MUL_HI_I64: use source registers directly in
  sdiv/udiv/umulh/smulh instead of copying to scratch first
- SWIZZLE: fast paths for identity (no-op), broadcast (dup), and
  pair-swap (rev64) before falling back to general TBL
- LOAD_VECTOR_SHL/SHR: build base index vector with fmov+ins
  instead of stp+ldr stack round-trip
2026-03-31 18:21:21 +09:00
Herman S.
59f9fb9964 [A64] Optimize FPCR switching with lazy mode tracking
Replace per-op save/restore of FPCR in EmitWithVmxFpcr with tracked
lazy switching via ChangeFpcrMode. Consecutive VMX float ops in the
same basic block now emit a single FPCR switch instead of one per op.

ChangeFpcrMode loads pre-computed values from the backend context
(fpcr_fpu/fpcr_vmx) instead of MRS + read-modify-write, eliminating
an expensive system register read per switch.

FPU mode is restored at block boundaries and calls via ForgetFpcrMode.
Scalar FP sequences guard with ChangeFpcrMode(Fpu) which is a no-op
when already in FPU mode.
2026-03-31 18:21:21 +09:00
Herman S.
904c6c8b1c [A64] Fix RESERVED_STORE LSE path leaving labels unbound
The LSE paths in RESERVED_STORE_I32/I64 returned early from Emit,
leaving forward-referenced no_reserve/done labels unbound. Xbyak
encodes these as offset-zero branches (branch-to-self), causing
infinite loops when the reservation check fails on LSE hardware.

Replace early return with branch-to-done inside an if/else so
labels are always bound regardless of the LSE path taken.

Adds tests for RESERVED_STORE I64 success path and I32/I64
no-reservation failure path with timeout-based hang detection.
2026-03-30 11:10:30 +09:00
Herman S.
553aedebb5 [A64] Remove dead code 2026-03-29 17:16:56 +09:00
Herman S.
2d2105cfd8 [A64] Assert OPCODE_MEMSET invariants, remove dead general-case path 2026-03-29 15:14:04 +09:00
Wunkolo
664b77f38e [a64] Optimize OPCODE_MEMSET with zva
* Add unit tests
* Use `dc zva` to zero out entire cache-lines worth of data, when possible
 * Special instruction that zaps an entire cache-line into being zero-values, typically 64-bytes at a time
* Statically read and initialize the `DCZID_EL0` register value since reading registers with `mrs` can be kinda slow and isn't worth doing redundantly at JIT-time when it never changes.
* Update store-instructions to use inline post-increments to avoid an additional `add` instruction and keep encoded instruction immediates small

Pretty much every arm processor has a cache line size of 64 bytes, so a typical `dcbz128` to clear 128-bytes of data now results in:
```
dc zva, x0
add x0, x0, 64
dc zva, x0
```
rather than a sequence of 8 `stp xzr, xzr, ...` instructions
2026-03-29 15:13:45 +09:00
Herman S.
57c1af465a [Build/CPU] Remove #pragma pack from Export and PPCOpcodeDisasmInfo
Pack(1) causes unaligned pointer errors on ARM64 with Apple's linker.
These are static read-only tables where the ~9KB size savings from
packing is negligible. Removing the pack may also marginally improve
access speed on x86 by avoiding unaligned loads.
2026-03-27 02:44:00 +09:00
Herman S.
cb12f7fa1e [Build] Generalize POSIX platform guards
Most non-Windows code paths use standard POSIX APIs (sockets, signals,
dlopen, threading) that work on any POSIX platform. Change Linux-specific
guards to !WIN32 or #else where the code is portable. Linux-specific
APIs (SIGRTMIN, Vulkan/X11, fontconfig/GTK) remain Linux-guarded.
2026-03-26 23:10:47 +09:00
Herman S.
30fd2a5ac9 [CPU] Fix breakpoint host_address() to_hex_string portability
Cast uintptr_t to uint64_t explicitly for to_hex_string, which
has no uintptr_t overload and can be ambiguous on some platforms.
2026-03-26 23:10:47 +09:00
Wunkolo
45cf464f63 [a64] Optimize more LoadV128Const splat opportunities
Optimize `LoadV128Const` to detect even more opportunities
to use `movi`, `mvni`, and `fmov` and such for 16-bit, 32-bit
and 64-bit splats.

Update some `mov`+`dup` idioms into `LoadV128Const` as well
to catch more opportunities to optimize these const-loads when
possible.
2026-03-26 22:42:01 +09:00
Wunkolo
6a47370219 [a64] Fix ATOMIC_EXCHANGE swp operand order
`swp` is weird and actually writes the first operand into the
memory address into the third operand,
_and puts the old value into the second operand_.
2026-03-26 16:04:36 +09:00
Herman S.
b6ad99ee21 [A64] Add thread-safe atomics to A64Function
Also adds some bounds check to LookupFunction.

Co-Authored-By: Reality <reality@xenios.jp>
2026-03-25 15:31:26 +09:00
Herman S.
0e05b92f85 [A64] Use shifted immediate for 0x1000 add in ComputeMemoryAddress 2026-03-25 15:31:26 +09:00
Herman S.
d731a01d89 [Testing] Add tests for AND_NOT, TRUNCATE, VECTOR_COMPARE_SGE/UGE 2026-03-25 15:31:26 +09:00
Herman S.
e54a053eca [A64] Fix epilog label memory leak in ARM64 emitter 2026-03-25 15:31:26 +09:00
Wunkolo
dd3ffeb9cb [a64] Implement FEAT_LSE optimizations
Adds `platform_arm64` similar to `platform_arm64` to populate a 64-bit feature-flag value and creates a `a64_extension_mask` configuration-mask for the detection and utilization of certain arm ISA features. The first feature being `FEAT_LSE` which maps to `XBYAK_AARCH64_HWCAP_ATOMIC`.

Just like the x64 backend, implements `IsFeatureEnabled` to the emitter for checking if the host processor supports a certain subset of feature flag(s) at once.

Optimizes `OPCODE_ATOMIC_EXCHANGE`, `OPCODE_ATOMIC_COMPARE_EXCHANGE`,
and `OPCODE_RESERVED_STORE` with `FEAT_LSE` instructions.
2026-03-25 14:31:53 +09:00
Wunkolo
bf83c4e9f5 [a64] Implement OPCODE_CACHE_CONTROL store 2026-03-25 13:32:21 +09:00
Herman S.
680aeaf52b [A64] Fix ARM64 DWARF/SEH unwind info and add registration test 2026-03-25 12:58:44 +09:00
Herman S.
6e557abb0d [A64] Inline all vector C helpers using NEON/GPR and add some tests 2026-03-25 09:48:47 +09:00
Herman S.
ef13662234 [A64] Fix SET_NJM to update cached fpcr_vmx 2026-03-25 09:48:35 +09:00
Herman S.
8911a3b7d8 [a64] Inline UNPACK_FLOAT16_2/4 using NEON fcvtl
Replace CallNativeSafe round-trips with fcvtl/fcvtl2 for half-to-float
conversion. A rev64 fixup corrects the PPC word-pair ordering. FLOAT16_2
uses ext to rotate the two source halfs into position and sets the
constant {0.0, 1.0} tail lanes. PACK_FLOAT16 kept as C helpers since
fcvtn doesn't match Xenos overflow saturation semantics.
2026-03-24 16:17:13 +09:00
Herman S.
2fe20d8d4f [A64] Inline LVL/LVR using NEON TBL instead of C helpers
Replace CallNativeSafe round-trips with inline TBL shuffles. LVL uses
a single-register TBL where out-of-range indices naturally produce
zero. LVR uses a 2-register TBL over {zeros, mem} so indices 0-15 map
to zeros and 16-31 map to memory bytes.
2026-03-24 16:17:13 +09:00
Herman S.
a1e333223e [A64] Use 16-byte NEON stores in MEMSET fallback loop
Splat the fill byte into v0.16b and use str q0 (16 bytes/iter) for
the bulk, falling back to a byte loop for the 0-15 byte tail.
2026-03-24 16:17:13 +09:00
Herman S.
bdf64db79e [A64] Fix CNTLZ_I8/I16 returning 32 for zero input
Add sentinel bits after the left-shift so clz stops at the correct
count (8 or 16) instead of counting through all 32 bits of the
widened register. Unlikely to hit in practice since PPC only has
cntlzw/cntlzd, but corrects existing sub-word variants.
2026-03-24 16:17:13 +09:00
Herman S.
02d2cb5cc4 [A64] Add v8-v15 to allocatable VEC pool
Expands the vector register allocator from 20 to 28 registers by
including v8-v15. The HostToGuestThunk now saves/restores full Q8-Q15
(128-bit) instead of just D8-D15, and the GuestToHostThunk adds Q8-Q15
to its save/restore set since AAPCS64 only preserves their lower 64
bits across C calls.

Reduces register pressure for VMX-heavy guest code at the cost of
slightly larger thunk stack frames.
2026-03-24 15:12:10 +09:00
Herman S.
756ae7a558 [A64] Dedicate x19 as backend context pointer
Reserves x19 to permanently hold the A64BackendContext pointer
(x20 - sizeof(A64BackendContext)), set once in the HostToGuestThunk.
Since x19 is AAPCS64 callee-saved, it survives all host calls for free.

Eliminates repeated 2-instruction mov+sub sequences in stackpoint
push/pop, stack synchronization, FPCR management, and reserved
load/store paths.

Reduces allocatable GPRs from 8 to 7 (like on x64).
2026-03-24 14:23:31 +09:00
Wunkolo
cfc1e4d069 [a64] Optimize EmitD3DCOLOR constants
`3.0` works with `fmov`
2026-03-24 13:54:57 +09:00
Wunkolo
531c49fbdc [a64] Optimize FlushDenormals_V128 constants
`mov`+`dup` can ve `movi`.

`mov`+dup` sequences for constants like `0x00FFFFFF` in particular can just use `mvni`(bit-inverse of `movi`)
2026-03-24 13:54:57 +09:00
Wunkolo
095bbbbda1 [a64] Optimize OPCODE_RECIP constants
Loading the value `1.0` can be done with a singular `fmov` instruction rather than a generic `mov`+`dup` sequence
2026-03-24 13:54:57 +09:00
Wunkolo
39706a0974 [a64] Avoid LoadV128Const scratch-memory usage
Use the provided scratch register-index, defaults to W0/X0, and insert 64-bit elements directly into the vector-register rather than writing/reading to scratch memory.
2026-03-24 13:46:28 +09:00