ilo-vm/source/ilo-amd64-openbsd.s

424 lines
10 KiB
ArmAsm

/* AMD64 ilo, (c) 2023 Christopher Leonard, MIT License */
.global main
.extern open, read, write, close, exit, lseek
/* rax: top of stack */
/* rbx: data stack */
/* rbp: jump table address */
/* r12: address stack */
/* r13: instruction pointer */
/* r14: opcode shift register */
/* r15: memory */
.bss
.align 8
blocks: .skip 8 /* name of blocks file (ilo.blocks) */
rom: .skip 8 /* name of image (ilo.rom) */
dstack: .skip 32*4
astack: .skip 256*4
a: .skip 4 /* other variables for misc. purposes */
b: .skip 4
f: .skip 4
s: .skip 4
d: .skip 4
l: .skip 4
memory: .skip 65536*4
.section .rodata
default_blocks:
.asciz "ilo.blocks"
default_rom:
.asciz "ilo.rom"
io_table:
.byte 0
.byte iob-ioa
.byte ioc-ioa
.byte iod-ioa
.byte ioe-ioa
.byte iof-ioa
.byte iog-ioa
.byte ioh-ioa
.text
rdonly:
mov $0, %esi /* O_RDONLY */
call open
mov %eax, %edi
ret
wronly:
mov $1, %esi /* O_WRONLY */
call open
mov %eax, %edi
ret
load_image:
mov rom(%rip), %rdi
call rdonly
or %eax, %eax
jz 1f
mov %r15, %rsi
mov $65536 * 4, %edx
call read
call close
xor %eax, %eax
lea dstack-4(%rip), %rbx
lea astack-4(%rip), %r12
xor %r13d, %r13d
1: ret
save_image:
push %rax
mov rom(%rip), %rdi
call wronly
or %eax, %eax
jz 1f
mov %r15, %rsi
mov $65536 * 4, %edx
call write
call close
1: pop %rax
ret
block_read:
mov (%rbx), %esi # Get the block number
shl $12, %esi # Multiply by 4096 (block size)
xor %edx, %edx # SEEK_SET
mov %rax, %rdi # File descriptor (from %rax)
call lseek # Call lseek
mov $4096, %edx # Number of bytes to read
lea (%r15, %r8, 4), %rsi # Buffer location
call read # Call read
mov -4(%rbx), %esi # Retrieve value from the stack
sub $8, %rbx # Update the stack pointer
ret
block_write:
mov (%rbx), %esi # Get the block number
shl $12, %esi # Multiply by 4096 (block size)
xor %edx, %edx # SEEK_SET
mov %rax, %rdi # File descriptor (from %rax)
call lseek # Call lseek
mov $4096, %edx # Number of bytes to read
lea (%r15, %r8, 4), %rsi # Buffer location
call write
mov -4(%rbx), %esi # Retrieve value from the stack
sub $8, %rbx # Update the stack pointer
ret
.align 32
table: ret
.align 32
li: add $4, %rbx
inc %r13d
mov %eax, (%rbx)
mov (%r15,%r13,4), %eax
ret
.align 32
du: add $4, %rbx
mov %eax, (%rbx)
ret
.align 32
dr: mov (%rbx), %eax
sub $4, %rbx
ret
.align 32
sw: xchg (%rbx), %eax
ret
.align 32
pu: add $4, %r12
mov %eax, (%r12)
mov (%rbx), %eax
sub $4, %rbx
ret
.align 32
po: add $4, %rbx
mov %eax, (%rbx)
mov (%r12), %eax
sub $4, %r12
ret
.align 32
ju: lea -1(%eax), %r13d
mov (%rbx), %eax
sub $4, %rbx
ret
.align 32
ca: add $4, %r12
mov %r13d, (%r12)
lea -1(%eax), %r13d
mov (%rbx), %eax
sub $4, %rbx
ret
.align 32
cc: cmpl $0, (%rbx)
jz 1f
add $4, %r12
mov %r13d, (%r12)
lea -1(%eax), %r13d
1: mov -4(%rbx), %eax
sub $8, %rbx
ret
.align 32
cj: cmpl $0, (%rbx)
jz 1f
lea -1(%eax), %r13d
1: mov -4(%rbx), %eax
sub $8, %rbx
ret
.align 32
re: mov (%r12), %r13d
sub $4, %r12
ret
.align 32
eq: cmp %eax, (%rbx)
sete %al
movzbl %al, %eax
neg %eax
sub $4, %rbx
ret
.align 32
ne: cmp %eax, (%rbx)
setne %al
movzbl %al, %eax
neg %eax
sub $4, %rbx
ret
.align 32
lt: cmp %eax, (%rbx)
setl %al
movzbl %al, %eax
neg %eax
sub $4, %rbx
ret
.align 32
gt: cmp %eax, (%rbx)
setg %al
movzbl %al, %eax
neg %eax
sub $4, %rbx
ret
.align 32
fe: mov (%r15,%rax,4), %eax
ret
.align 32
st: mov (%rbx), %ecx
mov %ecx, (%r15,%rax,4)
mov -4(%rbx), %eax
sub $8, %rbx
ret
.align 32
ad: add (%rbx), %eax
sub $4, %rbx
ret
.align 32
su: sub (%rbx), %eax
neg %eax
sub $4, %rbx
ret
.align 32
mu: mull (%rbx)
sub $4, %rbx
ret
.align 32
di: mov %eax, %ecx
mov (%rbx), %eax
cdq
idiv %ecx
mov %edx, (%rbx)
ret
.align 32
an: and (%rbx), %eax
sub $4, %rbx
ret
.align 32
or: or (%rbx), %eax
sub $4, %rbx
ret
.align 32
xo: xor (%rbx), %eax
sub $4, %rbx
ret
.align 32
sl: mov %eax, %ecx
mov (%rbx), %eax
sub $4, %rbx
shl %cl, %eax
ret
.align 32
sr: mov %eax, %ecx
mov (%rbx), %eax
sub $4, %rbx
sar %cl, %eax
ret
.align 32
cp: mov %eax, %ecx
mov (%rbx), %edi
mov -4(%rbx), %esi
sub $8, %rbx
lea (%r15,%rdi,4), %rdi
lea (%r15,%rsi,4), %rsi
cmp %eax, %eax
repe cmpsd
sete %al
movzbl %al, %eax
neg %eax
ret
.align 32
cy: mov %eax, %ecx
mov (%rbx), %edi
mov -4(%rbx), %esi
mov -8(%rbx), %eax
sub $12, %rbx
lea (%r15,%rdi,4), %rdi
lea (%r15,%rsi,4), %rsi
repe movsd
ret
.align 32
io: mov %eax, %ecx
mov (%rbx), %eax
sub $4, %rbx
cmp $7, %ecx
ja 1f
lea io_table(%rip), %rdx
movzbl (%rdx,%rcx), %ecx
lea ioa(%rip), %rdx
add %rdx, %rcx
jmp *%rcx
1: ret
ioa: push %rax
mov %rsp, %rsi /* buffer pointer */
mov $1, %edx /* write one byte */
mov $1, %edi /* file descriptor (stdout) */
call write
pop %rax
mov (%rbx), %eax
sub $4, %rbx
ret
xiob: add $4, %rbx
mov %eax, (%rbx)
push %rax
xor %edi, %edi /* file descriptor (stdin) */
mov %rsp, %rsi /* buffer pointer */
mov $1, %edx /* read one byte */
call read
pop %rax
ret
iob: add $4, %rbx
mov %eax, (%rbx)
xor %edi, %edi # %edi = 0 (stdin)
lea a(%rip), %rsi # Load address of 'a' into %rsi (buffer)
mov $1, %edx # %edx = 1 (read one byte)
call read # Call libc read: read(0, a, 1)
movzx a(%rip), %eax # Move the byte from 'a' into %eax (zero-extend)
ret
ioc: mov %eax, %r8d
mov blocks(%rip), %rdi
mov $0, %rsi
mov $0, %rdx
call open /* open file (read-only) */
call block_read
call close
mov %esi, %eax
ret
iod: mov %eax, %r8d
mov blocks(%rip), %rdi
mov $1, %rsi
mov $0, %rdx
call open /* open file (write-only) */
call block_write
call close
mov %esi, %eax
ret
ioe: jmp save_image
iof: call load_image
xor %rax, %rax
xor %r13, %r13
jmp _execute
iog: mov $65536, %r13d
ret
ioh: add $8, %rbx
mov %eax, -4(%rbx)
lea astack-4(%rip), %rdx
neg %edx
lea 4*32-8(%rbx,%rdx), %rax
shr $2, %eax
mov %eax, (%rbx)
lea (%r12,%rdx), %rax
shr $2, %eax
ret
main:
xor %eax, %eax
lea memory(%rip), %r15
lea dstack-4(%rip), %rbx
lea astack-4(%rip), %r12
xor %r13d, %r13d
lea table(%rip), %rbp
mov 8(%rsp), %rcx
or %rcx, %rcx
jz 1f
mov 16(%rsp), %rcx
or %rcx, %rcx
jz 1f
mov %rcx, blocks(%rip)
mov 24(%rsp), %rcx
or %rcx, %rcx
jz 2f
mov %rcx, rom(%rip)
jmp 3f
1: lea default_blocks(%rip), %rcx
mov %rcx, blocks(%rip)
2: lea default_rom(%rip), %rcx
mov %rcx, rom(%rip)
3: call load_image
_execute:
jmp 3f
.align 64
2: mov (%r15,%r13,4), %r14d
movzbl %r14b, %edi
shr $8, %r14d
cmp $29, %edi
ja 1f
shl $5, %edi
add %rbp, %rdi
call *%rdi
1: movzbl %r14b, %edi
shr $8, %r14d
cmp $29, %edi
ja 1f
shl $5, %edi
add %rbp, %rdi
call *%rdi
1: movzbl %r14b, %edi
shr $8, %r14d
cmp $29, %edi
ja 1f
shl $5, %edi
add %rbp, %rdi
call *%rdi
1: mov %r14d, %edi
cmp $29, %edi
ja 1f
shl $5, %edi
add %rbp, %rdi
call *%rdi
1: inc %r13
3: cmp $65536, %r13
jl 2b
xor %edi, %edi
call exit /* exit program */