vector pairwise add
vector unsigned shift right with narrowing
vector unsigned and signed extend with lengthening from upper bits
vector unsigned and signed multiply with lengthening from upper bits
These are fairly popular so not having them around is causing headaches.
We will really want these in the future to use the host register, btu
that is more time consuming than I want to dedicate to at the moment.
So the FCMP instruction must be told which flags to generate up front,
then it generates the flags in to a GPR which are then tracked and
pulled out with a specific IR op.
This can be augmented in the future to more easily RA the host flag
register
fmov (vector, immediate, broadcast) keys register size based on the
float/double constant passed in
So since 1.0f was missing the f, it was passed as a double, duplicating
64bit doubles rather than 32bit floats
In the case that RA does Dst = Src[1] then we would have overwrote our
shift value. Move the negation to the top of the 8bit and 16bit ROL to
make sure that doesn't happen
futex command 9 is actually WAIT_BITSET, not WAKE_BITSET
Implements futexes with timeouts as well, necessary for anything using
std::condition_variable and wait_for/wait_until
A few instructions were missing flag setting entirely or were generating
wrong flags
- ROL, ROR, SHL, SHR, ASHR, SHLD, SHRD, CMPXCHG
This fixes those instructions and removes a few outdated comments
Specifically noticed when trying to run xcalc, it was using the flag
results from SHL for something and crashed without flag setting.
Unit tests for RFLAG setting instructions is still forthcoming
4000'0000h is the hypervisor CPUID information leaf, can just return all
zeroes to imply we aren't running under a hypervisor
EAX: The maximum input value for CPUID supported by the hypervisor.
- We return zero here to signify no Hypervisor
EBX, ECX, EDX: Vedor ID signature
CPUID 4000'0001h - 4000'000Fh is reserved for hypervisor, which we don't
need to expose since we return zero in EAX
These don't need to operate at 128bit, just one size larger than
incoming.
This is because of 8bit and 16bit shifts rely on 32bit size masking
rather than 8bit and 32bit, so they have to shift at a larger size due
to ensure correct behaviour(that is not undefined).
LLVM-8 worked with the previous behaviour but broke with LLVM-9.
So changing it to this slightly smarter code gen.