py: Add AArch64 native emitter and inline assembler. by StrideZhou · Pull Request #19697 · micropython/micropython · GitHub
Skip to content

py: Add AArch64 native emitter and inline assembler. - #19697

Draft
StrideZhou wants to merge 1 commit into
micropython:masterfrom
StrideZhou:aarch64-pr
Draft

StrideZhou wants to merge 1 commit into
micropython:masterfrom
StrideZhou:aarch64-pr

Conversation

@StrideZhou

@StrideZhou StrideZhou commented Sep 11, 2026

Copy link
Copy Markdown

1. Motivation & Problem Statement

Currently, MicroPython lacks runtime native code generation (Native/Viper) and inline assembler support for the 64-bit ARM (AArch64/ARMv8-A) architecture. This limits performance optimization opportunities on modern 64-bit ARM platforms, such as native Unix hosts or QEMU-emulated environments. This PR aims to bridge this gap by providing a complete, robust AArch64 instruction emission and inline assembly framework.

2. Summary of Changes

This PR introduces ~5,400+ lines of code, structured across the following areas:

  • Core Compiler (py/): Added the AArch64 assembler, Native/Viper code emitters, and inline assembler instruction encoders.
  • QEMU Port (ports/qemu/):
    • Introduced VIRT_AARCH64 and VIRT_AARCH64_FLOAT board configurations.
    • Added low-level support: startup code, exception handling, generic timer, PL011 UART, and semihosting (shared/runtime/semihosting_aarch64.c).
    • Math library optimization: Added hardware-accelerated sqrt and sqrtf implementations using the AArch64 fsqrt instruction (lib/libm/ and lib/libm_dbl/).
  • Unix Port: Enabled AArch64 native and inline emitters for the Unix port, supporting both native 64-bit ARM hosts and qemu-aarch64 user-mode emulation.
  • Documentation: Added docs/reference/asm_aarch64.rst, detailing register calling conventions, supported instruction subsets (including Python keyword workarounds like and_), and known limitations.
  • Test Suite (tests/):
    • Added targeted regression tests: 64-bit large constants (native_const64.py, viper_const64.py), large stack frame locals (viper_many_locals.py), and large pointer offsets (viper_ptr_large_offset.py).
    • Updated existing QEMU tests (asm_test.py, native_test.py, viper_test.py) to gracefully SKIP if the target lacks a .mpy architecture ID, preventing false CI failures.
  • CI/CD Pipeline: Added comprehensive AArch64 jobs in .github/workflows/ and tools/ci.sh, including automated ARM GNU toolchain download/verification, QEMU bare-metal build/test, Unix user-mode emulation test, and dedicated gcov coverage collection for the new emitter files.

3. Testing & Verification

Strictly adhering to project CI standards, the following verifications have been completed:

  • Local Build & Execution: Successfully built mpy-cross and the Unix port with AArch64 emitters enabled. Feature detection correctly reports aarch64.
  • Test Pass Rate: Successfully compiled all 20 AArch64 inline-assembler test files and 4 new Native/Viper regression tests. Basic regression tests resulted in 313 passed, 0 failed (feature-dependent tests unsupported by the minimal host config were correctly skipped).
  • CI Coverage: New CI jobs successfully build and run the QEMU VIRT_AARCH64 test suite, inline-assembler tests, and Unix AArch64 bytecode/native test suites, generating accurate gcov reports for asmaarch64.c, emitnaarch64.c, and emitinlineaarch64.c.

4. Trade-offs, Limitations & Alternatives

(Addressing MicroPython's core concerns regarding code size and architectural compatibility)

  • Code Size Impact: The new assembler, emitters, and runtime helpers increase the AArch64-specific source and CI footprint. However, because other architectures do not enable these emitters, there is zero runtime code-size increase for other ports. (Confirmed by the CI Code Size Report: all non-AArch64 ports show +0 +0.000%).
  • No .mpy Architecture ID (Critical Limitation): The current .mpy file format has exhausted its available architecture IDs. Consequently, persistent native .mpy loading is deliberately disabled for AArch64. Inline assembler and Native/Viper code are compiled at runtime only. This is a pragmatic trade-off; architecture-ID allocation is deferred until the .mpy v7 format and native toolchain design are updated (see Issue mpy-cross/mpy-ld/natmod Please add target for aarch64 #19386).
  • Instruction Set Limitations:
    • Floating-point (SIMD/FP) registers and instructions are not supported.
    • Load/store operations only support constant offsets; register-offset addressing and pre/post-indexed forms are not supported.
    • push and pop operations automatically pad an odd number of registers with a dummy slot (using the zero register) to maintain strict 16-byte stack pointer (sp) alignment.

5. Compliance & Generative AI Declaration

  • Git History: The commit history is strictly linear with no merge commits, adhering to MicroPython's rebase standards.
  • Generative AI Policy: Generative AI tools were utilized during the creation of this PR. However, all code and descriptions have been thoroughly read, manually validated, and are the sole responsibility of the human contributor, fully complying with the MicroPython Generative AI Policy.

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown

@codecov

codecov Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.59%. Comparing base (0414173) to head (b402048).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #19697      +/-   ##
==========================================
+ Coverage   98.55%   98.59%   +0.03%     
==========================================
  Files         182      182              
  Lines       23335    23335              
  Branches        5        5              
==========================================
+ Hits        22998    23006       +8     
+ Misses        336      328       -8     
  Partials        1        1              
Flag Coverage Δ
unix-coverage-32bit 98.59% <ø> (+0.03%) ⬆️
unix-coverage-64bit 98.52% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@StrideZhou
StrideZhou force-pushed the aarch64-pr branch 3 times, most recently from 2316851 to 7d3d35b Compare September 13, 2026 15:12
@StrideZhou
StrideZhou marked this pull request as ready for review September 13, 2026 16:38
@StrideZhou
StrideZhou marked this pull request as draft September 14, 2026 06:27
@StrideZhou
StrideZhou force-pushed the aarch64-pr branch 2 times, most recently from c86997d to 14347f4 Compare September 14, 2026 16:03
Add support for emitting native and Viper code on AArch64, together with
an AArch64 inline assembler and the corresponding instruction encoders.

Enable the emitters for the unix AArch64 target and add QEMU virt
AArch64 boards, including startup code, exception handling, timer and
PL011 UART support, semihosting, GC helpers, and libm primitives.

Add inline-assembler and native-emitter tests, plus QEMU and unix
AArch64 CI jobs.

Persistent native .mpy loading remains disabled because the current
.mpy format has no available AArch64 architecture ID.  See issue micropython#19386.

Signed-off-by: Stride Zhou <stride_anderson@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant