* 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
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.
Replace Linux-specific fstat64/ftruncate64 with portable POSIX equivalents.
Fix mmap error check to use MAP_FAILED instead of null pointer comparison.
Remove unconditional ftruncate after mmap that could corrupt files.
Add zero-length guard.
Replace Linux-specific fseeko64/ftello64/ftruncate64 with portable
POSIX equivalents.
Fix pread/pwrite error handling that assigned -1 to unsigned size_t.
Implement SetAttributes via chmod instead of stubbing it out.
Fix potential overflow in Unix-to-Windows filetime conversion.
Clean up unused removeCallback.
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.
std::ctype<char16_t> is a non-standard extension that's not available
on all platforms. Neither this nor the original technically match the
Windows kernel's fixed Unicode table approach and can produce different
results based on system locale.
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.
ffs() can collide with POSIX macro definitions on some platforms;
__builtin_ffs is the portable GCC/Clang intrinsic. log2_floor/log2_ceil
passed template types directly to lzcnt which has only uint32_t and
uint64_t overloads, causing implicit narrowing on smaller types.
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.
Implements a raw clock by directly accessing the `CNTVCT_EL0` and
`CNTFRQ_EL0` registers by using `mrs` intrinsics.
Should allow for a raw-clock to work on all ARM platforms without having
to make a per-platform implementation for any further a64 platforms like
MacOS or Linux or Android and such.
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.
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.
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.
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.
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).
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.
Should allow certain splats to opportunistically emit the best assembly when possible.
Also use `std::bit_cast` rather than an inline `union` type to directly
cast a `float` into a `uint32_t`.
The `BRK` instruction code needs to be specified correctly so that a debugger can handle it properly(and continue from it). `brk 0xF000` implements a debug-breakpoint that can be continued from, and `brk 0xF001` is implemented an assertion failing. Any other codes like `0` and `F1` will not be able to be continued from or handled correctly by debuggers.
These seem to be standard brk codes:
```
Breakpoint 0xF000
Assert 0xF001
Debug Service 0xF002
Fastfail 0xF003
Divide by 0 0xF004
```
Rather than using a `mov` and vector-`dup` for vector-splats, just use the `movi` instruction where applicable(8-bit element-splats).
Eventually we might want to detect opportunities to use `FMOV` and the 64-bit form of `MOVI` over in `LoadV128Const`.
Track PPC scalar FP state in the backend context and restore it at
host/guest boundaries so translated FP code has a stable rounding mode.
Convert remaining VMX sequences to scoped EmitWithVmxFpcr. Remove
unnecessary ChangeFpcrMode from sequences that only call native helpers.
Co-Authored-By: Reality <reality@xenios.jp>