Created
May 19, 2021 08:00
-
-
Save dstogov/b81a2eb2e2f4927150225ac70b838442 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ext/opcache/jit/dynasm/dasm_arm64.h b/ext/opcache/jit/dynasm/dasm_arm64.h | |
index 909b51f808..fdb22435e8 100644 | |
--- a/ext/opcache/jit/dynasm/dasm_arm64.h | |
+++ b/ext/opcache/jit/dynasm/dasm_arm64.h | |
@@ -482,7 +482,12 @@ int dasm_encode(Dst_DECL, void *buffer) | |
} | |
break; | |
case DASM_REL_A: { | |
- ptrdiff_t na = (((ptrdiff_t)(*b++) << 32) | (unsigned int)n) - (ptrdiff_t)cp + 4; | |
+ ptrdiff_t na; | |
+ if ((ins & 0x3000) == 0x3000) { /* ADRP */ | |
+ na = ((((ptrdiff_t)(*b++) << 32) | (unsigned int)n) & ~0xfff) - (((ptrdiff_t)cp + 4) & ~0xfff); | |
+ } else { | |
+ na = (((ptrdiff_t)(*b++) << 32) | (unsigned int)n) - (ptrdiff_t)cp + 4; | |
+ } | |
n = (int)na; | |
CK_REL((ptrdiff_t)n == na, na); | |
goto patchrel; | |
diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc | |
index e5a0a1e79b..750a201ea1 100644 | |
--- a/ext/opcache/jit/zend_jit_arm64.dasc | |
+++ b/ext/opcache/jit/zend_jit_arm64.dasc | |
@@ -110,6 +110,8 @@ static int sp_adj[SP_ADJ_LAST]; | |
#define LDRB_STRB_PIMM MAX_IMM12 // ldrb/strb insn | |
#define B_IMM (1<<27) // signed imm26 * 4 | |
+#define ADR_IMM (1<<20) // signed imm21 | |
+#define ADRP_IMM (1LL<<32) // signed imm21 * 4096 | |
static bool arm64_may_use_b(const void *addr) | |
{ | |
@@ -123,6 +125,30 @@ static bool arm64_may_use_b(const void *addr) | |
return 0; | |
} | |
+static bool arm64_may_use_adr(const void *addr) | |
+{ | |
+ if (addr >= dasm_buf && addr < dasm_end) { | |
+ return (((char*)dasm_end - (char*)dasm_buf) < ADR_IMM); | |
+ } else if (addr >= dasm_end) { | |
+ return (((char*)addr - (char*)dasm_buf) < ADR_IMM); | |
+ } else if (addr < dasm_buf) { | |
+ return (((char*)dasm_end - (char*)addr) < ADR_IMM); | |
+ } | |
+ return 0; | |
+} | |
+ | |
+static bool arm64_may_use_adrp(const void *addr) | |
+{ | |
+ if (addr >= dasm_buf && addr < dasm_end) { | |
+ return (((char*)dasm_end - (char*)dasm_buf) < ADRP_IMM); | |
+ } else if (addr >= dasm_end) { | |
+ return (((char*)addr - (char*)dasm_buf) < ADRP_IMM); | |
+ } else if (addr < dasm_buf) { | |
+ return (((char*)dasm_end - (char*)addr) < ADRP_IMM); | |
+ } | |
+ return 0; | |
+} | |
+ | |
#include "Zend/zend_cpuinfo.h" | |
#ifdef HAVE_VALGRIND | |
@@ -223,6 +249,13 @@ static int logical_immediate_p (uint64_t value, uint32_t reg_size) | |
| mov reg, xzr | |
|| } else if (((uintptr_t)(addr)) <= MOVZ_IMM) { | |
| movz reg, #((uint64_t)(addr)) | |
+|| } else if (arm64_may_use_adr((void*)(addr))) { | |
+| adr reg, &addr | |
+|| } else if (arm64_may_use_adrp((void*)(addr))) { | |
+| adrp reg, &(((uintptr_t)(addr))) | |
+|| if (((uintptr_t)(addr)) & 0xfff) { | |
+| add reg, reg, #(((uintptr_t)(addr)) & 0xfff) | |
+|| } | |
|| } else if ((uintptr_t)(addr) & 0xffff) { | |
| movz reg, #((uintptr_t)(addr) & 0xffff) | |
|| if (((uintptr_t)(addr) >> 16) & 0xffff) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment