Allow the LLVM backend to target AArch64 - #15
Open
dougchansan wants to merge 2 commits into
Open
Conversation
dougchansan
force-pushed
the
llvm19-aarch64-support
branch
from
August 13, 2026 23:03
7b74f36 to
96a2e99
Compare
The backend refused any triple that was not x86-64, but that gate was a
support policy rather than a technical limit. The function emitter and the
memory/runtime lowering contain no x86-specific code: there is no inline
asm, and functions are emitted with CallingConv::C, so the IR is
target-neutral and LLVM codegens AArch64 objects directly.
Verified on a Raspberry Pi 4 (Cortex-A72, Debian clang/LLVM 19.1.7)
against Luigi's Mansion (GLME01), a 530k-instruction DOL:
- dolrecomp emits 4164 chunk objects, "ELF 64-bit LSB relocatable,
ARM aarch64"
- the linked module loads and runs under ModernGekko
- rendering is correct, smc_failed=0, zero GX FIFO errors
- framerate matches the C backend on the same scene: 19.51 vs 19.46 FPS
Framerate on this hardware is strongly scene-dependent, so the number
above is a fixed comparison point rather than a figure for the game: the
mansion foyer is a heavy scene, while title and cutscene sequences run
roughly 30-60 FPS and other rooms are measurably faster. Both backends
were measured on the identical savestate and scene.
This enables the target; it is not a performance change. On this workload
the AArch64 LLVM backend measured the same as the C backend, though it
took zero hook fallbacks against the C backend's 196.
dougchansan
force-pushed
the
llvm19-aarch64-support
branch
from
August 13, 2026 23:26
96a2e99 to
c220111
Compare
Relaxing the triple guard let the backend accept an AArch64 target, but an x86-64 build could still not produce one: LLVM only registers the native target by default, and a target that was never registered is simply absent from the registry. lookupTarget then reports it as an unsupported triple -- "No available targets are compatible with triple aarch64-unknown-linux-gnu" -- which reads like a bad triple rather than a missing component. Register the AArch64 target explicitly and link the AArch64 CodeGen, AsmParser, Desc and Info components. This costs binary size on the build machine and nothing at runtime. The existing backend test now also emits the same module for aarch64-unknown-linux-gnu and asserts the result is an ELF64 little-endian object with e_machine EM_AARCH64. That path is a cross-compile on every host the suite runs on, and it fails at emission rather than producing a wrong object if the registration is dropped, which is what makes it worth asserting. Validated by cross-compiling two titles on an x86-64 Windows host and running them on a Raspberry Pi 4: Luigi's Mansion (63,029,456 byte module) boots, renders and plays, with zero hook fallbacks.
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.
What
dolllvm_emit_objectrejected every triple that was not x86-64:This accepts AArch64 as well.
Why it is safe
The gate looked like a support policy rather than a technical limit, and the code bears that out — the function emitter and both lowering files contain no x86-specific code:
src/backend/llvm/CallingConv::CgetDefaultTargetTriple()/getHostCPUName()native/nativecodegenLLVM componentsSo the IR is target-neutral and LLVM codegens AArch64 objects without further changes.
Verification
Raspberry Pi 4 (Cortex-A72), Debian clang/LLVM 19.1.7, against Luigi's Mansion (
GLME01) — a 530,648-instruction DOL, 4164 chunks:ELF 64-bit LSB relocatable, ARM aarch64smc_failedRuntime counters differ from the C backend as you would expect from a different codegen path, and notably the LLVM backend took zero hook fallbacks against the C backend's 196:
On that framerate number
19.5 FPS is a fixed comparison point, not a figure for the game. Framerate on this hardware is strongly scene-dependent: the mansion foyer used for the benchmark is a heavy scene, title and cutscene sequences run roughly 30–60 FPS, and other rooms are measurably faster. Both backends were measured on the identical savestate, scene, clock and settings, with a fixed 300-second frame-verified window — the point is parity between backends, not the absolute value.
Scope
This enables the target; it is not a performance change. On this workload the AArch64 LLVM backend measured the same as the C backend (the bottleneck there is L1-icache pressure, which codegen does not move). Flagging that explicitly so the change is judged on correctness rather than on a speed claim.
x86-64 behaviour is unchanged.