LoongArch64 backend for the OPcache JIT

From: Date: Wed, 11 Nov 2026 14:07:31 +0000
Subject: LoongArch64 backend for the OPcache JIT
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-133074@lists.php.net to get a copy of this message
Hello internals, I would like to raise the question of adding a LoongArch64 backend to the OPcache JIT, and to ask for guidance before writing any substantial amount of code. Status today (PHP 8.5 / master):   - ext/opcache/config.m4 gates the JIT on the host CPU:       AS_CASE([$host_cpu],         [[i[34567]86*|x86*|aarch64|amd64]], [],         [AC_MSG_WARN([JIT not supported by host architecture])          PHP_OPCACHE_JIT=no])     On loongarch64 this silently disables --enable-opcache-jit.   - ext/opcache/jit/ir/ contains ir_x86.dasc (~930 KB) and ir_aarch64.dasc     (~328 KB) and their headers. There is no ir_loongarch64.dasc.   - The bundled DynASM provides dasm_arm, dasm_arm64, dasm_mips, dasm_ppc     and dasm_x86/x64, but no LoongArch64 target, so a backend needs a     DynASM target first.   - Fibers already work on LoongArch64 (make_loongarch64_sysv_elf_gas.S and     jump_loongarch64_sysv_elf_gas.S under Zend/asm/, plus loongarch64 in     configure.ac), so the LP64D calling convention is already used in-tree.   - PCRE2's SLJIT has a LoongArch64 backend (sljitNativeLOONGARCH_64.c), so     pcre.jit=1 reports "PCRE JIT Target => LOONGARCH 64bit". The gap is     specific to the Zend JIT, not to the platform. Why it matters: LoongArch64 is a supported Linux target for several distributions (Debian loong64 ports, AOSC OS, Loongnix) and the hardware family (3A6000, 3B6000, 3C6000) is used as desktop and server hardware. PHP is a mainstream workload there, and without the JIT these systems are structurally 10-30% behind on JIT-friendly code. Frequency scaling is also not exposed on several of these platforms, so the JIT is one of the few remaining single-thread levers. Scope, as far as I can tell from ir_aarch64.dasc:   1. A DynASM target: dasm_loongarch64.lua and dasm_loongarch64.h      (encoding tables, relocations).   2. ir_loongarch64.dasc and ir_loongarch64.h: all IR opcodes, register      constraints, calling convention, stack frames, safepoints,      exception/GC handling, JIT helper ABI.   3. Wiring in config.m4 (IR_TARGET, DASM_ARCH) and the guards in      zend_jit.c / zend_jit_ir.c.   4. Running the test matrix, e.g.        make test TESTS="-d opcache.jit_buffer_size=16M -d opcache.enable=1 \          -d opcache.enable_cli=1 -d opcache.protect_memory=1 \          -d opcache.jit=tracing --repeat 2 -j\$(nproc) ext/opcache Zend"      and the same with opcache.jit=function and opcache.jit=off. Questions:   1. Would an in-tree LoongArch64 IR backend be acceptable in principle, or      are JIT backends expected to stay limited to architectures the core team      can test and maintain?   2. Is there a porting checklist beyond using ir_aarch64.dasc as a reference?   3. Given that the legacy zend_jit_*.dasc backends were removed, is the      IR-based JIT (8.4+) the only sensible target?   4. Would an initial patch limited to the DynASM target plus a skeleton IR      backend (builds, passes a small opcode subset) be reviewable, or is a      complete backend expected before discussion? I have Loongson 3B6000M hardware (LA664, 8 cores, LSX, no LASX) running AOSC OS 14 and Debian loong64, and can run tests and publish benchmark numbers. I would prefer to agree on the approach first rather than write several thousand lines of assembler that upstream would not want to carry. Thanks, tsuibin

« previous php.internals (#133074) next »