nx_aarch64.nx
buildroot/runtime/nx_aarch64.nx
about
DEFINITION-COMPLETE: an instruction/ABI emitter exposes one function per emitted form. Emitters
with no caller yet are the backend still being built, NOT dead code. Declared so the reachability
census buckets them instead of ratcheting a correct steady state as debt.
nx_aarch64.nx -- AArch64 Linux AAPCS asm emitter (foundation; session 1).
Pure NishiLang port of nxc2/aarch64.c. Lives outside the C side per
cardinal feedback-no-nxc2-c-extension-only-nishilang-forward. This
file is the FOUNDATION layer; sessions 2-N fill in the per-opcode
IR-to-asm dispatch and wire into nxc.nx as --target aarch64.
Session 1 scope (this file):
* AArch64 register name table (AAPCS)
* function prologue / epilogue (stp x29,x30 / add x29,sp / sub sp)
* .text / .rodata section directives
* label emission
* literal constant load (movz + movk chain for full 64-bit imm)
* register-to-register move (mov xD, xS)
* PIC-aware address load (adrp + add for label)
* add / sub register-to-register (add xD, xS, xN / sub)
* syscall (svc #0 -- the ARM64 supervisor call)
* .asciz string literal emission with byte-escape
Sessions 2-N (deferred):
* IR-instruction dispatch (binop / cmp / branch / call / load /
store / GEP / phi / return / tail_call / inline_asm)
* stack-machine slot layout per nxc2/aarch64.c
* regalloc integration (linear-scan with AAPCS-preserved regs)
* NEON SIMD (mov vD.16b, vS.16b / add vD.4s, vS.4s, vN.4s)
* full nxc.nx wiring as --target aarch64 dispatch
Output format: GNU AS unified syntax (no AT&T % prefix), Linux
AAPCS ABI, position-independent via adrp/add for label refs.
Byte-compatible with `aarch64-linux-gnu-as`.
genealogy_id: nxc2_aarch64_c_2026 + aapcs64_v1
lineage_id: nx_aarch64_foundation_v1
nx_safety_envelope:
intended_use: "Foundation emit library for AArch64 Linux
AAPCS assembly text. Per-primitive functions
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_outbuf.nx
imported by: nobody (leaf or entry point)
structs
| none |
consts
| 75 | const NX_A64_N_ARG_REGS: i64 = 8 |
functions
| 77 | func a64_arg_reg_name(idx: i64) -> *u8 |
| 93 | func a64_syscall_arg_reg_name(idx: i64) -> *u8 |
| 105 | func a64_indent(o: *OutBuf) -> i64 calls 1: out_char |
| 115 | func a64_emit_section_text(o: *OutBuf) -> i64 |
| 120 | func a64_emit_section_rodata(o: *OutBuf) -> i64 calls 1: out_str |
| 127 | func a64_emit_label(o: *OutBuf, name: *u8) -> i64 |
| 134 | func a64_emit_function_start(o: *OutBuf, name: *u8) -> i64 |
| 146 | func a64_emit_function_end(o: *OutBuf, name: *u8) -> i64 |
| 161 | func a64_emit_asciz(o: *OutBuf, s: *u8, n: i64) -> i64 |
| 233 | func a64_round_up_16(n: i64) -> i64 |
| 237 | func a64_emit_prologue(o: *OutBuf, frame_size: i64) -> i64 |
| 248 | func a64_emit_epilogue(o: *OutBuf, frame_size: i64) -> i64 |
| 268 | func a64_emit_mov_imm64(o: *OutBuf, reg: *u8, imm: i64) -> i64 |
| 305 | func a64_emit_mov_reg_reg(o: *OutBuf, dst: *u8, src: *u8) -> i64 |
| 322 | func a64_emit_adrp(o: *OutBuf, reg: *u8, label: *u8) -> i64 |
| 344 | func a64_emit_add_rrr(o: *OutBuf, dst: *u8, src1: *u8, src2: *u8) -> i64 |
| 355 | func a64_emit_sub_rrr(o: *OutBuf, dst: *u8, src1: *u8, src2: *u8) -> i64 |
| 377 | func a64_emit_svc(o: *OutBuf) -> i64 |
| 386 | func a64_emit_svc_imm(o: *OutBuf, num: i64) -> i64 |
| 398 | func a64_emit_gnu_stack_note(o: *OutBuf) -> i64 calls 1: out_str |