Makes the behavior consistent with the x86 JIT.
We need to treat values larger than 31 as if they were 31 bit shifts in
order to handle sign-extending behavior properly.
Follow-up to #2327.
Split off from #2176 and improved.
32-bit signals are a bit more complex than 64-bit due to behaviour
changing depending on if `rt_sigaction` and `sigaction` syscall is used
and if `SA_SIGINFO` is passed in to the flags.
With `SA_SIGINFO` used, both turn in to an `RT` frame, which is encoded
differently than without `SA_SIGINFO`.
Additionally 32-bit signals support both regular Linux stack ABI and
`regparm(3)` ABI.
Without `SA_SIGINFO` then `siginfo_t` is removed from the signal handler
arguments, but most of the rest still remains.
Also two of the arguments to the signal handler are forced to be nullptr
with `regparm(3)`.
Split off from #2243 to remove each member individually.
Shaves 8-bits off of each IR op.
No need to cart around this data when it is constant for each operation.
Especially since most optimization passes don't need the data anyway.
Needed to add a new `GetRAArgs` to get the number of SSA arguments that
get RA versus `GetArgs` which returns all SSA arguments the IR operation
owns. This is what was causing #2243 to fail CI since it needs to know
the difference in some places.
In large blocks we can be generating a ton of inline constants. But in
most cases these end up being 0, 1, or (1 << N).
Add these to a map and reuse if possible. Makes some IR blocks
significantly smaller for later optimization passes.
The current separated adr and adrp handlers are difficult to use if you
don't know if the resulting address is going to be within 1MB or 4GB.
Adds a `LongAddressGen` helper that will generate the various pieces of
code that will need to be emitted.
Backward labels:
- Can generate three different code segments depending on distance to
label
- adr if label is within 1MB
- adrp if label is 4K page aligned and within 4GB
- adrp+add if label is within 4GB
Forward labels:
- Can generate three different code segments depending on distance to
label
- nop+adr if label is within 1MB
- nop+adrp if label is 4K page aligned and within 4GB
- adrp+add if label is within 4GB
There is still the limitation that this can't generate addresses to
labels that are >4GB away. Which is fine.
We can do a single LDP upfront when loading from the code cache, which
saves an instruction and one LDP costs the same as a single LDR.
Itty bitty optimization in the hot dispatcher.