1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00

more RISC-ifications

This commit is contained in:
julianb0 2019-07-18 22:49:31 +02:00
parent 5b315ad46a
commit 40653a8047
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
32 changed files with 436 additions and 601 deletions

View File

@ -11,7 +11,7 @@ kpc: vm/Makefile
@cd vm && make --no-print-directory -s verbose=yes @cd vm && make --no-print-directory -s verbose=yes
kas: kpc as/regs.lst as/k-as.py kas: kpc as/regs.lst as/k-as.py
@cp vm/in/instrs.lst as @cp vm/ob/instrs.lst as
dos: kas dosclean dos: kas dosclean
@cd ka && make --no-print-directory -s @cd ka && make --no-print-directory -s
@ -24,7 +24,7 @@ dosclean:
@rm -f $(KODIR)/*.com $(KODIR)/*.sym @rm -f $(KODIR)/*.com $(KODIR)/*.sym
inclean: inclean:
@rm -f vm/in/arch_i.h vm/in/instrs.lst vm/ob/in/*.o @rm -f vm/ob/arch_i.h vm/ob/instrs.lst vm/ob/in/*.o
clean: dosclean clean: dosclean
@cd vm && make clean --no-print-directory -s verbose=no @cd vm && make clean --no-print-directory -s verbose=no

View File

@ -13,7 +13,6 @@ start:
mov rbp, zero mov rbp, zero
cls cls
cld
call main call main
mov rax, Sys.EnterHaltMode mov rax, Sys.EnterHaltMode

View File

@ -10,4 +10,5 @@ include "crt/err/errno.k"
include "crt/fmt/format.k" include "crt/fmt/format.k"
include "crt/str/string.k" include "crt/str/string.k"
include "crt/lib/time.k" include "crt/lib/time.k"
include "crt/lib/arith128.k"

View File

@ -34,7 +34,7 @@ doprnt:
mov ax0, b[rbx] mov ax0, b[rbx]
call .doput call .doput
inc rbx add rbx, rbx, 1
jmp .print_regular jmp .print_regular
.check_modf: .check_modf:
@ -71,7 +71,7 @@ doprnt:
cmp ax0, zero cmp ax0, zero
jmp.z .main_loop jmp.z .main_loop
inc rdi add rdi, rdi, 1
call .doput call .doput
jmp .print_string jmp .print_string
@ -82,10 +82,8 @@ doprnt:
jmp .main_loop jmp .main_loop
.modf_p: .modf_p:
mov ax0, '0' call .doput, '0'
call .doput call .doput, 'x'
mov ax0, 'x'
call .doput
; Fallthrough ; Fallthrough
.modf_x: .modf_x:
@ -122,44 +120,29 @@ doprnt:
add.z rsp, rsp, 80 add.z rsp, rsp, 80
jmp.z .main_loop jmp.z .main_loop
inc rdi add rdi, rdi, 1
call .doput call .doput
jmp .print_itoa_buf jmp .print_itoa_buf
.modf_percent: .modf_percent:
mov ax0, '%' call .doput, '%'
call .doput
jmp .main_loop jmp .main_loop
.bad_modifier: .bad_modifier:
; print "%?" to clearly indicate that something is wrong ; print "%?" to clearly indicate that something is wrong
mov ax0, '%' call .doput, '%'
call .doput call .doput, '?'
mov ax0, '?'
call .doput
jmp .main_loop jmp .main_loop
.nullstring: .nullstring:
; %s was passed a NULL ; %s was passed a NULL
mov ax0, '(' call .doput, '('
call .doput call .doput, 'n'
call .doput, 'u'
mov ax0, 'n' call .doput, 'l'
call .doput call .doput, 'l'
call .doput, ')'
mov ax0, 'u'
call .doput
mov ax0, 'l'
call .doput
mov ax0, 'l'
call .doput
mov ax0, ')'
call .doput
jmp .main_loop jmp .main_loop
@ -178,7 +161,7 @@ doprnt:
; ;
.doput: .doput:
; update print count ; update print count
inc nx1 add nx1, nx1, 1
; if n==0, don't print ; if n==0, don't print
; we follow the C convention that sprintf()-like functions ; we follow the C convention that sprintf()-like functions
@ -188,7 +171,7 @@ doprnt:
ret.z ret.z
; if n>0, decrement n and print ; if n>0, decrement n and print
dec nx0 sub nx0, nx0, 1
call nx3 call nx3
; did putc fail? ; did putc fail?

View File

@ -34,10 +34,9 @@ ltostr:
b.z ax3, zero, .conv b.z ax3, zero, .conv
b.nz ax2, 10, .conv ; base 10 b.nz ax2, 10, .conv ; base 10
sgn r11, ax1 ; extract ax1 sign shr r11, ax1, 63 ; extract ax1 sign
cmp r11, zero ; negative?
cmp r11, -1 ; negative? sub.nz ax1, zero, ax1 ; yes
neg.z ax1, ax1
; main loop ; main loop
.conv: .conv:
@ -55,7 +54,7 @@ ltostr:
.next: .next:
mov b[ax0], r10 mov b[ax0], r10
inc ax0 add ax0, ax0, 1
div ax1, ax1, ax2 div ax1, ax1, ax2
jmp .conv jmp .conv
@ -64,12 +63,11 @@ ltostr:
.fini: .fini:
cmp r11, -1 cmp r11, -1
mov.z b[ax0], '-' mov.z b[ax0], '-'
inc.z ax0 add.z ax0, ax0, 1
mov b[ax0], zero mov b[ax0], zero
mov ax0, rax call strrev2, rax
call strrev2
ret ret

View File

@ -39,12 +39,12 @@ strtoq:
.skip_spc: .skip_spc:
cmp b[rdx], ' ' cmp b[rdx], ' '
inc.z rdx add.z rdx, rdx, 1
jmp.z .skip_spc jmp.z .skip_spc
; skip + ; skip +
cmp b[rdx], '+' cmp b[rdx], '+'
inc.z rdx add.z rdx, rdx, 1
; signed? ; signed?
cmp ax2, zero cmp ax2, zero
@ -53,7 +53,7 @@ strtoq:
; parse '-' ; parse '-'
cmp b[rdx], '-' cmp b[rdx], '-'
inc.z rdx add.z rdx, rdx, 1
mov.z r10, 1 mov.z r10, 1
mov.nz r10, zero mov.nz r10, zero
@ -64,7 +64,7 @@ strtoq:
; base prefix? ; base prefix?
b.nz b[rdx], '0', .main_loop b.nz b[rdx], '0', .main_loop
inc rdx add rdx, rdx, 1
movzx rcx, b[rdx] movzx rcx, b[rdx]
; "0x"/"0b" prefix ; "0x"/"0b" prefix
@ -81,7 +81,7 @@ strtoq:
; if not, leave rax = 0 and *rdx = 'x' ; if not, leave rax = 0 and *rdx = 'x'
b.nz ax1, 16, .done b.nz ax1, 16, .done
; else ; else
inc rdx add rdx, rdx, 1
jmp .main_loop jmp .main_loop
.parsed_0b: .parsed_0b:
@ -89,7 +89,7 @@ strtoq:
; if not, leave rax = 0 and *rdx = 'b' ; if not, leave rax = 0 and *rdx = 'b'
b.nz ax1, 2, .done b.nz ax1, 2, .done
; else ; else
inc rdx add rdx, rdx, 1
jmp .main_loop jmp .main_loop
.base_0: .base_0:
@ -98,15 +98,15 @@ strtoq:
cmp b[rdx], '0' cmp b[rdx], '0'
mov.nz ax1, 10 mov.nz ax1, 10
jmp.nz .main_loop jmp.nz .main_loop
inc rdx add rdx, rdx, 1
cmp b[rdx], 'x' cmp b[rdx], 'x'
inc.z rdx add.z rdx, rdx, 1
mov.z ax1, 16 mov.z ax1, 16
jmp.z .main_loop jmp.z .main_loop
cmp b[rdx], 'b' cmp b[rdx], 'b'
inc.z rdx add.z rdx, rdx, 1
mov.z ax1, 2 mov.z ax1, 2
jmp.z .main_loop jmp.z .main_loop
@ -114,7 +114,7 @@ strtoq:
.main_loop: .main_loop:
movzx r12, b[rdx] movzx r12, b[rdx]
inc rdx add rdx, rdx, 1
cmp r12, '0' cmp r12, '0'
jmp.b .done jmp.b .done
@ -147,7 +147,7 @@ strtoq:
ret.z ret.z
; yes ; yes
neg rax, rax sub rax, zero, rax
ret ret
.bad: .bad:

59
ka/crt/lib/arith128.k Normal file
View File

@ -0,0 +1,59 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; int:int add_lq_q(int:int x, int y)
;
add_lq_q:
addf rax, ax0, ax2
adcx rdx, ax1, zero
ret
;
; int:int add_lq_lq(int:int x, int:int y)
;
add_lq_lq:
addf rax, ax0, ax2
adcx rdx, ax1, ax3
ret
;
; int:int sub_lq_q(int:int x, int y)
;
sub_lq_q:
subf rax, ax0, ax2
sbbx rdx, ax1, zero
ret
;
; int:int sub_q_lq(int x, int:int y)
;
sub_q_lq:
subf rax, ax0, ax1
sbbx rdx, zero, ax2
ret
;
; int:int sub_lq_lq(int:int x, int:int y)
;
sub_lq_lq:
subf rax, ax0, ax2
sbbx rdx, ax1, ax3
ret
;
; int:int mul_lq_q(int x, int y)
;
mul_q_q:
mov rax, ax0
mulhi rdx, rax, ax1
ret
;
; int:int imul_lq_q(int x, int y)
;
imul_q_q:
mov rax, ax0
imulhi rdx, rax, ax1
ret

View File

@ -36,7 +36,7 @@ DaysInYear:
b.nz rcx, zero, .end b.nz rcx, zero, .end
.leap: .leap:
inc rax add rax, rax, 1
.end: .end:
ret ret

View File

@ -11,12 +11,27 @@
; ;
strcmp: strcmp:
mov rcx, STRLEN_MAX mov rcx, STRLEN_MAX
cmpzsb.rep.z ax0, ax1
mov rax, b[ax0-1] .1:
mov rcx, b[ax1-1] jmp.cxz .2
sub rax, rax, rcx
movzx rax, b[ax0]
movzx rdx, b[ax1]
cmp rax, rdx
jmp.nz .2
; both zero?
add r11, rax, rdx
b.z r11, zero, .2
add ax0, ax0, 1
add ax1, ax1, 1
sub rcx, rcx, 1
jmp .1
.2:
sub rax, rax, rdx
ret ret
; ;
@ -24,14 +39,22 @@ strcmp:
; ;
strncmp: strncmp:
mov rcx, ax2 mov rcx, ax2
mov.cxz rax, zero
ret.cxz
cmpzsb.rep.z ax0, ax1 .1:
jmp.cxz .2
mov rax, b[ax0-1] mov rax, b[ax0]
mov rcx, b[ax1-1] mov rdx, b[ax1]
sub rax, rax, rcx
cmp rax, rdx
jmp.nz .2
add ax0, ax0, 1
add ax1, ax1, 1
sub rcx, rcx, 1
jmp .1
.2:
sub rax, rax, rdx
ret ret

View File

@ -5,8 +5,17 @@
; void strcpy(char *, const char *) ; void strcpy(char *, const char *)
; ;
strcpy: strcpy:
mov rcx, STRLEN_MAX mov rax, b[ax1]
movsb.rep.nz ax0, ax1 mov b[ax0], rax
b.z rax, zero, .1
add ax0, ax0, 1
add ax1, ax1, 1
jmp strcpy
.1:
ret ret
; ;
@ -14,24 +23,42 @@ strcpy:
; ;
strncpy: strncpy:
mov rcx, ax2 mov rcx, ax2
.1:
ret.cxz ret.cxz
movsb.rep.nz ax0, ax1 mov rax, b[ax1]
ret mov b[ax0], rax
add ax0, ax0, 1
add ax1, ax1, 1
sub rcx, rcx, 1
jmp .1
; ;
; void strnzcpy(char *, const char *, int) ; void strnzcpy(char *, const char *, int)
; ;
strnzcpy: strnzcpy:
mov rcx, ax2 mov rcx, ax2
ret.cxz
dec rcx
jmp.cxz .1
movsb.rep.nz ax0, ax1
.1: .1:
jmp.cxz .2
mov rax, b[ax1]
mov b[ax0], rax
b.z rax, zero, .3
add ax0, ax0, 1
add ax1, ax1, 1
sub rcx, rcx, 1
jmp .1
.2:
mov b[ax0], zero mov b[ax0], zero
.3:
ret ret

View File

@ -15,6 +15,10 @@ strnlen:
; int strlen(char *) ; int strlen(char *)
; ;
strlen: strlen:
mov ax1, STRLEN_MAX mov rcx, STRLEN_MAX
jmp strnlen mov rdx, rcx
scasb.rep.nz ax0, zero
sub rax, rdx, rcx
ret

View File

@ -18,7 +18,7 @@ strrev:
; the null terminator ; the null terminator
mov rcx, STRLEN_MAX mov rcx, STRLEN_MAX
scasb.rep.nz ax1, zero scasb.rep.nz ax1, zero
dec ax1 sub ax1, ax1, 1
.2: .2:
; copy, going backward though str ; copy, going backward though str
@ -30,8 +30,8 @@ strrev:
mov.z b[ax0+1], zero mov.z b[ax0+1], zero
ret.z ret.z
inc ax0 add ax0, ax0, 1
dec ax1 sub ax1, ax1, 1
jmp .2 jmp .2
@ -50,7 +50,7 @@ strrev2:
; the null terminator ; the null terminator
mov rcx, STRLEN_MAX mov rcx, STRLEN_MAX
scasb.rep.nz ax1, zero scasb.rep.nz ax1, zero
dec ax1 sub ax1, ax1, 1
; increase ax0 while decreasing ax1, performing exchanges ; increase ax0 while decreasing ax1, performing exchanges
.2: .2:
@ -60,8 +60,8 @@ strrev2:
xchg rax, b[ax0] xchg rax, b[ax0]
mov b[ax1], rax mov b[ax1], rax
inc ax0 add ax0, ax0, 1
dec ax1 sub ax1, ax1, 1
jmp .2 jmp .2
.3: .3:

View File

@ -28,17 +28,13 @@ TrapHandlers.epilog:
; TRAP return values: RAX-RDX ; TRAP return values: RAX-RDX
mov ax0, r12
mov ax1, $rax
mov ax2, rax mov ax2, rax
call RFS.StoreReg call RFS.StoreReg, r12, $rax
mov ax1, $rdx
mov ax2, rdx mov ax2, rdx
call RFS.StoreReg call RFS.StoreReg, r12, $rdx
mov ax0, r11 call IDT.DoneHandling, r11
call IDT.DoneHandling
iret iret

View File

@ -37,18 +37,16 @@ trap0_handler:
.handle_Exit: .handle_Exit:
; Open COMMAND.COM ; Open COMMAND.COM
mov ax0, .cmdcom call DISK.OpenFile, .cmdcom
call DISK.OpenFile
; Crash on failure ; Crash on failure
cmp rax, zero cmp rax, zero
crash.l crash.l
; Load at CMDCOM_LOADP ; Load at CMDCOM_LOADP
mov ax0, rax
mov ax1, CMDCOM_LOADP mov ax1, CMDCOM_LOADP
mov ax2, CMDCOM_MAXSZ mov ax2, CMDCOM_MAXSZ
call DISK.ReadFile call DISK.ReadFile, rax
; Assume that COMMAND.COM being ; Assume that COMMAND.COM being
; less then 4KB means something ; less then 4KB means something
@ -57,32 +55,26 @@ trap0_handler:
crash.b crash.b
; Close the handle ; Close the handle
mov ax0, rax call DISK.CloseFile, rax
call DISK.CloseFile
; Code address ; Code address
mov ax0, zero
mov ax1, $rip
mov ax2, 0x100000 mov ax2, 0x100000
call RFS.StoreReg call RFS.StoreReg, zero, $rip
; Usermode ; Usermode
mov ax1, $cr0
mov ax2, 3 mov ax2, 3
call RFS.StoreReg call RFS.StoreReg, zero, $cr0
mov rcx, CMDCOM_LOADP mov rcx, CMDCOM_LOADP
sub rcx, rcx, 0x100000 sub rcx, rcx, 0x100000
; Code offset ; Code offset
mov ax1, $cr1
mov ax2, rcx mov ax2, rcx
call RFS.StoreReg call RFS.StoreReg, zero, $cr1
; Data offset ; Data offset
mov ax1, $cr2
mov ax2, rcx mov ax2, rcx
call RFS.StoreReg call RFS.StoreReg, zero, $cr2
; Return frame ; Return frame
mov q[rbp-16], zero mov q[rbp-16], zero
@ -128,7 +120,9 @@ trap0_handler:
.handle_HaltMode: .handle_HaltMode:
hlt hlt
.HLT.loop: .HLT.loop:
xpause pause
pause
pause
scan rax scan rax
b.z rax, zero, .HLT.loop b.z rax, zero, .HLT.loop

View File

@ -1,6 +1,61 @@
; The OS/K Team licenses this file to you under the MIT license. ; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information. ; See the LICENSE file in the project root for more information.
arith128_test:
call .test_add
call .test_sub
ret
.print_lq:
push rax
push rdx
mov ax0, .fmt
call printf
add rsp, rsp, 16
prn 10
ret
.fmt = "0x%x:%x"
.test_add:
mov ax0, 0x99AABBCCDDEEFF00
mov ax1, 0x1122334455667788
mov ax2, 0xFF
call add_lq_q
call .print_lq
mov ax0, 0xFFFFFFFFFFFFFFFF
mov ax1, zero
mov ax2, 5
call add_lq_q
call .print_lq
mov ax0, 0x5500660077008800
mov ax1, 0x1100220033004400
mov ax2, 0x00AA00BB00CC00DD
mov ax3, 0x009900CE00DF00AB
call add_lq_lq
call .print_lq
ret
.test_sub:
mov ax0, 0x99AABBCCDDEEFFFF
mov ax1, 0x1122334455667788
mov ax2, 0xFF
call sub_lq_q
call .print_lq
mov ax0, zero
mov ax1, zero
mov ax2, 2
call sub_lq_q
call .print_lq
ret
file_test: file_test:
.bufsize := 256 .bufsize := 256

View File

@ -32,7 +32,7 @@ builtins.dir:
b.z rax, 0, .end b.z rax, 0, .end
; found something ; found something
inc nx0 add nx0, nx0, 1
; separate extension from file name ; separate extension from file name
mov rcx, NAME_MAX mov rcx, NAME_MAX
@ -46,13 +46,13 @@ builtins.dir:
; calculate where to put extension ; calculate where to put extension
sub r11, r10, .buf sub r11, r10, .buf
dec r11 sub r11, r11, 1
.ext_pad: .ext_pad:
; print at least 11 non-space characters before extension ; print at least 11 non-space characters before extension
b.ae r11, 11, .print_ext b.ae r11, 11, .print_ext
prn ' ' prn ' '
inc r11 add r11, r11, 1
jmp .ext_pad jmp .ext_pad
.print_ext: .print_ext:
@ -61,15 +61,16 @@ builtins.dir:
prn ' ' prn ' '
cmp b[r10], '.' cmp b[r10], '.'
inc.z r10 add.z r10, r10, 1
.print_ext.1: .print_ext.1:
b.z b[r10], 0, .print_ext.2 b.z b[r10], 0, .print_ext.2
; print and decrease rcx, unless it's already 0 ; print and decrease rcx, unless it's already 0
prn b[r10] mov r12, b[r10]
inc r10 prn r12
dec.cxnz rcx add r10, r10, 1
sub.cxnz rcx, rcx, 1
jmp .print_ext.1 jmp .print_ext.1
@ -88,10 +89,9 @@ builtins.dir:
shr rax, rdx, 10 shr rax, rdx, 10
and rdx, rdx, 1023 and rdx, rdx, 1023
mov ax0, .bytesstr
push rdx push rdx
push rax push rax
call printf call printf, .bytesstr
add rsp, rsp, 16 add rsp, rsp, 16
.bytesstr = "%d kilobytes + %d bytes" .bytesstr = "%d kilobytes + %d bytes"
@ -102,14 +102,11 @@ builtins.dir:
jmp .next jmp .next
.end: .end:
mov ax0, .endstr1
push nx0 push nx0
call printf call printf, .endstr1
add rsp, rsp, 8 add rsp, rsp, 8
mov rcx, STRLEN_MAX call print, .endstr2
mov rdx, .endstr2
prns.rep.nz rdx
pop nx0 pop nx0
ret ret

View File

@ -13,9 +13,7 @@ ps1 = "C:\\> "
main: main:
.print_prompt: .print_prompt:
mov rcx, STRLEN_MAX call print, ps1
mov rdx, ps1
prns.rep.nz rdx
; empty argbuf ; empty argbuf
mov rcx, argbuf.size mov rcx, argbuf.size
@ -43,7 +41,7 @@ main:
b.z rcx, zero, .input_loop b.z rcx, zero, .input_loop
; delete it ; delete it
dec rcx sub rcx, rcx, 1
add rdx, rcx, argbuf add rdx, rcx, argbuf
mov b[rdx], zero mov b[rdx], zero
@ -65,7 +63,7 @@ main:
; add character to buffer and increase iterator (rcx) ; add character to buffer and increase iterator (rcx)
add rdx, rcx, argbuf add rdx, rcx, argbuf
mov b[rdx], rax mov b[rdx], rax
inc rcx add rcx, rcx, 1
; another one ; another one
jmp .input_loop jmp .input_loop
@ -83,7 +81,7 @@ main:
; argv1 exists? if so, save its position ; argv1 exists? if so, save its position
mov r11, rdx mov r11, rdx
b.z b[r11], zero, .no_argv1 b.z b[r11], zero, .no_argv1
inc r11 add r11, r11, 1
.next_space: .next_space:
mov r10, b[r11] mov r10, b[r11]
@ -91,7 +89,7 @@ main:
; skip spaces ; skip spaces
cmp r10, ' ' cmp r10, ' '
inc.z r11 add.z r11, r11, 1
jmp.z .next_space jmp.z .next_space
mov q[argv1pos], r11 mov q[argv1pos], r11
@ -108,68 +106,59 @@ main:
sub rcx, rdx, argbuf sub rcx, rdx, argbuf
mov rdx, argbuf mov rdx, argbuf
mov rax, argv0 mov rax, argv0
movsb.rep rax, rdx
.mmove:
jmp.cxz .detect_builtin
mov r11, b[rdx]
mov b[rax], r11
add rdx, rdx, 1
add rax, rax, 1
sub rcx, rcx, 1
jmp .mmove
.detect_builtin: .detect_builtin:
.builtin_cls = "cls" .builtin_cls = "cls"
mov ax0, argv0 call strcmp, argv0, .builtin_cls
mov ax1, .builtin_cls
call strcmp
b.z rax, 0, .handle_CLS b.z rax, 0, .handle_CLS
.builtin_date = "date" .builtin_date = "date"
mov ax0, argv0 call strcmp, argv0, .builtin_date
mov ax1, .builtin_date
call strcmp
b.z rax, 0, .handle_DATE b.z rax, 0, .handle_DATE
.builtin_dir = "dir" .builtin_dir = "dir"
mov ax0, argv0 call strcmp, argv0, .builtin_dir
mov ax1, .builtin_dir
call strcmp
b.z rax, 0, .handle_DIR b.z rax, 0, .handle_DIR
.builtin_dump = "dump" .builtin_dump = "dump"
mov ax0, argv0 call strcmp, argv0, .builtin_dump
mov ax1, .builtin_dump
call strcmp
b.z rax, 0, .handle_DUMP b.z rax, 0, .handle_DUMP
.builtin_echo = "echo" .builtin_echo = "echo"
mov ax0, argv0 call strcmp, argv0, .builtin_echo
mov ax1, .builtin_echo
call strcmp
b.z rax, 0, .handle_ECHO b.z rax, 0, .handle_ECHO
.builtin_exit = "exit" .builtin_exit = "exit"
mov ax0, argv0 call strcmp, argv0, .builtin_exit
mov ax1, .builtin_exit
call strcmp
b.z rax, 0, .handle_EXIT b.z rax, 0, .handle_EXIT
.builtin_help = "help" .builtin_help = "help"
mov ax0, argv0 call strcmp, argv0, .builtin_help
mov ax1, .builtin_help
call strcmp
b.z rax, 0, .handle_HELP b.z rax, 0, .handle_HELP
.builtin_print = "print" .builtin_print = "print"
mov ax0, argv0 call strcmp, argv0, .builtin_print
mov ax1, .builtin_print
call strcmp
b.z rax, 0, .handle_PRINT b.z rax, 0, .handle_PRINT
.builtin_time = "time" .builtin_time = "time"
mov ax0, argv0 call strcmp, argv0, .builtin_time
mov ax1, .builtin_time
call strcmp
b.z rax, 0, .handle_TIME b.z rax, 0, .handle_TIME
.builtin_ver = "ver" .builtin_ver = "ver"
mov ax0, argv0 call strcmp, argv0, .builtin_ver
mov ax1, .builtin_ver
call strcmp
b.z rax, 0, .handle_VER b.z rax, 0, .handle_VER
jmp .command_not_found jmp .command_not_found
@ -182,19 +171,17 @@ main:
jmp .print_prompt jmp .print_prompt
.handle_DATE: .handle_DATE:
time ax0
call GetTimeUTC call GetTimeUTC
push b[rax+3] push b[rax+3]
mov rcx, b[rax+4] mov rcx, b[rax+4]
inc rcx add rcx, rcx, 1
push rcx push rcx
push w[rax+6] push w[rax+6]
mov ax0, .datefmt call printf, .datefmt
call printf
add rsp, rsp, 5*8 add rsp, rsp, 40
jmp .print_prompt jmp .print_prompt
@ -252,53 +239,36 @@ main:
jmp .print_prompt jmp .print_prompt
.handle_TIME: .handle_TIME:
time ax0
call GetTimeUTC call GetTimeUTC
push b[rax] push b[rax]
push b[rax+1] push b[rax+1]
push b[rax+2] push b[rax+2]
mov ax0, .timefmt call printf, .timefmt
call printf add rsp, rsp, 24
add rsp, rsp, 3*8
jmp .print_prompt jmp .print_prompt
.timefmt = "%d:%d:%d\n" .timefmt = "%d:%d:%d\n"
.handle_VER: .handle_VER:
mov rcx, STRLEN_MAX call print, cmd.versionstr
mov rdx, cmd.versionstr
prns.rep.nz rdx
prn 10 prn 10
jmp .print_prompt jmp .print_prompt
.handle_HELP: .handle_HELP:
mov rcx, STRLEN_MAX call print, .helpmsg
call print, .helpmsg.cls
mov rdx, .helpmsg call print, .helpmsg.date
prns.rep.nz rdx call print, .helpmsg.dir
mov rdx, .helpmsg.cls call print, .helpmsg.dump
prns.rep.nz rdx call print, .helpmsg.echo
mov rdx, .helpmsg.date call print, .helpmsg.exit
prns.rep.nz rdx call print, .helpmsg.help
mov rdx, .helpmsg.dir call print, .helpmsg.print
prns.rep.nz rdx call print, .helpmsg.time
mov rdx, .helpmsg.dump call print, .helpmsg.ver
prns.rep.nz rdx
mov rdx, .helpmsg.echo
prns.rep.nz rdx
mov rdx, .helpmsg.exit
prns.rep.nz rdx
mov rdx, .helpmsg.help
prns.rep.nz rdx
mov rdx, .helpmsg.print
prns.rep.nz rdx
mov rdx, .helpmsg.time
prns.rep.nz rdx
mov rdx, .helpmsg.ver
prns.rep.nz rdx
jmp .print_prompt jmp .print_prompt
@ -315,22 +285,17 @@ main:
.helpmsg.ver = " VER Display current COMMAND.COM and DOS kernel versions\n" .helpmsg.ver = " VER Display current COMMAND.COM and DOS kernel versions\n"
.command_not_found: .command_not_found:
mov rcx, STRLEN_MAX call print, argv0
mov rdx, argv0 call print, .cnf_errmsg
prns.rep.nz rdx
mov rdx, .cnf_errmsg
prns.rep.nz rdx
jmp .print_prompt jmp .print_prompt
.cnf_errmsg = ": command not found\n" .cnf_errmsg = ": command not found\n"
.file_not_found: .file_not_found:
mov ax0, .fnf_errmsg
push q[argv1pos] push q[argv1pos]
push argv0 push argv0
call printf call printf, .fnf_errmsg
add rsp, rsp, 16 add rsp, rsp, 16
jmp .print_prompt jmp .print_prompt
@ -338,10 +303,9 @@ main:
.fnf_errmsg = "%s: %s: file not found\n" .fnf_errmsg = "%s: %s: file not found\n"
.empty_file: .empty_file:
mov ax0, .ef_errmsg
push q[argv1pos] push q[argv1pos]
push argv0 push argv0
call printf call printf, .ef_errmsg
add rsp, rsp, 16 add rsp, rsp, 16
jmp .print_prompt jmp .print_prompt
@ -349,10 +313,9 @@ main:
.ef_errmsg = "%s: %s: file is empty\n" .ef_errmsg = "%s: %s: file is empty\n"
.couldnt_read: .couldnt_read:
mov ax0, .cno_errmsg
push q[argv1pos] push q[argv1pos]
push argv0 push argv0
call printf call printf, .cno_errmsg
add rsp, rsp, 16 add rsp, rsp, 16
jmp .print_prompt jmp .print_prompt
@ -360,12 +323,8 @@ main:
.cno_errmsg = "%s: %s: an error occured while reading file\n" .cno_errmsg = "%s: %s: an error occured while reading file\n"
.need_params: .need_params:
mov rcx, STRLEN_MAX call print, argv0
mov rdx, argv0 call print, .np_errmsg
prns.rep.nz rdx
mov rdx, .np_errmsg
prns.rep.nz rdx
jmp .print_prompt jmp .print_prompt

View File

@ -46,14 +46,14 @@ $(OBJDIR)/%.d: %.c
# echo ${CL2}[$@] ${CL}dependencies generated.${CL3};\ # echo ${CL2}[$@] ${CL}dependencies generated.${CL3};\
# fi # fi
in/instrs.lst: in/INSTRS in/arch_i.py ob/instrs.lst: in/arch_i.py
@cd in && python3 arch_i.py @cd in && python3 arch_i.py
clean: clean:
@rm -f $(OBJDIR)/*/*.o in/arch_i.h in/instrs.lst @rm -f $(OBJDIR)/*/*.o ob/arch_i.h ob/instrs.lst
@rm -f $(OBJDIR)/*/*.d @rm -f $(OBJDIR)/*/*.d
$(KEXE): in/instrs.lst $(obj) $(KEXE): ob/instrs.lst $(obj)
@gcc -O2 -lSDL2 -lSDL2_ttf -Wall $(obj) -o $(KEXE) @gcc -O2 -lSDL2 -lSDL2_ttf -Wall $(obj) -o $(KEXE)
@echo ${CL2}[$@] ${CL}made successfully.${CL3} @echo ${CL2}[$@] ${CL}made successfully.${CL3}

106
vm/in/ALU
View File

@ -5,15 +5,6 @@
# Logical instructions # # Logical instructions #
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
#
# Bitwise NOT operation
#
# $1 = NOT($2)
#
# Preserves all flags
#
not r r
# #
# Bitwise OR operation # Bitwise OR operation
# #
@ -22,10 +13,6 @@ not r r
# Preserves all flags # Preserves all flags
# #
or r r ri or r r ri
# $dest = $src1 OR NOT($src2)
orn r r ri
# $dest = NOT($src1 OR $src2)
nor r r ri
# #
# Bitwise AND operation # Bitwise AND operation
@ -35,10 +22,6 @@ nor r r ri
# Preserves all flags # Preserves all flags
# #
and r r ri and r r ri
# $dest = $src1 AND NOT($src2)
andn r r ri
# $dest = NOT($src1 AND $src2)
nand r r ri
# #
# Bitwise XOR operation # Bitwise XOR operation
@ -48,10 +31,6 @@ nand r r ri
# Preserves all flags # Preserves all flags
# #
xor r r ri xor r r ri
# $dest = $src1 XOR NOT($src2)
xorn r r ri
# $dest = NOT($src1 XOR $src2)
xnor r r ri
# #
# Logical left/right shift (SHL/SHR) # Logical left/right shift (SHL/SHR)
@ -91,50 +70,6 @@ sar r r ri
cmp r ri cmp r ri
cmp m ri cmp m ri
#
# Arithmetical SGN operation
#
# IF ($1 == 0) THEN
# $2 = 0
# ELIF ($1 GT 0) THEN
# $2 = 1
# ELSE
# $2 = LONG_MIN
# FI
#
# Treats $1 and $2 as signed values
#
# Preserves all flags
#
sgn r r
#
# Arithmetical NEG operation
#
# $1 = NOT($2) + 1
#
# Preserves all flags
#
neg r r
#
# Arithmetical INC operation
#
# $1 = $1 + 1
#
# Preserves all flags
#
inc r
#
# Arithmetical DEC operation
#
# $1 = $1 - 1
#
# Preserves all flags
#
dec r
# #
# Arithmetical ADD operation # Arithmetical ADD operation
# #
@ -146,7 +81,6 @@ dec r
# #
add r r ri add r r ri
addf r r ri addf r r ri
addo r r ri
# #
# Arithmetical SUB operation # Arithmetical SUB operation
@ -159,26 +93,22 @@ addo r r ri
# #
sub r r ri sub r r ri
subf r r ri subf r r ri
subo r r ri
# #
# Arithmetical ADD/SUB operation, with carry/overflow # Arithmetical ADD/SUB operation, with carry/overflow
# #
# $dest = $src1 + $src2 + CF (ADC) # $dest = $src1 + $src2 + CF (ADC)
# $dest = $src1 + $src2 + OF (ADO)
# $dest = $src1 - $src2 - CF (SBB) # $dest = $src1 - $src2 - CF (SBB)
# $dest = $src1 - $src2 - OF (SBO)
# #
# Preserves ZF and SF # Sets CF if unsigned integer overflow occur, clears it otherwise
# Flags CF and OF are undefined for now # Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
# #
adcx r r ri adcx r r ri
adox r r ri
sbbx r r ri sbbx r r ri
sbox r r ri
# #
# Arithmetical unsigned MUL operation # Arithmetical MUL operation
# #
# $dest = LO($src1 * $src2) # $dest = LO($src1 * $src2)
# #
@ -187,31 +117,47 @@ sbox r r ri
# #
mul r r ri mul r r ri
mulf r r ri mulf r r ri
mulo r r ri
# Arithmetical unsigned MUL operation # Arithmetical unsigned MUL operation
# #
# $dest1 = HI($dest2 * $src) # $dest1 = HI($dest2 * $src)
# $dest2 = LO($dest2 * $src) # $dest2 = LO($dest2 * $src)
# #
# Sets CF and OF if HI($2 * $3) > 0, clears them otherwise # Preserves all flags
# Preserves ZF and SF
# #
mulhi r r ri mulhi r r ri
# Arithmetical signed MUL operation
#
# $dest1 = HI($dest2 ** $src)
# $dest2 = LO($dest2 ** $src)
#
# Preserves all flags
#
imulhi r r ri
# #
# Arithmetical unsigned DIV operation # Arithmetical unsigned DIV operation
# #
# $dest1 = $1 DIV $2 # $dest = $src1 DIV $src2
# #
# Preserves all flags # Preserves all flags
# #
div r r ri div r r ri
# #
# Arithmetical unsigned modulo operation (REM) # Arithmetical signed DIV operation
# #
# $1 = $1 MOD $2 # $dest = $src1 IDIV $src2
#
# Preserves all flags
#
idiv r r ri
#
# Arithmetical modulo operation (REM)
#
# $dest = $src1 MOD $src2
# #
# Preserves all flags # Preserves all flags
# #

View File

@ -24,36 +24,21 @@ dump
# Misc. instructions # # Misc. instructions #
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
#
# Do nothing (NOOP)
#
# (nothing)
#
# Throws:
# (nothing)
#
# Preserves all flags
#
nop
# #
# Pause the CPU for a very short amount of time (PAUSE) # Pause the CPU for a very short amount of time (PAUSE)
# Used in spin-like loops # Used in spin-type loops
# #
pause pause
# #
# Pause the CPU for a relatively long time (XPAUSE) # Throw #OVF when RFX.OF=1 (INTO)
# #
# Throws: into
# #SYS if not in supervisor mode
#
xpause
# #
# Get timestamp in seconds # Get timestamp in µseconds
# #
time r utime r r
# #
# $1 = seconds since start of month # $1 = seconds since start of month
@ -62,68 +47,11 @@ time r
# #
ytime r r r ytime r r r
#
# Get timestamp in µseconds
#
utime r
#
# CPU Identification Number
#
# Does nothing (for now)
#
cpuid
#---------------------------------------------------------------------------#
# Clean-up misc. instructions #
#---------------------------------------------------------------------------#
# #
# Clear all GPR registers except RBP/RSP # Clear all GPR registers except RBP/RSP
# #
cls cls
#
# Clear base registers except RBP/RSP (CLR)
#
clr
#
# Clear argument registers (CLA)
#
cla
#
# Clear nonvolatile registers (CLN)
#
cln
#---------------------------------------------------------------------------#
# Flag manipulation instructions #
#---------------------------------------------------------------------------#
#
# Clear or set interrupt flag (CLI/STI)
#
# Throws:
# #SYS if not in supervisor mode
#
cli
sti
#
# Clear or set direction flag (CLD/STD)
#
cld
std
#
# Complement, clear or set carry flag (CMC/CLC/STC)
#
cmc
clc
stc
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# Byte-wise / bit-wise manipulation instructions # # Byte-wise / bit-wise manipulation instructions #
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
@ -144,7 +72,7 @@ dswap r r
# #
# Send a character to standard output (PRN) # Send a character to standard output (PRN)
# #
prn rim prn ri
# #
# Print a string to standard output (PRN) # Print a string to standard output (PRN)

View File

@ -52,6 +52,8 @@ b rm ri ri
# JMP(RIP) # JMP(RIP)
# #
call ri call ri
call i ri
call i ri ri
# #
# Return to caller (RET) # Return to caller (RET)
@ -103,9 +105,9 @@ pop r
# $1 = ADDR($2) # $1 = ADDR($2)
# #
# For instance: # For instance:
# LEA RAX, [RBX + RCX + 4] # LEA RAX, [RBX + RCX * 2 + 4]
# will result in: # will result in:
# RAX = RBX + RCX + 4 # RAX = RBX + RCX * 2 + 4
# #
# Preserves all flags # Preserves all flags
# #

View File

@ -20,24 +20,6 @@ stosw r ri
stosl r ri stosl r ri
stosq r ri stosq r ri
#
# Load value from string (LODSx)
#
# $1 = [%2]
# IF (DF == 0) THEN
# %str = %str + sizeof(x)
# ELSE
# %str = %str - sizeof(x)
# FI
#
# Preserves CF, OF and SF
# Sets ZF according to the loaded value
#
lodsb r r
lodsw r r
lodsl r r
lodsq r r
# #
# Scan string for a particular value (SCASx) # Scan string for a particular value (SCASx)
# #
@ -65,61 +47,5 @@ scasw r ri
scasl r ri scasl r ri
scasq r ri scasq r ri
#
# Compare bytes in strings (CMPSx)
#
# CMP([%1], [%2])
#
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# %2 = %2 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# %2 = %2 - sizeof(x)
# FI
#
# Sets CF, OF, ZF and SF according to the result of the comparison
#
# Moves past the compared values in any case!
#
cmpsb r r
cmpsw r r
cmpsl r r
cmpsq r r
#
# Safe compare bytes in strings (CMPZSx)
#
# Behaves precisely like CMPSx, except in the following case:
# - If both [%1] and [%2] are zero, clears ZF (indicating NOT EQUAL)
#
# This prevents 'CMPZSx.REP.Z' from ignoring null-terminators when both strings
# have the exact same content; this allows for short strcmp's
#
cmpzsb r r
cmpzsw r r
cmpzsl r r
cmpzsq r r
#
# Move value from string to string (MOVSx)
#
# [%1] = [%2]
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# %2 = %2 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# %2 = %2 - sizeof(x)
# FI
#
# Preserves CF, OF and SF
# Sets ZF according to the moved value
#
movsb r r
movsw r r
movsl r r
movsq r r
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#

View File

@ -58,6 +58,15 @@ trap ri
# #
iret iret
#
# Clear or set interrupt flag (CLI/STI)
#
# Throws:
# #SYS if not in supervisor mode
#
cli
sti
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# Device control instructions # # Device control instructions #
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
@ -70,7 +79,7 @@ iret
# Throws: # Throws:
# #SYS if not in supervisor mode # #SYS if not in supervisor mode
# #
devctl ri ri devctl r r
# #
# Call a device-defined function slot of device (IOCALL) # Call a device-defined function slot of device (IOCALL)

View File

@ -4,26 +4,16 @@
#include <in/instrs.h> #include <in/instrs.h>
#define _NEED_ARCH_I #define _NEED_ARCH_I
#include <in/arch_i.h> #include <ob/arch_i.h>
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_2(not) { v1 = ~v2; } IMPL_OUT;
IMPL_START_3(or) { v1 = v2 | v3; } IMPL_OUT; IMPL_START_3(or) { v1 = v2 | v3; } IMPL_OUT;
IMPL_START_3(and) { v1 = v2 & v3; } IMPL_OUT; IMPL_START_3(and) { v1 = v2 & v3; } IMPL_OUT;
IMPL_START_3(xor) { v1 = v2 ^ v3; } IMPL_OUT; IMPL_START_3(xor) { v1 = v2 ^ v3; } IMPL_OUT;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_3(orn) { v1 = v2 | ~v3; } IMPL_OUT;
IMPL_START_3(nor) { v1 = ~(v2 | v3); } IMPL_OUT;
IMPL_START_3(andn) { v1 = v2 & ~v3; } IMPL_OUT;
IMPL_START_3(nand) { v1 = ~(v2 & v3); } IMPL_OUT;
IMPL_START_3(xorn) { v1 = v2 ^ ~v3; } IMPL_OUT;
IMPL_START_3(xnor) { v1 = ~(v2 ^ v3); } IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_3(shl) { v1 = v2 << v3; } IMPL_OUT; IMPL_START_3(shl) { v1 = v2 << v3; } IMPL_OUT;
IMPL_START_3(shr) { v1 = v2 >> v3; } IMPL_OUT; IMPL_START_3(shr) { v1 = v2 >> v3; } IMPL_OUT;
IMPL_START_3(sal) { v1 = (ulong)((long)v2 << (long)v3); } IMPL_OUT; IMPL_START_3(sal) { v1 = (ulong)((long)v2 << (long)v3); } IMPL_OUT;
@ -31,81 +21,64 @@ IMPL_START_3(sar) { v1 = (ulong)((long)v2 >> (long)v3); } IMPL_OUT;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_2(sgn) { v1 = (!v2 ? 0: ((long)v2 < 0 ? (ulong)-1L : 1)); } IMPL_OUT;
IMPL_START_2(neg) { v1 = ~v2 + 1; } IMPL_OUT;
IMPL_START_1(inc) { v1++; } IMPL_OUT;
IMPL_START_1(dec) { v1--; } IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_3(add) { v1 = v2 + v3; } IMPL_OUT; IMPL_START_3(add) { v1 = v2 + v3; } IMPL_OUT;
IMPL_START_3(addf) { COMPARE(v2, ~v3+1); v1 = v2 + v3; } IMPL_OUT; IMPL_START_3(addf) { COMPARE_ADD(v2, v3); v1 = v2 + v3; } IMPL_OUT;
IMPL_START_3(addo) { COMPARE(v2, ~v3+1); v1 = v2 + v3; INTO(); } IMPL_OUT;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_2(cmp) { COMPARE(v1, v2); } IMPL_END; IMPL_START_2(cmp) { COMPARE_SUB(v1, v2); } IMPL_END;
IMPL_START_3(sub) { v1 = v2 - v3; } IMPL_OUT; IMPL_START_3(sub) { v1 = v2 - v3; } IMPL_OUT;
IMPL_START_3(subf){ COMPARE(v2, v3); v1 = v2 - v3; } IMPL_OUT; IMPL_START_3(subf){ COMPARE_SUB(v2, v3); v1 = v2 - v3; } IMPL_OUT;
IMPL_START_3(subo){ COMPARE(v2, v3); v1 = v2 - v3; INTO(); } IMPL_OUT;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_3(adcx) { v1 = v2 + v3 + !!(R(RFX)&CF); } IMPL_OUT; IMPL_START_3(adcx) { v3 += !!(R(RFX)&CF); COMPARE_ADD(v2, v3); v1 = v2 + v3; } IMPL_OUT;
IMPL_START_3(adox) { v1 = v2 + v3 + !!(R(RFX)&OF); } IMPL_OUT; IMPL_START_3(sbbx) { v3 += !!(R(RFX)&CF); COMPARE_SUB(v2, v3); v1 = v2 - v3; } IMPL_OUT;
IMPL_START_3(sbbx) { v1 = v2 - v3 - !!(R(RFX)&CF); } IMPL_OUT;
IMPL_START_3(sbox) { v1 = v2 - v3 - !!(R(RFX)&OF); } IMPL_OUT;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT;
IMPL_START_3(rem) { v1 = v2 % v3; } IMPL_OUT; IMPL_START_3(rem) { v1 = v2 % v3; } IMPL_OUT;
IMPL_START_3(div) { IMPL_START_3(div) {
if (!v3) if (!v3)
_except(ctx, E_DIV, "DIV by 0"); _except(ctx, E_DIV, "DIV by 0");
v1 = v2 / v3; v1 = v2 / v3;
} IMPL_OUT; } IMPL_OUT;
IMPL_START_3(idiv) {
if (!v3)
_except(ctx, E_DIV, "IDIV by 0");
v1 = (ulong)((long)v2/(long)v3);
} IMPL_OUT;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
// static void __unsigned_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
//
static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
{ {
ulong u1 = (u & 0xffffffff); __uint128_t r = (__uint128_t)u * (__uint128_t)v;
ulong v1 = (v & 0xffffffff);
ulong t = (u1 * v1); *hi = r >> 64;
ulong w3 = (t & 0xffffffff); *lo = r;
ulong k = (t >> 32);
u >>= 32;
t = (u * v1) + k;
k = (t & 0xffffffff);
ulong w1 = (t >> 32);
v >>= 32;
t = (u1 * v) + k;
k = (t >> 32);
if (hi) *hi = (u * v) + w1 + k;
if (lo) *lo = (t << 32) + w3;
} }
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT; IMPL_START_3(mulhi) { __unsigned_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2;
IMPL_START_3(mulhi) { multiply(v2, v3, &v1, &v2); } IMPL_OUT_2;
IMPL_START_3(mulf) { IMPL_START_3(mulf) {
ulong tmp; ulong tmp;
multiply(v2, v3, &tmp, &v1); __unsigned_multiply128(v2, v3, &tmp, &v1);
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF); R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
} IMPL_OUT; } IMPL_OUT;
IMPL_START_3(mulo) { //----------------------------------------------------------------------------//
ulong tmp;
multiply(v2, v3, &tmp, &v1); static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF); {
INTO(); __int128_t r = (__int128_t)(long)u * (__int128_t)(long)v;
} IMPL_OUT;
*hi = r >> 64;
*lo = r;
}
IMPL_START_3(imulhi) { __signed_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -131,8 +131,8 @@ def parse_2(fp):
count = count + 1 count = count + 1
fi = open("INSTRS") fi = open("INSTRS")
hd = open("arch_i.h", "w") hd = open("../ob/arch_i.h", "w")
ls = open("instrs.lst", "w") ls = open("../ob/instrs.lst", "w")
count = 0 count = 0

View File

@ -2,7 +2,6 @@
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#include <pc/arch.h> #include <pc/arch.h>
#include <in/arch_i.h>
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
@ -108,18 +107,29 @@ IMPL_START_2(name) \
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#define COMPARE(v1, v2) \ #define COMPARE_ADD(v1, v2) \
ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \ ulong _u1 = (ulong)v1, _u2 = (ulong)v2, _u3 = (_u1 + _u2); \
long _s1 = (long)v1, _s2 = (long)v2; \ \
if (_u1 + _u2 < _u2) R(RFX) |= CF; \
else R(RFX) &= ~CF; \
\
if (((_u1 ^ _u3) & (_u2 ^ _u3)) >> 63) \
R(RFX) |= OF; \
else R(RFX) &= ~OF; \
\
SET_ZSF(_u3);
#define COMPARE_SUB(v1, v2) \
ulong _u1 = (ulong)v1, _u2 = (ulong)v2, _u3 = (_u1 - _u2); \
\ \
if (_u1 < _u2) R(RFX) |= CF; \ if (_u1 < _u2) R(RFX) |= CF; \
else R(RFX) &= ~CF; \ else R(RFX) &= ~CF; \
\ \
if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \ if (((_u1 ^ _u3) & (_u1 ^ _u2)) >> 63) \
|| ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \
R(RFX) |= OF; \ R(RFX) |= OF; \
else R(RFX) &= ~OF; \ else R(RFX) &= ~OF; \
SET_ZSF(_u1 - _u2); \
SET_ZSF(_u3);
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -9,11 +9,8 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_0(nop) {} IMPL_END; IMPL_START_0(into) { INTO(); } IMPL_END;
IMPL_START_0(cpuid) { rax = rdx = 0; } IMPL_END;
IMPL_START_0(pause) { usleep(5000); } IMPL_END; IMPL_START_0(pause) { usleep(5000); } IMPL_END;
IMPL_START_0(xpause) { CHK_SUPERV(); usleep(25000); } IMPL_END;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
@ -46,8 +43,6 @@ IMPL_END;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_X_NOIN(time) { v1 = time(NULL); } IMPL_OUT;
IMPL_START_X_NOIN(ytime) IMPL_START_X_NOIN(ytime)
{ {
time_t t = time(NULL); time_t t = time(NULL);
@ -77,24 +72,6 @@ IMPL_START_0(cls) {
for (int i = R10; i <= NX7; i++) R(i) = 0; for (int i = R10; i <= NX7; i++) R(i) = 0;
} IMPL_END; } IMPL_END;
IMPL_START_0(clr) {
R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
for (int i = R10; i <= R15; i++) R(i) = 0;
} IMPL_END;
IMPL_START_0(cla) { for (int i = AX0; i <= AX7; i++) R(i) = 0; } IMPL_END;
IMPL_START_0(cln) { for (int i = NX0; i <= NX7; i++) R(i) = 0; } IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_0(cli) { CHK_SUPERV(); R(CR0) &= ~IF; } IMPL_END;
IMPL_START_0(sti) { CHK_SUPERV(); R(CR0) |= IF; } IMPL_END;
IMPL_START_0(cld) { R(RFX) &= ~DF; } IMPL_END;
IMPL_START_0(clc) { R(RFX) &= ~CF; } IMPL_END;
IMPL_START_0(std) { R(RFX) |= DF; } IMPL_END;
IMPL_START_0(stc) { R(RFX) |= CF; } IMPL_END;
IMPL_START_0(cmc) { R(RFX) = (R(RFX)&CF ? R(RFX)&~CF : R(RFX)|CF); } IMPL_END;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_2(bswap) IMPL_START_2(bswap)
@ -151,7 +128,7 @@ IMPL_START_0(prns)
{ {
uchar ch = readmemzx(ctx, R(p1->reg), 1); uchar ch = readmemzx(ctx, R(p1->reg), 1);
COMPARE(ch, 0); COMPARE_SUB(ch, 0);
if ((R(RFX) & ZF) == 0) if ((R(RFX) & ZF) == 0)
{ {

View File

@ -15,7 +15,7 @@ IMPL_START_1(loop) {
IMPL_END; IMPL_END;
IMPL_START_3(b) { IMPL_START_3(b) {
COMPARE(v1, v2); COMPARE_SUB(v1, v2);
if (eval_cond(ctx, ctx->cond)) if (eval_cond(ctx, ctx->cond))
R(RIP) = v3; R(RIP) = v3;
@ -51,11 +51,32 @@ IMPL_START_1(pop) {
R(RSP) += 8; R(RSP) += 8;
} IMPL_OUT; } IMPL_OUT;
/*
IMPL_START_1(call) { IMPL_START_1(call) {
R(RSP) -= 8; R(RSP) -= 8;
writemem(ctx, R(RIP), R(RSP), 8); writemem(ctx, R(RIP), R(RSP), 8);
R(RIP) = v1; R(RIP) = v1;
} IMPL_END; } IMPL_END;
*/
IMPL_START_1(call) {
R(RSP) -= 8;
writemem(ctx, R(RIP), R(RSP), 8);
R(RIP) = v1;
if (p2)
{
DECV(v2, p2);
ax0 = v2;
if (p3)
{
DECV(v3, p3);
ax1 = v3;
}
}
} IMPL_END;
IMPL_START_0(ret) { IMPL_START_0(ret) {
R(RIP) = readmem(ctx, R(RSP), 8); R(RSP) += 8; R(RIP) = readmem(ctx, R(RSP), 8); R(RSP) += 8;

View File

@ -25,26 +25,12 @@ IMPL_START_0(stosq) { stos_impl(ctx, p1, p2, 8); } IMPL_END;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
static void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
R(p1->reg) = readmem(ctx, R(p2->reg), len);
R(RFX) = (R(p1->reg) == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
STR_MOVE(p2->reg, len);
}
IMPL_START_0(lodsb) { lods_impl(ctx, p1, p2, 1); } IMPL_END;
IMPL_START_0(lodsw) { lods_impl(ctx, p1, p2, 2); } IMPL_END;
IMPL_START_0(lodsl) { lods_impl(ctx, p1, p2, 4); } IMPL_END;
IMPL_START_0(lodsq) { lods_impl(ctx, p1, p2, 8); } IMPL_END;
//----------------------------------------------------------------------------//
static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{ {
DECV(v2, p2); DECV(v2, p2);
ulong x = readmem(ctx, R(p1->reg), len); ulong x = readmem(ctx, R(p1->reg), len);
COMPARE(x, v2); COMPARE_SUB(x, v2);
if (x == 0) { if (x == 0) {
R(RFX) |= ZF; R(RFX) |= ZF;
@ -62,45 +48,6 @@ IMPL_START_0(scasq) { scas_impl(ctx, p1, p2, 8); } IMPL_END;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
static void cmps_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
ulong x1 = readmem(ctx, R(p1->reg), len);
ulong x2 = readmem(ctx, R(p2->reg), len);
COMPARE(x1, x2);
STR_MOVE(p1->reg, len);
STR_MOVE(p2->reg, len);
}
IMPL_START_0(cmpsb) { cmps_impl(ctx, p1, p2, 1); } IMPL_END;
IMPL_START_0(cmpsw) { cmps_impl(ctx, p1, p2, 2); } IMPL_END;
IMPL_START_0(cmpsl) { cmps_impl(ctx, p1, p2, 4); } IMPL_END;
IMPL_START_0(cmpsq) { cmps_impl(ctx, p1, p2, 8); } IMPL_END;
//----------------------------------------------------------------------------//
static void cmpzs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
ulong x1 = readmem(ctx, R(p1->reg), len);
ulong x2 = readmem(ctx, R(p2->reg), len);
COMPARE(x1, x2);
if (!x1 && !x2)
R(RFX) &= ~ZF;
STR_MOVE(p1->reg, len);
STR_MOVE(p2->reg, len);
}
IMPL_START_0(cmpzsb) { cmpzs_impl(ctx, p1, p2, 1); } IMPL_END;
IMPL_START_0(cmpzsw) { cmpzs_impl(ctx, p1, p2, 2); } IMPL_END;
IMPL_START_0(cmpzsl) { cmpzs_impl(ctx, p1, p2, 4); } IMPL_END;
IMPL_START_0(cmpzsq) { cmpzs_impl(ctx, p1, p2, 8); } IMPL_END;
//----------------------------------------------------------------------------//
static void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) static void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{ {
ulong x = readmem(ctx, R(p2->reg), len); ulong x = readmem(ctx, R(p2->reg), len);

View File

@ -42,7 +42,6 @@ IMPL_START_1(trap) {
_except(ctx, v1 + 256, "TRAP instruction"); _except(ctx, v1 + 256, "TRAP instruction");
} IMPL_END; } IMPL_END;
IMPL_START_0(into) { INTO(); } IMPL_END;
IMPL_START_0(iret) { IMPL_START_0(iret) {
if (ctx->dumpsw) if (ctx->dumpsw)
@ -55,6 +54,9 @@ IMPL_START_0(iret) {
} }
IMPL_END; IMPL_END;
IMPL_START_0(cli) { CHK_SUPERV(); R(CR0) &= ~IF; } IMPL_END;
IMPL_START_0(sti) { CHK_SUPERV(); R(CR0) |= IF; } IMPL_END;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
// //

View File

@ -102,7 +102,7 @@ extern void do_hlt(ctx_t *ctx);
#include <pc/regs.h> #include <pc/regs.h>
#include <pc/decode.h> #include <pc/decode.h>
#include <pc/except.h> #include <pc/except.h>
#include <in/arch_i.h> #include <ob/arch_i.h>
extern ctx_t main_ctx; extern ctx_t main_ctx;
extern reg_t arch_r[NREGS]; extern reg_t arch_r[NREGS];

View File

@ -2,7 +2,6 @@
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#include <pc/arch.h> #include <pc/arch.h>
#include <in/arch_i.h>
#define rfx R(RFX) #define rfx R(RFX)