There were four independent arrays for each size of the RA.
Missed the 16bit and 8bit registers when removing a register.
This removes the redundant arrays and just uses one and transforms the
register to the right size depending on what the JIT wants
This is pretty easy to implement. Kind of flies in the face of why the
instruction implementation exists (icache and frontend issue overhead
savings) but it is easy to implement.
BMI1 would be straightforward to implement, BMI2 would take a bit more
effort because of the PDEP, PEXT, and BZHI instructions.
Bigger problem is that we don't support VEX three operand decoding in
the frontend at all.
Disable these until then
This is something that TSAN caught was happening.
Grabs the thread creation mutex when checking for idle and extends the
sleep time for WaitForIdle to something that is still below unit test
run time
Sadly this is a fairly substantial change that can't be broken in to
something smaller.
The gist of the problem is that most of the vector ops declared their
own uint8_t RegisterSize and ElementSize variables in their structs.
This was initially done because there were assumptions elsewhere in the
source that sometimes mixed up the IROp member `Size` and `Elements` as
sometimes meaning `Size` elements and `Elements` number of elements.
Other times there was an assumption that `Size` was the full register
size and `Elements` was the number of elements inside that size.
ex: `Size`: 16, `Elements` 8 would sometimes be interpreted as i8v16 OR i128v8
These assumptions are now removed and we also save on average 16bits per
vector operation. This is a necessary evil first step for upcoming IR
considerations.
This should have zero change on runtime behaviour and unit tests confirm
that.
Changes the IR register class definition to exist in the JSON file.
Removes a couple of IR ops that were unused and weren't necessary.
Changes the CPUID IR op to the new paired op which improves perf ever so
slightly.
Changes RA class handling in the RA pass to pull directly from the new
generated helper routine until it hits a complex op
Still need RA constraints to remove extraneous moves that would crop up
Consolidates usage of register class to the one that is defined in the
IR Json file.
Every magic number is replaced with InvalidClass and instead uses the
enums directly
Another bug fix is that the GetHostFlags IR ops was being declared as
using the flags register class, which isn't a real thing yet.
This would most likely have ended up with host flag usage being
scheduled to a GPR that was already scheduled and overwrite it.
Once this IR op ends up in host flags this will be changed as well
There are still some extraneous moves generated around the instruction,
but we need RA instruction constraints in order to safely (and cleanly)
remove them
Splits out to a jump table approach and loosely classifies and groups
the syscalls.
Also defines syscalls by number of arguments so it can be optimized
SystemV ABI mandates that the stack frame is aligned to 16bytes.
Once the call instruction happens then it is offset by 8bytes, so it is
on the callee's hands to realign the stack pointer to 16bytes.
We rely on the assumption that the stack is aligned to 16bytes for spill
slots and other function calls
Both AArch64 and x86 don't have optimal paths to move <64bit FPRs to
another with ZEXT.
So this is optimal for 128bit and 64bit while smaller ops have have the
expected overhead when using it