monkey-asm 2.0.2

AOT AArch64 assembly backend for monkeylang (Linux ELF and macOS Mach-O)
Documentation
---
source: asm/lower_test.rs
expression: "assembly(\"let f = fn(n) { if (n > 0) { f(n - 1) } else { 0 } };\\nf(3);\")"
---
// Generated by monkey-asm (docs/arm64-asm-backend-design.md). Do not edit.
    .text
    .globl main
    .p2align 2
main:
    stp x29, x30, [sp, #-16]!
    mov x29, sp
    adrp x0, g_globals
    add x0, x0, :lo12:g_globals
    movz x1, #0x1                   // global slot count
    bl rt_globals_init
    // let f = fn(n) { if (n > 0) { f(n - 1) } …
    adrp x0, .Lfn0                  // fn f(n)
    add x0, x0, :lo12:.Lfn0
    movz x1, #0x1                   // num_parameters
    add x2, sp, #0                  // captured values
    movz x3, #0                     // num_free
    bl rt_closure
    adrp x8, g_globals              // let f
    add x8, x8, :lo12:g_globals
    str x0, [x8]
    // f(3)
    sub sp, sp, #16
    adrp x8, g_globals              // f
    add x8, x8, :lo12:g_globals
    ldr x0, [x8]
    str x0, [sp]                    // callee
    movz x0, #0x6                   // 3
    str x0, [sp, #8]                // arg 0
    ldr x0, [sp]                    // callee
    movz x1, #0x1                   // argc
    add x2, sp, #8                  // argv
    bl rt_call
    add sp, sp, #16
.Lmain_exit:
    mov w0, #0                      // exit code is never the tagged value
    mov sp, x29
    ldp x29, x30, [sp], #16
    ret

.Lfn0:                              // fn f(n)
    stp x29, x30, [sp, #-16]!
    mov x29, sp
    sub sp, sp, #32
    stur x0, [x29, #-16]            // closure (hidden argument)
    stur x1, [x29, #-32]            // n
    ldur x0, [x29, #-32]            // n
    str x0, [sp, #-16]!             // left operand
    movz x0, #0                     // 0
    mov x1, x0                      // right operand
    ldr x0, [sp], #16               // left operand
    bl rt_gt                        // n > 0
    bl rt_truthy                    // if (n > 0)
    cbz x0, .L0
    // f(n - 1)
    sub sp, sp, #16
    ldur x0, [x29, #-16]            // current closure (f)
    str x0, [sp]                    // callee
    ldur x0, [x29, #-32]            // n
    str x0, [sp, #-16]!             // left operand
    movz x0, #0x2                   // 1
    mov x1, x0                      // right operand
    ldr x0, [sp], #16               // left operand
    bl rt_sub                       // n - 1
    str x0, [sp, #8]                // arg 0
    ldr x0, [sp]                    // callee
    movz x1, #0x1                   // argc
    add x2, sp, #8                  // argv
    bl rt_call
    add sp, sp, #16
    b .L1
.L0:
    movz x0, #0                     // 0
.L1:
.Lfn0_ret:
    mov sp, x29
    ldp x29, x30, [sp], #16
    ret

    .bss
    .balign 8
g_globals:                          // 1 global slot(s)
    .skip 8