Skip to content

Instantly share code, notes, and snippets.

@dstogov
Created May 19, 2021 08:00
Show Gist options
  • Save dstogov/b81a2eb2e2f4927150225ac70b838442 to your computer and use it in GitHub Desktop.
Save dstogov/b81a2eb2e2f4927150225ac70b838442 to your computer and use it in GitHub Desktop.
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