mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
ARM64: Improve K13 constant rematerialization.
Algorithm by Dougall Johnson: https://dougallj.wordpress.com/2021/10/30/ Thanks to Peter Cawley. #1065
This commit is contained in:
parent
9bd2404137
commit
9daf9f9003
@ -43,26 +43,18 @@ static uint32_t emit_isk12(int64_t n)
|
|||||||
/* Encode constant in K13 format for logical data processing instructions. */
|
/* Encode constant in K13 format for logical data processing instructions. */
|
||||||
static uint32_t emit_isk13(uint64_t n, int is64)
|
static uint32_t emit_isk13(uint64_t n, int is64)
|
||||||
{
|
{
|
||||||
int inv = 0, w = 128, lz, tz;
|
/* Thanks to: https://dougallj.wordpress.com/2021/10/30/ */
|
||||||
if (n & 1) { n = ~n; w = 64; inv = 1; } /* Avoid wrap-around of ones. */
|
int rot, ones, size, immr, imms;
|
||||||
if (!n) return 0; /* Neither all-zero nor all-ones are allowed. */
|
if (!is64) n = ((uint64_t)n << 32) | (uint32_t)n;
|
||||||
do { /* Find the repeat width. */
|
if ((n+1u) <= 1u) return 0; /* Neither all-zero nor all-ones are allowed. */
|
||||||
if (is64 && (uint32_t)(n^(n>>32))) break;
|
rot = (n & (n+1u)) ? emit_ctz64(n & (n+1u)) : 64;
|
||||||
n = (uint32_t)n;
|
n = lj_ror(n, rot & 63);
|
||||||
if (!n) return 0; /* Ditto when passing n=0xffffffff and is64=0. */
|
ones = emit_ctz64(~n);
|
||||||
w = 32; if ((n^(n>>16)) & 0xffff) break;
|
size = emit_clz64(n) + ones;
|
||||||
n = n & 0xffff; w = 16; if ((n^(n>>8)) & 0xff) break;
|
if (lj_ror(n, size & 63) != n) return 0; /* Non-repeating? */
|
||||||
n = n & 0xff; w = 8; if ((n^(n>>4)) & 0xf) break;
|
immr = -rot & (size - 1);
|
||||||
n = n & 0xf; w = 4; if ((n^(n>>2)) & 0x3) break;
|
imms = (-(size << 1) | (ones - 1)) & 63;
|
||||||
n = n & 0x3; w = 2;
|
return A64I_K13 | A64F_IMMR(immr | (size & 64)) | A64F_IMMS(imms);
|
||||||
} while (0);
|
|
||||||
lz = emit_clz64(n);
|
|
||||||
tz = emit_ctz64(n);
|
|
||||||
if ((int64_t)(n << lz) >> (lz+tz) != -1ll) return 0; /* Non-contiguous? */
|
|
||||||
if (inv)
|
|
||||||
return A64I_K13 | (((lz-w) & 127) << 16) | (((lz+tz-w-1) & 63) << 10);
|
|
||||||
else
|
|
||||||
return A64I_K13 | ((w-tz) << 16) | (((63-lz-tz-w-w) & 63) << 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t emit_isfpk64(uint64_t n)
|
static uint32_t emit_isfpk64(uint64_t n)
|
||||||
|
Loading…
Reference in New Issue
Block a user