/*************************************************************** crc's _ _ (_) | ___ | | |/ _ \ a tiny virtual computer | | | (_) | 64kw RAM, 32-bit, Dual Stack, MISC |_|_|\___/ (c) charles childers This is an implementation of ilo in aarch64 assembly. To build: as ilo-aarch64-linux.s -o ilo.o ld -nostdlib -s ilo.o -o ilo **************************************************************/ .text .globl _start // ------------------------------------------------------------- // System Call Interface // // ilo makes use of a small number of system calls. These are: // // +-------------+--------+ // | System Call | Number | // +=============+========+ // | openat (*) | 56 | // | close | 57 | // | read | 63 | // | write | 64 | // | lseek | 62 | // | exit | 93 | // +-------------+--------+ // // (*) On most systems, I use the open() system call. But, on // aarch64, Linux does not implement open() as a system // call. Instead, it uses openat(). I implement an os_open() // to wrap the actual openat() call. // ------------------------------------------------------------- os_openat: mov x8, #56 svc #0 ret os_close: mov x8, #57 svc #0 ret os_lseek: mov x8, #62 svc #0 ret os_read: mov x8, #63 svc #0 ret os_write: mov x8, #64 svc #0 ret os_exit: mov x0, #0 // exit, with return code 0 mov x8, #93 svc #0 os_open: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 str x0, [sp, #8] str w1, [sp, #4] ldr x1, [sp, #8] ldr w2, [sp, #4] mov w0, #-100 bl os_openat ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- pop: adrp x8, sp ldr w9, [x8, :lo12:sp] subs w9, w9, #1 str w9, [x8, :lo12:sp] ldr w8, [x8, :lo12:sp] add w9, w8, #1 adrp x8, data add x8, x8, :lo12:data ldr w0, [x8, w9, sxtw #2] ret // ------------------------------------------------------------- push: sub sp, sp, #16 str w0, [sp, #12] adrp x9, sp ldr w8, [x9, :lo12:sp] add w8, w8, #1 str w8, [x9, :lo12:sp] ldr w8, [sp, #12] ldrsw x10, [x9, :lo12:sp] adrp x9, data add x9, x9, :lo12:data str w8, [x9, x10, lsl #2] add sp, sp, #16 ret // ------------------------------------------------------------- prepare_vm: adrp x8, rp str wzr, [x8, :lo12:rp] adrp x8, sp str wzr, [x8, :lo12:sp] adrp x8, ip str wzr, [x8, :lo12:ip] ret // ------------------------------------------------------------- load_image: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 adrp x8, rom ldr x0, [x8, :lo12:rom] mov w1, wzr mov w2, #438 bl os_open adrp x8, fp str w0, [x8, :lo12:fp] ldr w8, [x8, :lo12:fp] subs w8, w8, #0 cset w8, ne tbnz w8, #0, .image_found b .load_image_done .image_found: adrp x8, fp str x8, [sp, #8] // 8-byte Folded Spill ldr w0, [x8, :lo12:fp] adrp x1, m add x1, x1, :lo12:m mov x2, #262144 bl os_read ldr x8, [sp, #8] // 8-byte Folded Reload ldr w0, [x8, :lo12:fp] bl os_close bl prepare_vm .load_image_done: ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- save_image: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 adrp x8, rom ldr x0, [x8, :lo12:rom] mov w1, #1 mov w2, #438 bl os_open adrp x8, fp str x8, [sp, #8] // 8-byte Folded Spill str w0, [x8, :lo12:fp] ldr w0, [x8, :lo12:fp] adrp x1, m add x1, x1, :lo12:m mov x2, #262144 bl os_write ldr x8, [sp, #8] // 8-byte Folded Reload ldr w0, [x8, :lo12:fp] bl os_close ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- block_common: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp bl pop adrp x8, buffer str w0, [x8, :lo12:buffer] bl pop adrp x8, block str w0, [x8, :lo12:block] adrp x9, fp ldr w0, [x9, :lo12:fp] ldr w9, [x8, :lo12:block] mov w8, #4096 mul w9, w8, w9 // implicit-def: $x8 mov w8, w9 sxtw x1, w8 mov w2, wzr bl os_lseek ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- read_block: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 adrp x8, blocks ldr x0, [x8, :lo12:blocks] mov w1, wzr mov w2, #438 bl os_open adrp x8, fp str x8, [sp, #8] // 8-byte Folded Spill str w0, [x8, :lo12:fp] bl block_common ldr x8, [sp, #8] // 8-byte Folded Reload ldr w0, [x8, :lo12:fp] adrp x8, buffer ldrsw x9, [x8, :lo12:buffer] adrp x8, m add x8, x8, :lo12:m add x1, x8, x9, lsl #2 mov x2, #4096 bl os_read ldr x8, [sp, #8] // 8-byte Folded Reload ldr w0, [x8, :lo12:fp] bl os_close ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- write_block: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 adrp x8, blocks ldr x0, [x8, :lo12:blocks] mov w1, #1 mov w2, #438 bl os_open adrp x8, fp str x8, [sp, #8] // 8-byte Folded Spill str w0, [x8, :lo12:fp] bl block_common ldr x8, [sp, #8] // 8-byte Folded Reload ldr w0, [x8, :lo12:fp] adrp x8, buffer ldrsw x9, [x8, :lo12:buffer] adrp x8, m add x8, x8, :lo12:m add x1, x8, x9, lsl #2 mov x2, #4096 bl os_write ldr x8, [sp, #8] // 8-byte Folded Reload ldr w0, [x8, :lo12:fp] bl os_close ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- save_ip: adrp x9, rp ldr w8, [x9, :lo12:rp] add w8, w8, #1 str w8, [x9, :lo12:rp] adrp x8, ip ldr w8, [x8, :lo12:ip] ldrsw x10, [x9, :lo12:rp] adrp x9, address add x9, x9, :lo12:address str w8, [x9, x10, lsl #2] ret // ------------------------------------------------------------- li: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp adrp x8, ip ldr w9, [x8, :lo12:ip] add w9, w9, #1 str w9, [x8, :lo12:ip] ldrsw x9, [x8, :lo12:ip] adrp x8, m add x8, x8, :lo12:m ldr w0, [x8, x9, lsl #2] bl push ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- du: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp adrp x8, sp ldrsw x9, [x8, :lo12:sp] adrp x8, data add x8, x8, :lo12:data ldr w0, [x8, x9, lsl #2] bl push ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- dr: adrp x9, sp ldrsw x11, [x9, :lo12:sp] adrp x10, data add x10, x10, :lo12:data mov w8, wzr str w8, [x10, x11, lsl #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- sw: adrp x10, sp ldrsw x8, [x10, :lo12:sp] adrp x9, data add x9, x9, :lo12:data ldr w11, [x9, x8, lsl #2] adrp x8, a str w11, [x8, :lo12:a] ldr w11, [x10, :lo12:sp] subs w11, w11, #1 ldr w11, [x9, w11, sxtw #2] ldrsw x12, [x10, :lo12:sp] str w11, [x9, x12, lsl #2] ldr w8, [x8, :lo12:a] ldr w10, [x10, :lo12:sp] subs w10, w10, #1 str w8, [x9, w10, sxtw #2] ret // ------------------------------------------------------------- pu: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 adrp x9, rp str x9, [sp, #8] // 8-byte Folded Spill ldr w8, [x9, :lo12:rp] add w8, w8, #1 str w8, [x9, :lo12:rp] bl pop ldr x8, [sp, #8] // 8-byte Folded Reload ldrsw x9, [x8, :lo12:rp] adrp x8, address add x8, x8, :lo12:address str w0, [x8, x9, lsl #2] ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- po: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 adrp x8, rp str x8, [sp, #8] // 8-byte Folded Spill ldrsw x9, [x8, :lo12:rp] adrp x8, address add x8, x8, :lo12:address ldr w0, [x8, x9, lsl #2] bl push ldr x9, [sp, #8] // 8-byte Folded Reload ldr w8, [x9, :lo12:rp] subs w8, w8, #1 str w8, [x9, :lo12:rp] ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- ju: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp bl pop subs w8, w0, #1 adrp x9, ip str w8, [x9, :lo12:ip] ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- ca: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp bl save_ip bl pop subs w8, w0, #1 adrp x9, ip str w8, [x9, :lo12:ip] ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- cc: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp bl pop adrp x8, t str w0, [x8, :lo12:t] bl pop subs w8, w0, #0 cset w8, eq tbnz w8, #0, .cc_skip_call // if true bl save_ip adrp x8, t ldr w8, [x8, :lo12:t] subs w8, w8, #1 adrp x9, ip str w8, [x9, :lo12:ip] .cc_skip_call: ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- cj: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp bl pop adrp x8, t str w0, [x8, :lo12:t] bl pop subs w8, w0, #0 cset w8, eq tbnz w8, #0, .cj_done // flag is false, skip branch // if flag is true adrp x8, t ldr w8, [x8, :lo12:t] subs w8, w8, #1 adrp x9, ip str w8, [x9, :lo12:ip] .cj_done: ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- re: adrp x9, rp ldrsw x10, [x9, :lo12:rp] adrp x8, address add x8, x8, :lo12:address ldr w8, [x8, x10, lsl #2] adrp x10, ip str w8, [x10, :lo12:ip] ldr w8, [x9, :lo12:rp] subs w8, w8, #1 str w8, [x9, :lo12:rp] ret // ------------------------------------------------------------- eq: adrp x9, sp ldr w8, [x9, :lo12:sp] subs w8, w8, #1 adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, w8, sxtw #2] ldrsw x11, [x9, :lo12:sp] ldr w11, [x10, x11, lsl #2] subs w8, w8, w11 cset w8, eq and w11, w8, #0x1 mov w8, wzr ands w11, w11, #0x1 csinv w8, w8, wzr, eq ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- ne: adrp x9, sp ldr w8, [x9, :lo12:sp] subs w8, w8, #1 adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, w8, sxtw #2] ldrsw x11, [x9, :lo12:sp] ldr w11, [x10, x11, lsl #2] subs w8, w8, w11 cset w8, ne and w11, w8, #0x1 mov w8, wzr ands w11, w11, #0x1 csinv w8, w8, wzr, eq ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- lt: // @lt adrp x9, sp ldr w8, [x9, :lo12:sp] subs w8, w8, #1 adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, w8, sxtw #2] ldrsw x11, [x9, :lo12:sp] ldr w11, [x10, x11, lsl #2] subs w8, w8, w11 cset w8, lt and w11, w8, #0x1 mov w8, wzr ands w11, w11, #0x1 csinv w8, w8, wzr, eq ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- gt: adrp x9, sp ldr w8, [x9, :lo12:sp] subs w8, w8, #1 adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, w8, sxtw #2] ldrsw x11, [x9, :lo12:sp] ldr w11, [x10, x11, lsl #2] subs w8, w8, w11 cset w8, gt and w11, w8, #0x1 mov w8, wzr ands w11, w11, #0x1 csinv w8, w8, wzr, eq ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- fe: adrp x10, sp ldrsw x8, [x10, :lo12:sp] adrp x9, data add x9, x9, :lo12:data ldrsw x11, [x9, x8, lsl #2] adrp x8, m add x8, x8, :lo12:m ldr w8, [x8, x11, lsl #2] ldrsw x10, [x10, :lo12:sp] str w8, [x9, x10, lsl #2] ret // ------------------------------------------------------------- st: adrp x9, sp ldr w8, [x9, :lo12:sp] subs w8, w8, #1 adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, w8, sxtw #2] ldrsw x11, [x9, :lo12:sp] ldrsw x11, [x10, x11, lsl #2] adrp x10, m add x10, x10, :lo12:m str w8, [x10, x11, lsl #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #2 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- ad: adrp x9, sp ldrsw x10, [x9, :lo12:sp] adrp x8, data add x8, x8, :lo12:data ldr w11, [x8, x10, lsl #2] ldr w10, [x9, :lo12:sp] subs w10, w10, #1 add x10, x8, w10, sxtw #2 ldr w8, [x10] add w8, w8, w11 str w8, [x10] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- su: adrp x9, sp ldrsw x10, [x9, :lo12:sp] adrp x8, data add x8, x8, :lo12:data ldr w11, [x8, x10, lsl #2] ldr w10, [x9, :lo12:sp] subs w10, w10, #1 add x10, x8, w10, sxtw #2 ldr w8, [x10] subs w8, w8, w11 str w8, [x10] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- mu: adrp x9, sp ldrsw x10, [x9, :lo12:sp] adrp x8, data add x8, x8, :lo12:data ldr w11, [x8, x10, lsl #2] ldr w10, [x9, :lo12:sp] subs w10, w10, #1 add x10, x8, w10, sxtw #2 ldr w8, [x10] mul w8, w8, w11 str w8, [x10] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- di: adrp x10, sp ldrsw x8, [x10, :lo12:sp] adrp x9, data add x9, x9, :lo12:data ldr w8, [x9, x8, lsl #2] adrp x11, a str w8, [x11, :lo12:a] ldr w8, [x10, :lo12:sp] subs w8, w8, #1 ldr w12, [x9, w8, sxtw #2] adrp x8, b str w12, [x8, :lo12:b] ldr w12, [x8, :lo12:b] ldr w13, [x11, :lo12:a] sdiv w12, w12, w13 ldrsw x13, [x10, :lo12:sp] str w12, [x9, x13, lsl #2] ldr w8, [x8, :lo12:b] ldr w12, [x11, :lo12:a] sdiv w11, w8, w12 mul w11, w11, w12 subs w8, w8, w11 ldr w10, [x10, :lo12:sp] subs w10, w10, #1 str w8, [x9, w10, sxtw #2] ret // ------------------------------------------------------------- an: adrp x9, sp ldrsw x8, [x9, :lo12:sp] adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, x8, lsl #2] ldr w11, [x9, :lo12:sp] subs w11, w11, #1 ldr w11, [x10, w11, sxtw #2] and w8, w8, w11 ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- or: adrp x9, sp ldrsw x8, [x9, :lo12:sp] adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, x8, lsl #2] ldr w11, [x9, :lo12:sp] subs w11, w11, #1 ldr w11, [x10, w11, sxtw #2] orr w8, w8, w11 ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- xo: adrp x9, sp ldrsw x8, [x9, :lo12:sp] adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, x8, lsl #2] ldr w11, [x9, :lo12:sp] subs w11, w11, #1 ldr w11, [x10, w11, sxtw #2] eor w8, w8, w11 ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- sl: adrp x9, sp ldr w8, [x9, :lo12:sp] subs w8, w8, #1 adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, w8, sxtw #2] ldrsw x11, [x9, :lo12:sp] ldr w11, [x10, x11, lsl #2] lsl w8, w8, w11 ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- sr: adrp x9, sp ldr w8, [x9, :lo12:sp] subs w8, w8, #1 adrp x10, data add x10, x10, :lo12:data ldr w8, [x10, w8, sxtw #2] ldrsw x11, [x9, :lo12:sp] ldr w11, [x10, x11, lsl #2] asr w8, w8, w11 ldr w11, [x9, :lo12:sp] subs w11, w11, #1 str w8, [x10, w11, sxtw #2] ldr w8, [x9, :lo12:sp] subs w8, w8, #1 str w8, [x9, :lo12:sp] ret // ------------------------------------------------------------- cp: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp bl pop adrp x8, len str w0, [x8, :lo12:len] bl pop adrp x8, dest str w0, [x8, :lo12:dest] bl pop adrp x8, src str w0, [x8, :lo12:src] mov w0, #-1 bl push // b .LBB35_1 .LBB35_1: // =>This Inner Loop Header: Depth=1 adrp x8, len ldr w8, [x8, :lo12:len] subs w8, w8, #0 cset w8, eq tbnz w8, #0, .LBB35_5 // b .LBB35_2 .LBB35_2: // in Loop: Header=BB35_1 Depth=1 adrp x8, dest ldrsw x8, [x8, :lo12:dest] adrp x9, m add x9, x9, :lo12:m ldr w8, [x9, x8, lsl #2] adrp x10, src ldrsw x10, [x10, :lo12:src] ldr w9, [x9, x10, lsl #2] subs w8, w8, w9 cset w8, eq tbnz w8, #0, .LBB35_4 // b .LBB35_3 .LBB35_3: // in Loop: Header=BB35_1 Depth=1 adrp x8, sp ldrsw x10, [x8, :lo12:sp] adrp x9, data add x9, x9, :lo12:data mov w8, wzr str w8, [x9, x10, lsl #2] // b .LBB35_4 .LBB35_4: // in Loop: Header=BB35_1 Depth=1 adrp x9, len ldr w8, [x9, :lo12:len] subs w8, w8, #1 str w8, [x9, :lo12:len] adrp x9, src ldr w8, [x9, :lo12:src] add w8, w8, #1 str w8, [x9, :lo12:src] adrp x9, dest ldr w8, [x9, :lo12:dest] add w8, w8, #1 str w8, [x9, :lo12:dest] b .LBB35_1 .LBB35_5: ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- cy: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill mov x29, sp bl pop adrp x8, len str w0, [x8, :lo12:len] bl pop adrp x8, dest str w0, [x8, :lo12:dest] bl pop adrp x8, src str w0, [x8, :lo12:src] // b .LBB36_1 .LBB36_1: // =>This Inner Loop Header: Depth=1 adrp x8, len ldr w8, [x8, :lo12:len] subs w8, w8, #0 cset w8, eq tbnz w8, #0, .LBB36_3 // b .LBB36_2 .LBB36_2: // in Loop: Header=BB36_1 Depth=1 adrp x10, src ldrsw x8, [x10, :lo12:src] adrp x11, m add x11, x11, :lo12:m ldr w8, [x11, x8, lsl #2] adrp x9, dest ldrsw x12, [x9, :lo12:dest] str w8, [x11, x12, lsl #2] adrp x11, len ldr w8, [x11, :lo12:len] subs w8, w8, #1 str w8, [x11, :lo12:len] ldr w8, [x10, :lo12:src] add w8, w8, #1 str w8, [x10, :lo12:src] ldr w8, [x9, :lo12:dest] add w8, w8, #1 str w8, [x9, :lo12:dest] b .LBB36_1 .LBB36_3: ldp x29, x30, [sp], #16 // 16-byte Folded Reload ret // ------------------------------------------------------------- io: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 bl pop subs w8, w0, #0 // kill: def $x8 killed $w8 str x8, [sp, #8] // 8-byte Folded Spill subs x8, x8, #7 cset w8, hi tbnz w8, #0, .LBB37_10 ldr x11, [sp, #8] // 8-byte Folded Reload adrp x10, .LJTI37_0 add x10, x10, :lo12:.LJTI37_0 .Ltmp1: adr x8, .Ltmp1 ldrsw x9, [x10, x11, lsl #2] add x8, x8, x9 br x8 .LBB37_2: bl pop adrp x8, iob adrp x1, iob add x1, x1, :lo12:iob strb w0, [x8, :lo12:iob] mov w0, #1 mov x2, #1 bl os_write b .LBB37_11 .LBB37_3: mov w0, wzr adrp x8, iob str x8, [sp] // 8-byte Folded Spill adrp x1, iob add x1, x1, :lo12:iob mov x2, #1 bl os_read ldr x8, [sp] // 8-byte Folded Reload ldrb w0, [x8, :lo12:iob] bl push b .LBB37_11 .LBB37_4: bl read_block b .LBB37_11 .LBB37_5: bl write_block b .LBB37_11 .LBB37_6: bl save_image b .LBB37_11 .LBB37_7: bl load_image mov w8, #-1 adrp x9, ip str w8, [x9, :lo12:ip] b .LBB37_11 .LBB37_8: adrp x9, ip mov w8, #65536 str w8, [x9, :lo12:ip] b .LBB37_11 .LBB37_9: adrp x8, sp ldr w0, [x8, :lo12:sp] bl push adrp x8, rp ldr w0, [x8, :lo12:rp] bl push b .LBB37_11 .LBB37_10: b .LBB37_11 .LBB37_11: ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret .LJTI37_0: .word .LBB37_2-.Ltmp1 .word .LBB37_3-.Ltmp1 .word .LBB37_4-.Ltmp1 .word .LBB37_5-.Ltmp1 .word .LBB37_6-.Ltmp1 .word .LBB37_7-.Ltmp1 .word .LBB37_8-.Ltmp1 .word .LBB37_9-.Ltmp1 // ------------------------------------------------------------- process: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 stur w0, [x29, #-4] ldur w8, [x29, #-4] subs w8, w8, #0 // kill: def $x8 killed $w8 str x8, [sp] // 8-byte Folded Spill subs x8, x8, #29 cset w8, hi tbnz w8, #0, .LBB38_32 ldr x11, [sp] // 8-byte Folded Reload adrp x10, .LJTI38_0 add x10, x10, :lo12:.LJTI38_0 .Ltmp2: adr x8, .Ltmp2 ldrsw x9, [x10, x11, lsl #2] add x8, x8, x9 br x8 .LBB38_2: b .LBB38_33 .LBB38_3: b li .LBB38_4: b du .LBB38_5: b dr .LBB38_6: b sw .LBB38_7: b pu .LBB38_8: b po .LBB38_9: b ju .LBB38_10: b ca .LBB38_11: b cc .LBB38_12: b cj .LBB38_13: b re .LBB38_14: b eq .LBB38_15: b ne .LBB38_16: b lt .LBB38_17: b gt .LBB38_18: b fe .LBB38_19: b st .LBB38_20: b ad .LBB38_21: b su .LBB38_22: b mu .LBB38_23: b di .LBB38_24: b an .LBB38_25: b or .LBB38_26: b xo .LBB38_27: b sl .LBB38_28: b sr .LBB38_29: b cp .LBB38_30: b cy .LBB38_31: b io .LBB38_32: b .LBB38_33 .LBB38_33: ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret .LJTI38_0: .word .LBB38_2-.Ltmp2 .word .LBB38_3-.Ltmp2 .word .LBB38_4-.Ltmp2 .word .LBB38_5-.Ltmp2 .word .LBB38_6-.Ltmp2 .word .LBB38_7-.Ltmp2 .word .LBB38_8-.Ltmp2 .word .LBB38_9-.Ltmp2 .word .LBB38_10-.Ltmp2 .word .LBB38_11-.Ltmp2 .word .LBB38_12-.Ltmp2 .word .LBB38_13-.Ltmp2 .word .LBB38_14-.Ltmp2 .word .LBB38_15-.Ltmp2 .word .LBB38_16-.Ltmp2 .word .LBB38_17-.Ltmp2 .word .LBB38_18-.Ltmp2 .word .LBB38_19-.Ltmp2 .word .LBB38_20-.Ltmp2 .word .LBB38_21-.Ltmp2 .word .LBB38_22-.Ltmp2 .word .LBB38_23-.Ltmp2 .word .LBB38_24-.Ltmp2 .word .LBB38_25-.Ltmp2 .word .LBB38_26-.Ltmp2 .word .LBB38_27-.Ltmp2 .word .LBB38_28-.Ltmp2 .word .LBB38_29-.Ltmp2 .word .LBB38_30-.Ltmp2 .word .LBB38_31-.Ltmp2 process_bundle: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 stur w0, [x29, #-4] ldurb w0, [x29, #-4] bl process ldur w8, [x29, #-4] asr w8, w8, #8 and w0, w8, #0xff bl process ldur w8, [x29, #-4] asr w8, w8, #16 and w0, w8, #0xff bl process ldur w8, [x29, #-4] asr w8, w8, #24 and w0, w8, #0xff bl process ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- execute: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 // b .LBB40_1 .LBB40_1: // =>This Inner Loop Header: Depth=1 adrp x8, ip ldr w8, [x8, :lo12:ip] subs w8, w8, #16, lsl #12 // =65536 cset w8, ge tbnz w8, #0, .LBB40_3 // b .LBB40_2 .LBB40_2: // in Loop: Header=BB40_1 Depth=1 adrp x8, ip str x8, [sp, #8] // 8-byte Folded Spill ldrsw x9, [x8, :lo12:ip] adrp x8, m add x8, x8, :lo12:m ldr w0, [x8, x9, lsl #2] bl process_bundle ldr x9, [sp, #8] // 8-byte Folded Reload ldr w8, [x9, :lo12:ip] add w8, w8, #1 str w8, [x9, :lo12:ip] b .LBB40_1 .LBB40_3: ldp x29, x30, [sp, #16] // 16-byte Folded Reload add sp, sp, #32 ret // ------------------------------------------------------------- _start: sub sp, sp, #32 stp x29, x30, [sp, #16] // 16-byte Folded Spill add x29, sp, #16 stur w0, [x29, #-4] str x1, [sp] adrp x9, blocks adrp x8, .blocks_name add x8, x8, :lo12:.blocks_name str x8, [x9, :lo12:blocks] adrp x9, rom adrp x8, .rom_name add x8, x8, :lo12:.rom_name str x8, [x9, :lo12:rom] bl load_image bl execute // mov w0, wzr // ldp x29, x30, [sp, #16] // 16-byte Folded Reload // add sp, sp, #32 b os_exit // ------------------------------------------------------------- .blocks_name: .asciz "ilo.blocks" .rom_name: .asciz "ilo.rom" // ------------------------------------------------------------- .bss sp: .word 0 // stack pointer data: .zero 132 // data stack rp: .word 0 // address pointer address:.zero 1028 // address stack ip: .word 0 // instruction pointer m: .zero 262144 // memory fp: .word 0 // file id buffer: .word 0 // address of block buffer block: .word 0 // block number to read/write a: .word 0 // scratch t: .word 0 // scratch b: .word 0 // scratch len: .word 0 // scratch dest: .word 0 // scratch src: .word 0 // scratch iob: .zero 2 // io buffr .p2align 3 rom: .xword 0 // file name for rom .p2align 3 blocks: .xword 0 // file name for blocks