Since we are masking signals before compiling code, we no longer will
receive a signal in the middle of compiling code.
This makes the compile service never be invoked so we can just remove
it.
We still have some locations in the syscall handling that isn't signal
safe, but compileservice wouldn't have fixed those anyway.
This table is particularly terrible. CRC32 is the first instruction in
this table that needs either prefix `72h` OR `66h && F2h`
For 8bit CRC32, this ignores the 66h operand size override prefix.
- But our table decoding didn't handle this
For 16bit/32bit/64bit CRC32 this behaviour changes depending on 66h
prefix AND REX.W
- 66h prefix is ignored when REX.W is set, always 64bit but it falls
down the other table path
This is an absolutely weird edge case that nobody should hit, but here
we are.
Brings along a bunch of enhancements and ensures we always build against
the latest version.
Also fixes up a few issues that arose due to changes in fmt
It doesn't make any sense anymore to have specific instruction names
set for UND versus a nullptr string anymore.
Was useful when we could use it to determine the difference between
undefined from the start versus set in the tables but with unknown
decoding. Which is an edge case.
Now instead just zero initialize the data, which means it is an unknown
type and nullptr name. Which works for use.
Improves initialization time of the InitializeInfoTables function from
423 microseconds to 37 microseconds.
We've run out of the range of 32 bits already and will need to use
another flag in upcoming changes, so we need to expand our flags to be
64-bit.
While we're at it, we can use a dedicated type alias for the instruction
flags to make the interface changeable from one spot in the future.
These only perform bit arithmetic, so we can allow them to be used in
constexpr contexts.
This allows clang to collapse quite a bit of code for the table
initializing functions. For example, in InitializeVEXTables(),
with these as inline (but not constexpr) functions, clang will
individually put all of the table entries onto the stack.
With these as constexpr functions, clang will be able to deduce that it
can construct the tables at compile time and reduces the amount of
generated code quite a bit.
Now possible in a less messy way, since the type is now centralized in
one location.
Makes it strongly typed and prevents any potential accidental implicit
assignments to Type instead of something intended for the Data members.
Significantly shortens the amount of code necessary for testing the type
of a decoded operand.
Also relocates the type field out of all the union types to have it in a
central location.
In the case of an instruction that used 16bit addressing mode. It would
calculate the amount of displacement needing to be read using a 32bit
modrm mode. It would then read calculate modrm displacement again and
read the correct number of bytes.
Leftover bytes would then be in a mismatched state which means if an
instruction was using 16bit addressing + modrm + literal at /that/ point
the number of literal bytes remaining would be calculated as a negative.
This didn't actually break things since instructions that have modrm +
literal and can safely use 16bit addressing without breaking in a 32bit
environment is impossible on Linux. Due to the inability to map a memory
range in 16bit range.
All of the ops that were relying on a 64bit memory offset were being
downgraded to 32bit.
Abuses the XMM_FLAGS option a bit to indicate that it shouldn't
downgrade the 64bit size flag. Which isn't an issue since all these
operations can't encode a register since modrm_r is used for table
decoding
RIP Literal isn't actually RIP literal on 32bit, it is RIP absolute.
64bit treats the 32bit as a signed offset, while 32bit treats it as a
32bit unsigned offset
This requires implementing custom ASM dispatchers for the interpreter
side of things so it works correctly.
Allows all of our CPU backends to safely support signaling.
This is a bit of a nightmare change and requires rethinking logic about
debugging in some instances.
This was sort of partially worked around.
The issue comes down to REX.W and Operand size prefix ordering on an
instruction.
When an instruction has both prefixes, then the one that has occured
later will overwrite the previous one.
Additionally in the case of 66h being reused as an escape prefix, we
needed to ignore it in this case.
The previous workaround was that if an instruction happened to have both
widening and narrowing, then widening would win(for MODRM args),
but then later on in the instruction decoding the literal constant
decoding would properly check which order the flags came in.
This resulted in literal constants working, but not modrm bytes
Instead replace the "last" flag handling with a two deep stack that we
can push and pop the flags correctly on to it, this ensures that the
flags stay around in the 66h ignoring mode (so widening doesn't get
obliterated).
This effects every instruction that supports REX.W and 66h Operand size
prefix, so it could be fixing some unknown bugs elsewhere.
Very specifically this one was found in OpenSSL, because it looks like
GCC is padding a mov instruction with 66h.
Instruction Examples:
Only difference is the prefix order being swapped
0x00000000 4 66488b1f mov rbx, qword [rdi]
0x00000004 4 48668b1f mov bx, word [rdi]
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.
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