Introduce and use ZEND_JIT_TARGET_X86 and ZEND_JIT_TARGET_ARM64 macros.

Remove x86 specific code from ext/opcache/jit/zend_jit_arm64.dasc.
Fixed ARM64 build without libcapstone.
This commit is contained in:
Dmitry Stogov 2021-05-18 21:59:32 +03:00
parent 0123c99595
commit 767a4af2c7
6 changed files with 41 additions and 136 deletions

View file

@ -39,12 +39,10 @@
#include "Optimizer/zend_call_graph.h"
#include "Optimizer/zend_dump.h"
#if defined(__x86_64__) || defined(i386) || defined(ZEND_WIN32)
#include "jit/zend_jit_x86.h"
#elif defined (__aarch64__)
#include "jit/zend_jit_arm64.h"
#else
#error "JIT not supported on this platform"
#if ZEND_JIT_TARGET_X86
# include "jit/zend_jit_x86.h"
#elif ZEND_JIT_TARGET_ARM64
# include "jit/zend_jit_arm64.h"
#endif
#include "jit/zend_jit_internal.h"
@ -206,12 +204,12 @@ static bool zend_is_commutative(zend_uchar opcode)
#define OP2_RANGE() OP_RANGE(ssa_op, op2)
#define OP1_DATA_RANGE() OP_RANGE(ssa_op + 1, op1)
#if defined(__x86_64__) || defined(i386) || defined(ZEND_WIN32)
#include "dynasm/dasm_x86.h"
#elif defined(__aarch64__)
#if ZEND_JIT_TARGET_X86
# include "dynasm/dasm_x86.h"
#elif ZEND_JIT_TARGET_ARM64
static int zend_jit_add_veneer(dasm_State *Dst, void *buffer, uint32_t ins, int *b, uint32_t *cp, ptrdiff_t offset);
#define DASM_ADD_VENEER zend_jit_add_veneer
#include "dynasm/dasm_arm64.h"
# define DASM_ADD_VENEER zend_jit_add_veneer
# include "dynasm/dasm_arm64.h"
#endif
#include "jit/zend_jit_helpers.c"
@ -224,11 +222,11 @@ static int zend_jit_add_veneer(dasm_State *Dst, void *buffer, uint32_t ins, int
# include "jit/zend_jit_oprofile.c"
#endif
#if defined(__x86_64__) || defined(i386) || defined(ZEND_WIN32)
#include "jit/zend_jit_vtune.c"
#include "jit/zend_jit_x86.c"
#elif defined(__aarch64__)
#include "jit/zend_jit_arm64.c"
#if ZEND_JIT_TARGET_X86
# include "jit/zend_jit_vtune.c"
# include "jit/zend_jit_x86.c"
#elif ZEND_JIT_TARGET_ARM64
# include "jit/zend_jit_arm64.c"
#endif
#if _WIN32
@ -410,7 +408,7 @@ static void *dasm_link_and_encode(dasm_State **dasm_state,
return NULL;
}
#ifdef __aarch64__
#if ZEND_JIT_TARGET_ARM64
dasm_venners_size = 0;
#endif
@ -422,7 +420,7 @@ static void *dasm_link_and_encode(dasm_State **dasm_state,
return NULL;
}
#ifdef __aarch64__
#if ZEND_JIT_TARGET_ARM64
size += dasm_venners_size;
#endif
@ -4407,7 +4405,7 @@ ZEND_EXT_API int zend_jit_startup(void *buf, size_t size, bool reattached)
}
zend_jit_unprotect();
#ifdef __aarch64__
#if ZEND_JIT_TARGET_ARM64
/* reserve space for global labels veneers */
dasm_labels_veneers = *dasm_ptr;
*dasm_ptr = (void**)*dasm_ptr + zend_lb_MAX;

View file

@ -19,6 +19,16 @@
#ifndef HAVE_JIT_H
#define HAVE_JIT_H
#if defined(__x86_64__) || defined(i386) || defined(ZEND_WIN32)
# define ZEND_JIT_TARGET_X86 1
# define ZEND_JIT_TARGET_ARM64 0
#elif defined (__aarch64__)
# define ZEND_JIT_TARGET_X86 0
# define ZEND_JIT_TARGET_ARM64 1
#else
# error "JIT not supported on this platform"
#endif
#define ZEND_JIT_LEVEL_NONE 0 /* no JIT */
#define ZEND_JIT_LEVEL_MINIMAL 1 /* minimal JIT (subroutine threading) */
#define ZEND_JIT_LEVEL_INLINE 2 /* selective inline threading */

View file

@ -2642,115 +2642,8 @@ static int zend_jit_setup(void)
allowed_opt_flags = 0;
#if ZTS
# ifdef _WIN64
tsrm_tls_index = _tls_index * sizeof(void*);
/* To find offset of "_tsrm_ls_cache" in TLS segment we perform a linear scan of local TLS memory */
/* Probably, it might be better solution */
do {
void ***tls_mem = ((void**)__readgsqword(0x58))[_tls_index];
void *val = _tsrm_ls_cache;
size_t offset = 0;
size_t size = (char*)&_tls_end - (char*)&_tls_start;
while (offset < size) {
if (*tls_mem == val) {
tsrm_tls_offset = offset;
break;
}
tls_mem++;
offset += sizeof(void*);
}
if (offset >= size) {
// TODO: error message ???
return FAILURE;
}
} while(0);
# elif ZEND_WIN32
tsrm_tls_index = _tls_index * sizeof(void*);
/* To find offset of "_tsrm_ls_cache" in TLS segment we perform a linear scan of local TLS memory */
/* Probably, it might be better solution */
do {
void ***tls_mem = ((void***)__readfsdword(0x2c))[_tls_index];
void *val = _tsrm_ls_cache;
size_t offset = 0;
size_t size = (char*)&_tls_end - (char*)&_tls_start;
while (offset < size) {
if (*tls_mem == val) {
tsrm_tls_offset = offset;
break;
}
tls_mem++;
offset += sizeof(void*);
}
if (offset >= size) {
// TODO: error message ???
return FAILURE;
}
} while(0);
# elif defined(__APPLE__) && defined(__x86_64__)
tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset();
if (tsrm_ls_cache_tcb_offset == 0) {
size_t *ti;
__asm__(
"leaq __tsrm_ls_cache(%%rip),%0"
: "=r" (ti));
tsrm_tls_offset = ti[2];
tsrm_tls_index = ti[1] * 8;
}
# elif defined(__GNUC__) && defined(__x86_64__)
tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset();
if (tsrm_ls_cache_tcb_offset == 0) {
#if defined(__has_attribute) && __has_attribute(tls_model) && !defined(__FreeBSD__)
size_t ret;
asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0"
: "=r" (ret));
tsrm_ls_cache_tcb_offset = ret;
#else
size_t *ti;
__asm__(
"leaq _tsrm_ls_cache@tlsgd(%%rip), %0\n"
: "=a" (ti));
tsrm_tls_offset = ti[1];
tsrm_tls_index = ti[0] * 16;
#endif
}
# elif defined(__GNUC__) && defined(__i386__)
tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset();
if (tsrm_ls_cache_tcb_offset == 0) {
#if !defined(__FreeBSD__)
size_t ret;
asm ("leal _tsrm_ls_cache@ntpoff,%0\n"
: "=a" (ret));
tsrm_ls_cache_tcb_offset = ret;
#else
size_t *ti, _ebx, _ecx, _edx;
__asm__(
"call 1f\n"
".subsection 1\n"
"1:\tmovl (%%esp), %%ebx\n\t"
"ret\n"
".previous\n\t"
"addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t"
"leal _tsrm_ls_cache@tlsldm(%%ebx), %0\n\t"
"call ___tls_get_addr@plt\n\t"
"leal _tsrm_ls_cache@tlsldm(%%ebx), %0\n"
: "=a" (ti), "=&b" (_ebx), "=&c" (_ecx), "=&d" (_edx));
tsrm_tls_offset = ti[1];
tsrm_tls_index = ti[0] * 8;
#endif
}
# elif defined(__aarch64__)
tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset();
ZEND_ASSERT(tsrm_ls_cache_tcb_offset != 0);
# elif
# endif
#endif
return SUCCESS;

View file

@ -23,7 +23,7 @@
# define HAVE_DISASM 1
# include <capstone/capstone.h>
# define HAVE_CAPSTONE_ITER 1
#else
#elif ZEND_JIT_TARGET_X86
# define HAVE_DISASM 1
# define DISASM_INTEL_SYNTAX 0
@ -38,6 +38,8 @@
# include "jit/libudis86/udis86.c"
#endif /* HAVE_CAPSTONE */
#ifdef HAVE_DISASM
static void zend_jit_disasm_add_symbol(const char *name,
uint64_t addr,
uint64_t size);
@ -225,7 +227,7 @@ static uint64_t zend_jit_disasm_branch_target(csh cs, const cs_insn *insn)
{
unsigned int i;
#if defined(__x86_64__) || defined(i386) || defined(ZEND_WIN32)
#if ZEND_JIT_TARGET_X86
if (cs_insn_group(cs, insn, X86_GRP_JUMP)) {
for (i = 0; i < insn->detail->x86.op_count; i++) {
if (insn->detail->x86.operands[i].type == X86_OP_IMM) {
@ -233,7 +235,7 @@ static uint64_t zend_jit_disasm_branch_target(csh cs, const cs_insn *insn)
}
}
}
#elif defined(__aarch64__)
#elif ZEND_JIT_TARGET_ARM64
if (cs_insn_group(cs, insn, ARM64_GRP_JUMP)
|| insn->id == ARM64_INS_BL
|| insn->id == ARM64_INS_ADR) {
@ -321,7 +323,7 @@ static int zend_jit_disasm(const char *name,
#endif
#ifdef HAVE_CAPSTONE
# if defined(__x86_64__) || defined(_WIN64) || defined(ZEND_WIN32)
# if ZEND_JIT_TARGET_X86
if (cs_open(CS_ARCH_X86, CS_MODE_64, &cs) != CS_ERR_OK)
return 0;
cs_option(cs, CS_OPT_DETAIL, CS_OPT_ON);
@ -330,7 +332,7 @@ static int zend_jit_disasm(const char *name,
# else
cs_option(cs, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
# endif
# elif defined(__aarch64__)
# elif ZEND_JIT_TARGET_ARM64
if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &cs) != CS_ERR_OK)
return 0;
cs_option(cs, CS_OPT_DETAIL, CS_OPT_ON);
@ -768,3 +770,5 @@ static void zend_jit_disasm_shutdown(void)
JIT_G(symbols) = NULL;
}
}
#endif /* HAVE_DISASM */

View file

@ -727,7 +727,7 @@ static zend_always_inline bool zend_jit_may_be_polymorphic_call(const zend_op *o
/* Instruction cache flush */
#ifndef JIT_CACHE_FLUSH
# if defined (__aarch64__)
# if ZEND_JIT_TARGET_ARM64
# if ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4003) || __has_builtin(__builtin___clear_cache))
# define JIT_CACHE_FLUSH(from, to) __builtin___clear_cache((char*)(from), (char*)(to))
# else

View file

@ -28,10 +28,10 @@
#include "Optimizer/zend_func_info.h"
#include "Optimizer/zend_call_graph.h"
#include "zend_jit.h"
#if defined(__x86_64__) || defined(i386) || defined(ZEND_WIN32)
#include "zend_jit_x86.h"
#elif defined(__aarch64__)
#include "zend_jit_arm64.h"
#if ZEND_JIT_TARGET_X86
# include "zend_jit_x86.h"
#elif ZEND_JIT_TARGET_ARM64
# include "zend_jit_arm64.h"
#endif
#include "zend_jit_internal.h"