Conversation
ncannasse
reviewed
May 14, 2026
ncannasse
reviewed
May 14, 2026
Author
|
rebased to latest hl2_ir code |
Contributor
|
@bmdhacks Can you rebase this again? |
Author
Working on this now! |
bmdhacks
force-pushed
the
aarch64-ir
branch
from
September 12, 2026 03:44
dc4fe12 to
1ece1ef
Compare
Port the AArch64 code generator onto the current IR contract on
upstream master. Folds the original backend commit and its follow-up
ABI fixes into one topic:
* AAPCS64 register classes; 16-byte PUSH stride so SP stays 16-byte
aligned, with the native stack layout (8-byte Linux slots,
natural-size Apple packing) derived from the configured push width
* PUSH_ADDR lowering for null-access source locations, patched with
output-relative ADRP+ADD page arithmetic
* debug callback trampoline registered via hl_jit_trampoline
* CMOV materialized at the value's real width so sub-word sources
(notably bools) are zero-extended instead of loading adjacent bytes
* V29-V31 reserved as codegen temporaries and kept out of the
allocator's visible scratch set
* persistent-save accounting at the backend push unit (16 bytes on
AArch64) rather than the x86 default
* gc.c: MAP_JIT plus hl_flush_executable_memory (I-cache flush and
W^X flip) so Apple ARM64 can allocate and publish JIT pages
* module.c: walk the X29 frame-pointer chain on AArch64 instead of
the heuristic scanner, and recover the synthetic PUSH_ADDR call
site so null-access stack traces report the access line
* profile.c: extract the program counter and stack pointer from the
Darwin arm64 mcontext
* CMake and Make: select the AArch64 backend and build the VM on
aarch64/arm64 instead of skipping it
The AArch64 backend is now present, so run the full build, smoke, and Haxe test matrix on arm64 instead of faking a non-JIT `hl`: * run the Makefile smoke test on arm64 (remove the arm64 guard) * drop the `--skip-hl-jit` test flag for arm64 * install the real arm64 `hl` binary instead of a stub
bmdhacks
force-pushed
the
aarch64-ir
branch
from
September 12, 2026 04:04
1ece1ef to
54d6959
Compare
Author
Author
|
BTW, @ncannasse I avoided making any changes to the IR since I wanted this to be as drop-in as possible to make it easyish for you to accept (I know it's still a big giant wall of code). But there are some more optimizations I could do like using NEON for some ops if you'd be up for a later PR with some IR additions/alterations. Also thanks for your time and consideration and all the work. Your contributions to gaming are amazing. |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Adds an AArch64 codegen backend that plugs into the new IR pipeline (jit.c -> jit_regs.c -> jit_aarch64.c), mirroring the role of jit_x86_64.c. Targets Linux and macOS ARM64 (AAPCS64; X15/X16/X17 reserved as backend temporaries, 16-byte internal push stride, native overflow arguments at the platform ABI).
Backend surface:
hl_jit_init_regs AAPCS64 register classes (X0..X14 scratch with X5
remapped to logical slot 32, X19..X28 persist;
V0..V7 and V16..V28 scratch, V8..V15 persist,
V29..V31 reserved)
hl_codegen_init module preamble: null-access stubs, c2hl/hl2c
trampolines
hl_codegen_function IR einstr stream -> AArch64 machine code
hl_codegen_flush_consts ADRP+LDR patching for the per-module pool
(distinguishes LDR Xt/Dt/St for correct imm12
scaling)
hl_codegen_final BL relocations, jump-table absolute fixups
Encoding layer (jit_aarch64_emit.c/h) supplies the instruction encoders shared with the trampolines; floating conditional moves use FCSEL and parallel-move cycles use XCHG/CXCHG.
regs_config gains a stack_arg_size field so the IR's stack-argument accounting agrees with the backend's 16-byte-per-push convention required by AAPCS64 stack alignment.
module.c: on AArch64, walk the X29 frame-pointer chain in module_capture_stack instead of the heuristic stack scanner. The scanner produces false-positive frames from callee-saved STP X19,X20 spills that look like (stack_addr, code_addr) pairs. PUSH_ADDR emits output-relative ADRP+ADD fixups so null-access frames resolve to the correct source line.
Build: CMake selects src/jit_aarch64.c when the target processor is aarch64/arm64; the Makefile gains an ARCH=arm64 branch. CI runs the ARM64 JIT tests.
macOS arm64 code memory uses MAP_JIT and pthread_jit_write_protect_np.
Validated against unit.hl with all tests passing.