Commit Graph
11 Commits
Author SHA1 Message Date
Bram Speeckaert b63808a652 JitArm64: rlwimix - Conditionally skip temp reg allocation 2024-05-07 21:12:34 +02:00
Bram Speeckaert f7c97ae654 JitArm64: srawx - Conditionally skip temp reg allocation 2024-05-07 21:12:24 +02:00
Bram Speeckaert 0189692ea3 JitArm64: divwx - Conditionally skip temp reg allocation 2024-05-07 21:11:49 +02:00
Bram Speeckaert defe97d9f1 JitArm64: addex - Skip temp reg allocation 2024-05-07 21:11:49 +02:00
Bram Speeckaert 5d647251f7 JitArm64: subfic - Conditionally skip temp reg allocation 2024-05-07 21:11:49 +02:00
Bram Speeckaert 2580837c60 JitArm64: Optimize divwux
When the divisor is a constant value, we can emit more efficient code.
For powers of two, we can use bit shifts. For other values, we can
instead use a multiplication by magic constant method.

- Example 1 - Division by 16 (power of two)
Before:
mov    w24, #0x10                ; =16
udiv   w27, w25, w24

After:
lsr    w27, w25, #4

- Example 2 - Division by 10 (fast)
Before:
mov    w25, #0xa                 ; =10
udiv   w27, w26, w25

After:
mov    w27, #0xcccd              ; =52429
movk   w27, #0xcccc, lsl #16
umull  x27, w26, w27
lsr    x27, x27, #35

- Example 3 - Division by 127 (slow)
Before:
mov    w26, #0x7f                ; =127
udiv   w27, w27, w26

After:
mov    w26, #0x408               ; =1032
movk   w26, #0x8102, lsl #16
umaddl x27, w27, w26, x26
lsr    x27, x27, #38
2024-03-23 20:13:15 +01:00
Bram Speeckaert 749ee2ff5e Jit64: Refactor divwux
Now that we've moved the logic to DivUtils, refactor the Jit64 code to
use it.
2024-03-23 20:13:15 +01:00
Bram Speeckaert 825a10616c DivUtils: Add unsigned division magic function
Takes the logic from Jit64 and moves it into DivUtils, so it can be
reused by other backends as well.
2024-03-23 20:13:15 +01:00
Bram Speeckaert a486168448 JitArm64: Use LogicalImm in boolX
ARM64 has a special logical immediate encoding scheme, that can be used
with AND, ORR, and EOR. By taking advantage of this, we no longer need
to materialize the immediate value in a register, saving instructions
and/or reducing register pressure.

- orx

Before:
mov    w23, #0x1
orr    w23, w25, w23

After:
orr    w23, w25, #0x1

- andx

Before:
mov    w26, #-0x80000000
and    w27, w27, w26
sxtw   x24, w27

After:
and    w27, w27, #0x80000000
sxtw   x26, w27

- eqvx

Before:
mov    w23, #0x4
eon    w26, w23, w22

After:
eor    w26, w22, #0xfffffffb

- xorx

Before:
mov    w23, #0x1e
eor    w23, w27, w23

After:
eor    w23, w27, #0x1e

- norx

Before:
mov    w25, #-0x2001
orr    w23, w23, w25
mvn    w23, w23

After:
orr    w23, w23, #0xffffdfff
mvn    w23, w23
2023-07-23 18:40:53 +02:00
Bram Speeckaert 4914ff25d6 JitArm64: boolX constant optimizations
A (partial) port of #9481 to ARM64. This commit adds special cases for
immediate values equal to 0 or 0xFFFFFFFF, allowing for more efficient
or no code to be generated.
2022-09-25 14:58:26 +02:00
Bram Speeckaert 9d73583ea3 JitArm64: Skip redundant imm to register writes
When a guest register is an immediate, it may be necessary to move this
value into a register. This is handled by gpr.R(), which lacks context
on how the register will be used. This leads to cases where the
immediate is written to a register, only for it to be overwritten. Take
for example this code generated by srwx:

0x5280031b   mov    w27, #0x18
0x53187edb   lsr    w27, w22, #24

gpr.BindToRegister() does have this context through the do_load
parameter, but didn't handle immediates. By adding this logic, we can
intelligently skip the write when do_load is false.
2022-09-25 10:04:51 +02:00