1120 lines
26 KiB
ArmAsm
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
|