mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-24 09:00:49 +02:00
Goes from 41 instructions down to 20(!) instructions. The primary optimization here is removing a bunch of dull inserts and instead using zip logic to get the elements where we want them. The previous implementation was trying to retain semantics around how the original instruction is implemented, which makes no sense at all. Unzip the even and odd elements and just do the saturating operations directly! Huge shoutout to @dougallj again, showing that I was thinking about this implementation far too much like an x86 developer. Before: ```asm 0x0000ffff8f300c50 10ffffe0 adr x0, #-0x4 (addr 0xffff8f300c4c) 0x0000ffff8f300c54 f9005f80 str x0, [x28, #184] 0x0000ffff8f300c58 3dc010c4 ldr q4, [x6, #64] 0x0000ffff8f300c5c 6e60bae5 neg v5.8h, v23.8h 0x0000ffff8f300c60 6e60b886 neg v6.8h, v4.8h 0x0000ffff8f300c64 4eb71ee0 mov v0.16b, v23.16b 0x0000ffff8f300c68 6e0614a0 mov v0.h[1], v5.h[1] 0x0000ffff8f300c6c 4ea01c07 mov v7.16b, v0.16b 0x0000ffff8f300c70 6e0614c4 mov v4.h[1], v6.h[1] 0x0000ffff8f300c74 6e0e34a7 mov v7.h[3], v5.h[3] 0x0000ffff8f300c78 6e0e34c4 mov v4.h[3], v6.h[3] 0x0000ffff8f300c7c 6e1654a7 mov v7.h[5], v5.h[5] 0x0000ffff8f300c80 6e1654c4 mov v4.h[5], v6.h[5] 0x0000ffff8f300c84 4ea71ce0 mov v0.16b, v7.16b 0x0000ffff8f300c88 6e1e74a0 mov v0.h[7], v5.h[7] 0x0000ffff8f300c8c 4ea01c05 mov v5.16b, v0.16b 0x0000ffff8f300c90 6e1e74c4 mov v4.h[7], v6.h[7] 0x0000ffff8f300c94 0f10a4a6 sxtl v6.4s, v5.4h 0x0000ffff8f300c98 4f10a4a5 sxtl2 v5.4s, v5.8h 0x0000ffff8f300c9c 0f10a487 sxtl v7.4s, v4.4h 0x0000ffff8f300ca0 4f10a484 sxtl2 v4.4s, v4.8h 0x0000ffff8f300ca4 4ea5bcc5 addp v5.4s, v6.4s, v5.4s 0x0000ffff8f300ca8 4ea4bce4 addp v4.4s, v7.4s, v4.4s 0x0000ffff8f300cac 0e6148a5 sqxtn v5.4h, v5.4s 0x0000ffff8f300cb0 4ea51ca0 mov v0.16b, v5.16b 0x0000ffff8f300cb4 4e614880 sqxtn2 v0.8h, v4.4s 0x0000ffff8f300cb8 4ea01c17 mov v23.16b, v0.16b 0x0000ffff8f300cbc 58000040 ldr x0, pc+8 (addr 0xffff8f300cc4) 0x0000ffff8f300cc0 d63f0000 blr x0 0x0000ffff8f300cc4 a4e97128 ldff1h {z8.d}, p4/z, [x9, x9, lsl #1] 0x0000ffff8f300cc8 0000ffff udf #0xffff 0x0000ffff8f300ccc 000100dd unallocated (Unallocated) 0x0000ffff8f300cd0 00000000 udf #0x0 [DEBUG] RIP: 0x100d7 [DEBUG] Guest Code instructions: 1 [DEBUG] Host Code instructions: 41 [DEBUG] Blow-up Amt: 41x ``` After: ```asm 0x0000ffffe2500a04 10ffffe0 adr x0, #-0x4 (addr 0xffffe2500a00) 0x0000ffffe2500a08 f9005f80 str x0, [x28, #184] 0x0000ffffe2500a0c 3dc010c4 ldr q4, [x6, #64] 0x0000ffffe2500a10 4e441ae5 uzp1 v5.8h, v23.8h, v4.8h 0x0000ffffe2500a14 4e445ae4 uzp2 v4.8h, v23.8h, v4.8h 0x0000ffffe2500a18 4e642cb7 sqsub v23.8h, v5.8h, v4.8h 0x0000ffffe2500a1c 58000040 ldr x0, pc+8 (addr 0xffffe2500a24) 0x0000ffffe2500a20 d63f0000 blr x0 0x0000ffffe2500a24 f7fec128 unallocated (Unallocated) 0x0000ffffe2500a28 0000ffff udf #0xffff 0x0000ffffe2500a2c 000100dd unallocated (Unallocated) 0x0000ffffe2500a30 00000000 udf #0x0 [DEBUG] RIP: 0x100d7 [DEBUG] Guest Code instructions: 1 [DEBUG] Host Code instructions: 20 [DEBUG] Blow-up Amt: 20x ```