mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
ARM64: Use ADR and ADRP to form constants.
Thanks to Peter Cawley. #1100
This commit is contained in:
parent
14866a6828
commit
d2a5487fd7
@ -193,6 +193,32 @@ static int emit_kdelta(ASMState *as, Reg rd, uint64_t k, int is64)
|
|||||||
return 0; /* Failed. */
|
return 0; /* Failed. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define glofs(as, k) \
|
||||||
|
((intptr_t)((uintptr_t)(k) - (uintptr_t)&J2GG(as->J)->g))
|
||||||
|
#define mcpofs(as, k) \
|
||||||
|
((intptr_t)((uintptr_t)(k) - (uintptr_t)(as->mcp - 1)))
|
||||||
|
#define checkmcpofs(as, k) \
|
||||||
|
(A64F_S_OK(mcpofs(as, k)>>2, 19))
|
||||||
|
|
||||||
|
/* Try to form a const as ADR or ADRP or ADRP + ADD. */
|
||||||
|
static int emit_kadrp(ASMState *as, Reg rd, uint64_t k)
|
||||||
|
{
|
||||||
|
A64Ins ai = A64I_ADR;
|
||||||
|
int64_t ofs = mcpofs(as, k);
|
||||||
|
if (!A64F_S_OK((uint64_t)ofs, 21)) {
|
||||||
|
uint64_t kpage = k & ~0xfffull;
|
||||||
|
MCode *adrp = as->mcp - 1 - (k != kpage);
|
||||||
|
ofs = (int64_t)(kpage - ((uint64_t)adrp & ~0xfffull)) >> 12;
|
||||||
|
if (!A64F_S_OK(ofs, 21))
|
||||||
|
return 0; /* Failed. */
|
||||||
|
if (k != kpage)
|
||||||
|
emit_dn(as, (A64I_ADDx^A64I_K12)|A64F_U12(k - kpage), rd, rd);
|
||||||
|
ai = A64I_ADRP;
|
||||||
|
}
|
||||||
|
emit_d(as, ai|(((uint32_t)ofs&3)<<29)|A64F_S19(ofs>>2), rd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_loadk(ASMState *as, Reg rd, uint64_t u64)
|
static void emit_loadk(ASMState *as, Reg rd, uint64_t u64)
|
||||||
{
|
{
|
||||||
int zeros = 0, ones = 0, neg, lshift = 0;
|
int zeros = 0, ones = 0, neg, lshift = 0;
|
||||||
@ -213,6 +239,9 @@ static void emit_loadk(ASMState *as, Reg rd, uint64_t u64)
|
|||||||
if (emit_kdelta(as, rd, u64, is64)) {
|
if (emit_kdelta(as, rd, u64, is64)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (emit_kadrp(as, rd, u64)) { /* Either 1 or 2 ins. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (neg) {
|
if (neg) {
|
||||||
u64 = ~u64;
|
u64 = ~u64;
|
||||||
@ -240,13 +269,6 @@ static void emit_loadk(ASMState *as, Reg rd, uint64_t u64)
|
|||||||
/* Load a 64 bit constant into a GPR. */
|
/* Load a 64 bit constant into a GPR. */
|
||||||
#define emit_loadu64(as, rd, i) emit_loadk(as, rd, i)
|
#define emit_loadu64(as, rd, i) emit_loadk(as, rd, i)
|
||||||
|
|
||||||
#define glofs(as, k) \
|
|
||||||
((intptr_t)((uintptr_t)(k) - (uintptr_t)&J2GG(as->J)->g))
|
|
||||||
#define mcpofs(as, k) \
|
|
||||||
((intptr_t)((uintptr_t)(k) - (uintptr_t)(as->mcp - 1)))
|
|
||||||
#define checkmcpofs(as, k) \
|
|
||||||
(A64F_S_OK(mcpofs(as, k)>>2, 19))
|
|
||||||
|
|
||||||
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
|
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
|
||||||
|
|
||||||
/* Get/set from constant pointer. */
|
/* Get/set from constant pointer. */
|
||||||
|
@ -234,6 +234,8 @@ typedef enum A64Ins {
|
|||||||
A64I_MOVZx = 0xd2800000,
|
A64I_MOVZx = 0xd2800000,
|
||||||
A64I_MOVNw = 0x12800000,
|
A64I_MOVNw = 0x12800000,
|
||||||
A64I_MOVNx = 0x92800000,
|
A64I_MOVNx = 0x92800000,
|
||||||
|
A64I_ADR = 0x10000000,
|
||||||
|
A64I_ADRP = 0x90000000,
|
||||||
|
|
||||||
A64I_LDRB = 0x39400000,
|
A64I_LDRB = 0x39400000,
|
||||||
A64I_LDRH = 0x79400000,
|
A64I_LDRH = 0x79400000,
|
||||||
|
Loading…
Reference in New Issue
Block a user