There's some history for this instruction. It is not in the official
instruction documentations from AMD or Intel but it is supported on
almost every x87 supporting CPU (I think there was some Cyrix that
missed it?)
This was originally implemented by accident on the Intel 80287 CPU.
It was then periodically documented in random documentation.
The instruction behaves exactly like FFREE but then pops the stack after
the operation.
For our current implementation of FFREE, which is a NOP, we just need to
pop the stack.
This must of have been a copy and paste error, I didn't even have this
instruction on my list of implemented instructions.
It definitely isn't converting to a GPR
32bit apps are setting GS register that I saw.
64Bit applications can also technically use these instructions but it
has some major limitation that causes applications to never use them
These can only be implemented as acquire/release exclusive loops on
ARMv8.0 so they end up looking pretty disgusting.
This is more for compatibility for testing than anything. I'm not
expecting ANY ARMv8.0 device to get decent performance
When the `BT mem` operation was accessing memory where the bit offset
wasn't a multiple of the access size, then we were dividing the offset
by bytes and accessing bits at `mem[byteOffset] &= (BitOffset)`.
BitOffset wasn't adjusted to compensate for the access size being added
to the address.
Causing a mismatch of testing the wrong bits. Unit tests didn't capture
this.
Trying to run glxgears on i965/iris showed extensive corruption because
of it though.
Theoretically the REP case can be optimized if it is known not to fault,
but that is one legitimate use case of this instruction.
This is just to ensure that we have this instruction covered, it hasn't
been encountered in a real program yet.
This implements support for 130 of the 132 x87 ops as interpreter
fallbacks.
The two missing ops are the BCD load and BCD store instructions and can
be implemented another time.
This allows us to no longer have to rely on a libstdc++ modification to
handle their usage of long double. This instead works entirely through
using `long double` directly in the interpreter. Which will either use
real x87 on an x86 host. Or in the case of ARM devices, fall down
glibc's long double soft float path.
This doesn't necessarily need to be quick right now. It's more important
to have the compatibility improvement from this.
As we run more threaded applications it is becoming apparent that this
needs to be fixed now.
This duplicates the FrontendDecoder and Passmanager per thread so they
no longer block each other while compiling.
Increases a bit of memory usage but completely worth it.
Adds a couple of assets in the other repeat instructions.
Jump targets were accidently inverted.
SCAS and LODS are the two repeat instructions we don't have unit tests
for.
Unit tests are forthcoming for this
The IRHeader itself contains a flag for if a block should fallback to
the interpreter.
This is necessary for the case that an IR is loaded and the Frontend
object no longer has the data necessary to know if it should do an
interpreter fallback.
This is super useful for bisecting JIT versus Intepreter failures, and
also cases where falling back to intepreter for compatibility is a lot
more simple than wiring things through the JIT (ala x87)
This isn't currently utilized, but will be once x87 work lands
This is a bit of a peculiar one, we want to ensure a single threaded
application is running on the emulator's primary thread.
This mitigates the problem that an application can do a getpid versus
gettid comparison and notice a problem.
Some games rely on getpid being the actual process ID and will spin
forever if it isn't the case.
This is also necessary for wine bringup since thread creation needs a
bit more finesse there.
Fixes#186
This keeps the XOP instruction tables around but removes the decoding
assert.
This lets us implement the POP instruction that overlapped the XOP
prefix without having to deal with XOP at all.
I don't believe we have any real need to support XOP, but if it is a
thing later then it'll be easy to add back
Optimization passes found a bug in the frontend regarding constants.
Specifically in the case of instructions that have a 32bit constant that
are sign extended to 64bit was being incorrectly set to have a size of
32bits (the size of the constant).
So an optimization pass would rematerialize constants of the expected
size, thus ~0ULL would turn in to ~0U and generate invalid code.
Now watch the destination size and set the constant to that size, which
matches what its size will be.