ilo-vm/source/ilo-aarch64-linux.s

1120 lines
26 KiB
ArmAsm

/***************************************************************
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