For the x86-64 JIT this is implemented with pulling rdtscp's result for
this value.
For Interpreter and AArch64 JIT this is implemented with the getcpu
syscall.
Theoretically AArch64 could implement this with MPIDR_EL1 but because
SoC vendors hecked this up, we can't. Thanks.
Kernel just returns zero + reserved bits if you try reading it.
This zeroes out an emulated 64byte cacheline. Writing zeros to memory.
This very specifically is only 64bytes to match x86 behaviour.
Also specifically non-temporal and weakly ordered. Which matches x86
CLZero behaviour.
Namespace-scope variables declared as const or constexpr have internal
linkage by default.
Also makes the output a little more consistent in terms of const/static
ordering.
Fixes#1217
Instead of throwing an error and closing down FEX. Instead pass the
SIGILL to the guest application.
On unhandled instruction implementation the instruction, we instead emit
a _Break IR op at that location.
A _Break IR op will ensure the context state is synchronized at the
point of of the fault and has fairly low overhead. We branch to the
dispatcher which does the SRA spilling.
Tested this with an application that attempts an AVX512 instruction,
catches the fault, and continues onward.
With #1383 in place, we also won't pass spurious ERROR_AND_DIE to the guest anymore.
In a syscall microbench this improves performance by ~19% on my
Snapdragon 888.
Going from ~9.6 million syscalls per second to ~11.5 million.
Macbook Pro is less effective here due to high syscall overhead due to
VM. Going form 7.2M/s to 7.6M/s, ~6% improvement
We can also inline some 32-bit syscalls but that will need some more
work which isn't done yet. Even though the op in the JIT supports it.
There's zero need for these to have an independent size field and it was
just confusing.
For stores it was always set to zero and for loads it was just
duplicated.
In addition this allows introspection of the store op without casting
the op, which can be useful in edge cases
This is a pretty straightforward operation that can be nicely modeled
by the BIC instruction on ARMv8, which is nice since we can get rid of
the need to manually perform the And and Not operations.
This allows the RA Validation pass to verify that a spill slot contains
the correct SSA.
I was originally planning to do a IR equlivent test between the IR
before and after register allocation, mostly to catch this type of error.
But this approach was much faster to implement and gives 90%
of the benefits.
When floats and doubles were converting to integers we weren't doing the correct transformation.
AArch64 provides direct ops for all four of the op types. So lets use them
- f32 -> int64
- f32 -> int32
- f64 -> int64
- f64 -> int32
Doesn't fully fix the case of overflow for AArch64 since overflow behaviour is different.
x86 returns 0x8000'0000 or 0x8000'0000'0000'0000 while AArch64 saturates to the maximum signed
integers. Can't work around that without checking overflow flags.
This does solve the typical case though.
Fixes audio problems in all FMod games.
Leafs come from ECX but only some CPUID functions support this.
This adds the initial infrastructure but doesn't yet add support for the CPUID functions to consume the leaf.
Both x86 and AArch64 support converting from one sized GPR to another
sized FPR. Expose it in our IR op.
Fixes a bug in CVTSI2SS with a 64bit source and it was treating the
input source as a 32bit value.
eg:
0x0000'0000'FFFF'FFFF was treated as converting to -1 float, which was wrong since it is a 64bit value
- InvalidateFlags pseudo-op is a hint for the Dead Flags Elimination pass that flags are not needed past that point
- Adds a new option, --abi-local-flags, that invalidates the flags on CALLs or RETs. This might break code that doesn't follow the ABI rules.