diff options
author | Mike Pall <mike> | 2023-10-08 22:10:02 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2023-10-08 22:10:02 +0200 |
commit | d2a5487fd79b0ce9cd303f84eae13ce12d4db4b7 (patch) | |
tree | b0b36e2f2414d2780b00696bf10ef7bb42988226 /src | |
parent | 14866a6828939d86e716939cfd2921ac5aaeca8e (diff) | |
download | luajit-d2a5487fd79b0ce9cd303f84eae13ce12d4db4b7.tar.gz luajit-d2a5487fd79b0ce9cd303f84eae13ce12d4db4b7.tar.bz2 luajit-d2a5487fd79b0ce9cd303f84eae13ce12d4db4b7.zip |
ARM64: Use ADR and ADRP to form constants.
Thanks to Peter Cawley. #1100
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_emit_arm64.h | 36 | ||||
-rw-r--r-- | src/lj_target_arm64.h | 2 |
2 files changed, 31 insertions, 7 deletions
diff --git a/src/lj_emit_arm64.h b/src/lj_emit_arm64.h index 3c510492..51d0c351 100644 --- a/src/lj_emit_arm64.h +++ b/src/lj_emit_arm64.h | |||
@@ -193,6 +193,32 @@ static int emit_kdelta(ASMState *as, Reg rd, uint64_t k, int is64) | |||
193 | return 0; /* Failed. */ | 193 | return 0; /* Failed. */ |
194 | } | 194 | } |
195 | 195 | ||
196 | #define glofs(as, k) \ | ||
197 | ((intptr_t)((uintptr_t)(k) - (uintptr_t)&J2GG(as->J)->g)) | ||
198 | #define mcpofs(as, k) \ | ||
199 | ((intptr_t)((uintptr_t)(k) - (uintptr_t)(as->mcp - 1))) | ||
200 | #define checkmcpofs(as, k) \ | ||
201 | (A64F_S_OK(mcpofs(as, k)>>2, 19)) | ||
202 | |||
203 | /* Try to form a const as ADR or ADRP or ADRP + ADD. */ | ||
204 | static int emit_kadrp(ASMState *as, Reg rd, uint64_t k) | ||
205 | { | ||
206 | A64Ins ai = A64I_ADR; | ||
207 | int64_t ofs = mcpofs(as, k); | ||
208 | if (!A64F_S_OK((uint64_t)ofs, 21)) { | ||
209 | uint64_t kpage = k & ~0xfffull; | ||
210 | MCode *adrp = as->mcp - 1 - (k != kpage); | ||
211 | ofs = (int64_t)(kpage - ((uint64_t)adrp & ~0xfffull)) >> 12; | ||
212 | if (!A64F_S_OK(ofs, 21)) | ||
213 | return 0; /* Failed. */ | ||
214 | if (k != kpage) | ||
215 | emit_dn(as, (A64I_ADDx^A64I_K12)|A64F_U12(k - kpage), rd, rd); | ||
216 | ai = A64I_ADRP; | ||
217 | } | ||
218 | emit_d(as, ai|(((uint32_t)ofs&3)<<29)|A64F_S19(ofs>>2), rd); | ||
219 | return 1; | ||
220 | } | ||
221 | |||
196 | static void emit_loadk(ASMState *as, Reg rd, uint64_t u64) | 222 | static void emit_loadk(ASMState *as, Reg rd, uint64_t u64) |
197 | { | 223 | { |
198 | int zeros = 0, ones = 0, neg, lshift = 0; | 224 | int zeros = 0, ones = 0, neg, lshift = 0; |
@@ -213,6 +239,9 @@ static void emit_loadk(ASMState *as, Reg rd, uint64_t u64) | |||
213 | if (emit_kdelta(as, rd, u64, is64)) { | 239 | if (emit_kdelta(as, rd, u64, is64)) { |
214 | return; | 240 | return; |
215 | } | 241 | } |
242 | if (emit_kadrp(as, rd, u64)) { /* Either 1 or 2 ins. */ | ||
243 | return; | ||
244 | } | ||
216 | } | 245 | } |
217 | if (neg) { | 246 | if (neg) { |
218 | u64 = ~u64; | 247 | u64 = ~u64; |
@@ -240,13 +269,6 @@ static void emit_loadk(ASMState *as, Reg rd, uint64_t u64) | |||
240 | /* Load a 64 bit constant into a GPR. */ | 269 | /* Load a 64 bit constant into a GPR. */ |
241 | #define emit_loadu64(as, rd, i) emit_loadk(as, rd, i) | 270 | #define emit_loadu64(as, rd, i) emit_loadk(as, rd, i) |
242 | 271 | ||
243 | #define glofs(as, k) \ | ||
244 | ((intptr_t)((uintptr_t)(k) - (uintptr_t)&J2GG(as->J)->g)) | ||
245 | #define mcpofs(as, k) \ | ||
246 | ((intptr_t)((uintptr_t)(k) - (uintptr_t)(as->mcp - 1))) | ||
247 | #define checkmcpofs(as, k) \ | ||
248 | (A64F_S_OK(mcpofs(as, k)>>2, 19)) | ||
249 | |||
250 | static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow); | 272 | static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow); |
251 | 273 | ||
252 | /* Get/set from constant pointer. */ | 274 | /* Get/set from constant pointer. */ |
diff --git a/src/lj_target_arm64.h b/src/lj_target_arm64.h index 65a14307..c34f1e59 100644 --- a/src/lj_target_arm64.h +++ b/src/lj_target_arm64.h | |||
@@ -234,6 +234,8 @@ typedef enum A64Ins { | |||
234 | A64I_MOVZx = 0xd2800000, | 234 | A64I_MOVZx = 0xd2800000, |
235 | A64I_MOVNw = 0x12800000, | 235 | A64I_MOVNw = 0x12800000, |
236 | A64I_MOVNx = 0x92800000, | 236 | A64I_MOVNx = 0x92800000, |
237 | A64I_ADR = 0x10000000, | ||
238 | A64I_ADRP = 0x90000000, | ||
237 | 239 | ||
238 | A64I_LDRB = 0x39400000, | 240 | A64I_LDRB = 0x39400000, |
239 | A64I_LDRH = 0x79400000, | 241 | A64I_LDRH = 0x79400000, |