From 40653a8047a0455c9523e2e81dfabb206b1ce102 Mon Sep 17 00:00:00 2001 From: julianb0 Date: Thu, 18 Jul 2019 22:49:31 +0200 Subject: [PATCH] more RISC-ifications --- Makefile | 4 +- ka/command.k | 1 - ka/crt/crt.k | 1 + ka/crt/fmt/doprnt.k | 49 +++++---------- ka/crt/fmt/ltostr.k | 14 ++--- ka/crt/fmt/strtol.k | 22 +++---- ka/crt/lib/arith128.k | 59 +++++++++++++++++ ka/crt/lib/time.k | 2 +- ka/crt/str/strcmp.k | 43 ++++++++++--- ka/crt/str/strcpy.k | 47 +++++++++++--- ka/crt/str/strlen.k | 8 ++- ka/crt/str/strrev.k | 12 ++-- ka/sys/intr/common.k | 10 +-- ka/sys/intr/trap0.k | 26 +++----- ka/sys/tests.k | 55 ++++++++++++++++ ka/usr/cmd/dir.k | 25 ++++---- ka/usr/cmd/main.k | 143 +++++++++++++++--------------------------- vm/Makefile | 6 +- vm/in/ALU | 106 ++++++++----------------------- vm/in/MISC | 84 ++----------------------- vm/in/MOV | 6 +- vm/in/STRING | 74 ---------------------- vm/in/SUPER | 11 +++- vm/in/alu.c | 89 +++++++++----------------- vm/in/arch_i.py | 4 +- vm/in/instrs.h | 24 ++++--- vm/in/misc.c | 27 +------- vm/in/mov.c | 23 ++++++- vm/in/string.c | 55 +--------------- vm/in/super.c | 4 +- vm/pc/arch.h | 2 +- vm/pc/exec.c | 1 - 32 files changed, 436 insertions(+), 601 deletions(-) create mode 100644 ka/crt/lib/arith128.k diff --git a/Makefile b/Makefile index 1ec14c4..b6c1bf2 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ kpc: vm/Makefile @cd vm && make --no-print-directory -s verbose=yes kas: kpc as/regs.lst as/k-as.py - @cp vm/in/instrs.lst as + @cp vm/ob/instrs.lst as dos: kas dosclean @cd ka && make --no-print-directory -s @@ -24,7 +24,7 @@ dosclean: @rm -f $(KODIR)/*.com $(KODIR)/*.sym 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 @cd vm && make clean --no-print-directory -s verbose=no diff --git a/ka/command.k b/ka/command.k index d2bce5f..cf7337c 100644 --- a/ka/command.k +++ b/ka/command.k @@ -13,7 +13,6 @@ start: mov rbp, zero cls - cld call main mov rax, Sys.EnterHaltMode diff --git a/ka/crt/crt.k b/ka/crt/crt.k index bbcf983..81a369a 100644 --- a/ka/crt/crt.k +++ b/ka/crt/crt.k @@ -10,4 +10,5 @@ include "crt/err/errno.k" include "crt/fmt/format.k" include "crt/str/string.k" include "crt/lib/time.k" +include "crt/lib/arith128.k" diff --git a/ka/crt/fmt/doprnt.k b/ka/crt/fmt/doprnt.k index 3ee0ba7..4156a26 100644 --- a/ka/crt/fmt/doprnt.k +++ b/ka/crt/fmt/doprnt.k @@ -34,7 +34,7 @@ doprnt: mov ax0, b[rbx] call .doput - inc rbx + add rbx, rbx, 1 jmp .print_regular .check_modf: @@ -71,7 +71,7 @@ doprnt: cmp ax0, zero jmp.z .main_loop - inc rdi + add rdi, rdi, 1 call .doput jmp .print_string @@ -82,10 +82,8 @@ doprnt: jmp .main_loop .modf_p: - mov ax0, '0' - call .doput - mov ax0, 'x' - call .doput + call .doput, '0' + call .doput, 'x' ; Fallthrough .modf_x: @@ -122,44 +120,29 @@ doprnt: add.z rsp, rsp, 80 jmp.z .main_loop - inc rdi + add rdi, rdi, 1 call .doput jmp .print_itoa_buf .modf_percent: - mov ax0, '%' - call .doput + call .doput, '%' jmp .main_loop .bad_modifier: ; print "%?" to clearly indicate that something is wrong - mov ax0, '%' - call .doput - - mov ax0, '?' - call .doput + call .doput, '%' + call .doput, '?' jmp .main_loop .nullstring: ; %s was passed a NULL - mov ax0, '(' - call .doput - - mov ax0, 'n' - call .doput - - mov ax0, 'u' - call .doput - - mov ax0, 'l' - call .doput - - mov ax0, 'l' - call .doput - - mov ax0, ')' - call .doput + call .doput, '(' + call .doput, 'n' + call .doput, 'u' + call .doput, 'l' + call .doput, 'l' + call .doput, ')' jmp .main_loop @@ -178,7 +161,7 @@ doprnt: ; .doput: ; update print count - inc nx1 + add nx1, nx1, 1 ; if n==0, don't print ; we follow the C convention that sprintf()-like functions @@ -188,7 +171,7 @@ doprnt: ret.z ; if n>0, decrement n and print - dec nx0 + sub nx0, nx0, 1 call nx3 ; did putc fail? diff --git a/ka/crt/fmt/ltostr.k b/ka/crt/fmt/ltostr.k index 6bd1686..57270a3 100644 --- a/ka/crt/fmt/ltostr.k +++ b/ka/crt/fmt/ltostr.k @@ -34,10 +34,9 @@ ltostr: b.z ax3, zero, .conv b.nz ax2, 10, .conv ; base 10 - sgn r11, ax1 ; extract ax1 sign - - cmp r11, -1 ; negative? - neg.z ax1, ax1 + shr r11, ax1, 63 ; extract ax1 sign + cmp r11, zero ; negative? + sub.nz ax1, zero, ax1 ; yes ; main loop .conv: @@ -55,7 +54,7 @@ ltostr: .next: mov b[ax0], r10 - inc ax0 + add ax0, ax0, 1 div ax1, ax1, ax2 jmp .conv @@ -64,12 +63,11 @@ ltostr: .fini: cmp r11, -1 mov.z b[ax0], '-' - inc.z ax0 + add.z ax0, ax0, 1 mov b[ax0], zero - mov ax0, rax - call strrev2 + call strrev2, rax ret diff --git a/ka/crt/fmt/strtol.k b/ka/crt/fmt/strtol.k index ad0e290..c3d1361 100644 --- a/ka/crt/fmt/strtol.k +++ b/ka/crt/fmt/strtol.k @@ -39,12 +39,12 @@ strtoq: .skip_spc: cmp b[rdx], ' ' - inc.z rdx + add.z rdx, rdx, 1 jmp.z .skip_spc ; skip + cmp b[rdx], '+' - inc.z rdx + add.z rdx, rdx, 1 ; signed? cmp ax2, zero @@ -53,7 +53,7 @@ strtoq: ; parse '-' cmp b[rdx], '-' - inc.z rdx + add.z rdx, rdx, 1 mov.z r10, 1 mov.nz r10, zero @@ -64,7 +64,7 @@ strtoq: ; base prefix? b.nz b[rdx], '0', .main_loop - inc rdx + add rdx, rdx, 1 movzx rcx, b[rdx] ; "0x"/"0b" prefix @@ -81,7 +81,7 @@ strtoq: ; if not, leave rax = 0 and *rdx = 'x' b.nz ax1, 16, .done ; else - inc rdx + add rdx, rdx, 1 jmp .main_loop .parsed_0b: @@ -89,7 +89,7 @@ strtoq: ; if not, leave rax = 0 and *rdx = 'b' b.nz ax1, 2, .done ; else - inc rdx + add rdx, rdx, 1 jmp .main_loop .base_0: @@ -98,15 +98,15 @@ strtoq: cmp b[rdx], '0' mov.nz ax1, 10 jmp.nz .main_loop - inc rdx + add rdx, rdx, 1 cmp b[rdx], 'x' - inc.z rdx + add.z rdx, rdx, 1 mov.z ax1, 16 jmp.z .main_loop cmp b[rdx], 'b' - inc.z rdx + add.z rdx, rdx, 1 mov.z ax1, 2 jmp.z .main_loop @@ -114,7 +114,7 @@ strtoq: .main_loop: movzx r12, b[rdx] - inc rdx + add rdx, rdx, 1 cmp r12, '0' jmp.b .done @@ -147,7 +147,7 @@ strtoq: ret.z ; yes - neg rax, rax + sub rax, zero, rax ret .bad: diff --git a/ka/crt/lib/arith128.k b/ka/crt/lib/arith128.k new file mode 100644 index 0000000..6023875 --- /dev/null +++ b/ka/crt/lib/arith128.k @@ -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 + diff --git a/ka/crt/lib/time.k b/ka/crt/lib/time.k index b56edcb..055da65 100644 --- a/ka/crt/lib/time.k +++ b/ka/crt/lib/time.k @@ -36,7 +36,7 @@ DaysInYear: b.nz rcx, zero, .end .leap: - inc rax + add rax, rax, 1 .end: ret diff --git a/ka/crt/str/strcmp.k b/ka/crt/str/strcmp.k index e2dfb01..ebfe69f 100644 --- a/ka/crt/str/strcmp.k +++ b/ka/crt/str/strcmp.k @@ -11,12 +11,27 @@ ; strcmp: mov rcx, STRLEN_MAX - cmpzsb.rep.z ax0, ax1 - mov rax, b[ax0-1] - mov rcx, b[ax1-1] - sub rax, rax, rcx +.1: + jmp.cxz .2 + 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 ; @@ -24,14 +39,22 @@ strcmp: ; strncmp: mov rcx, ax2 - mov.cxz rax, zero - ret.cxz - cmpzsb.rep.z ax0, ax1 +.1: + jmp.cxz .2 - mov rax, b[ax0-1] - mov rcx, b[ax1-1] - sub rax, rax, rcx + mov rax, b[ax0] + mov rdx, b[ax1] + 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 diff --git a/ka/crt/str/strcpy.k b/ka/crt/str/strcpy.k index e662549..52093c9 100644 --- a/ka/crt/str/strcpy.k +++ b/ka/crt/str/strcpy.k @@ -5,8 +5,17 @@ ; void strcpy(char *, const char *) ; strcpy: - mov rcx, STRLEN_MAX - movsb.rep.nz ax0, ax1 + mov rax, b[ax1] + mov b[ax0], rax + + b.z rax, zero, .1 + + add ax0, ax0, 1 + add ax1, ax1, 1 + + jmp strcpy + +.1: ret ; @@ -14,24 +23,42 @@ strcpy: ; strncpy: mov rcx, ax2 + +.1: ret.cxz - movsb.rep.nz ax0, ax1 - ret + mov rax, b[ax1] + mov b[ax0], rax + + add ax0, ax0, 1 + add ax1, ax1, 1 + sub rcx, rcx, 1 + + jmp .1 ; ; void strnzcpy(char *, const char *, int) ; strnzcpy: mov rcx, ax2 - ret.cxz - - dec rcx - jmp.cxz .1 - - movsb.rep.nz ax0, ax1 .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 + +.3: ret diff --git a/ka/crt/str/strlen.k b/ka/crt/str/strlen.k index 880d34d..355a4b4 100644 --- a/ka/crt/str/strlen.k +++ b/ka/crt/str/strlen.k @@ -15,6 +15,10 @@ strnlen: ; int strlen(char *) ; strlen: - mov ax1, STRLEN_MAX - jmp strnlen + mov rcx, STRLEN_MAX + mov rdx, rcx + scasb.rep.nz ax0, zero + + sub rax, rdx, rcx + ret diff --git a/ka/crt/str/strrev.k b/ka/crt/str/strrev.k index b3d81ca..bfb0425 100644 --- a/ka/crt/str/strrev.k +++ b/ka/crt/str/strrev.k @@ -18,7 +18,7 @@ strrev: ; the null terminator mov rcx, STRLEN_MAX scasb.rep.nz ax1, zero - dec ax1 + sub ax1, ax1, 1 .2: ; copy, going backward though str @@ -30,8 +30,8 @@ strrev: mov.z b[ax0+1], zero ret.z - inc ax0 - dec ax1 + add ax0, ax0, 1 + sub ax1, ax1, 1 jmp .2 @@ -50,7 +50,7 @@ strrev2: ; the null terminator mov rcx, STRLEN_MAX scasb.rep.nz ax1, zero - dec ax1 + sub ax1, ax1, 1 ; increase ax0 while decreasing ax1, performing exchanges .2: @@ -60,8 +60,8 @@ strrev2: xchg rax, b[ax0] mov b[ax1], rax - inc ax0 - dec ax1 + add ax0, ax0, 1 + sub ax1, ax1, 1 jmp .2 .3: diff --git a/ka/sys/intr/common.k b/ka/sys/intr/common.k index 230b3ab..922154f 100644 --- a/ka/sys/intr/common.k +++ b/ka/sys/intr/common.k @@ -28,17 +28,13 @@ TrapHandlers.epilog: ; TRAP return values: RAX-RDX - mov ax0, r12 - mov ax1, $rax mov ax2, rax - call RFS.StoreReg + call RFS.StoreReg, r12, $rax - mov ax1, $rdx mov ax2, rdx - call RFS.StoreReg + call RFS.StoreReg, r12, $rdx - mov ax0, r11 - call IDT.DoneHandling + call IDT.DoneHandling, r11 iret diff --git a/ka/sys/intr/trap0.k b/ka/sys/intr/trap0.k index f87ea9b..d0f11bb 100644 --- a/ka/sys/intr/trap0.k +++ b/ka/sys/intr/trap0.k @@ -37,18 +37,16 @@ trap0_handler: .handle_Exit: ; Open COMMAND.COM - mov ax0, .cmdcom - call DISK.OpenFile + call DISK.OpenFile, .cmdcom ; Crash on failure cmp rax, zero crash.l ; Load at CMDCOM_LOADP - mov ax0, rax mov ax1, CMDCOM_LOADP mov ax2, CMDCOM_MAXSZ - call DISK.ReadFile + call DISK.ReadFile, rax ; Assume that COMMAND.COM being ; less then 4KB means something @@ -57,32 +55,26 @@ trap0_handler: crash.b ; Close the handle - mov ax0, rax - call DISK.CloseFile + call DISK.CloseFile, rax ; Code address - mov ax0, zero - mov ax1, $rip mov ax2, 0x100000 - call RFS.StoreReg + call RFS.StoreReg, zero, $rip ; Usermode - mov ax1, $cr0 mov ax2, 3 - call RFS.StoreReg + call RFS.StoreReg, zero, $cr0 mov rcx, CMDCOM_LOADP sub rcx, rcx, 0x100000 ; Code offset - mov ax1, $cr1 mov ax2, rcx - call RFS.StoreReg + call RFS.StoreReg, zero, $cr1 ; Data offset - mov ax1, $cr2 mov ax2, rcx - call RFS.StoreReg + call RFS.StoreReg, zero, $cr2 ; Return frame mov q[rbp-16], zero @@ -128,7 +120,9 @@ trap0_handler: .handle_HaltMode: hlt .HLT.loop: - xpause + pause + pause + pause scan rax b.z rax, zero, .HLT.loop diff --git a/ka/sys/tests.k b/ka/sys/tests.k index ce85f98..6c3a3d8 100644 --- a/ka/sys/tests.k +++ b/ka/sys/tests.k @@ -1,6 +1,61 @@ ; The OS/K Team licenses this file to you under the MIT license. ; 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: .bufsize := 256 diff --git a/ka/usr/cmd/dir.k b/ka/usr/cmd/dir.k index ce86966..48ac4ca 100644 --- a/ka/usr/cmd/dir.k +++ b/ka/usr/cmd/dir.k @@ -32,7 +32,7 @@ builtins.dir: b.z rax, 0, .end ; found something - inc nx0 + add nx0, nx0, 1 ; separate extension from file name mov rcx, NAME_MAX @@ -46,13 +46,13 @@ builtins.dir: ; calculate where to put extension sub r11, r10, .buf - dec r11 + sub r11, r11, 1 .ext_pad: ; print at least 11 non-space characters before extension b.ae r11, 11, .print_ext prn ' ' - inc r11 + add r11, r11, 1 jmp .ext_pad .print_ext: @@ -61,15 +61,16 @@ builtins.dir: prn ' ' cmp b[r10], '.' - inc.z r10 + add.z r10, r10, 1 .print_ext.1: b.z b[r10], 0, .print_ext.2 ; print and decrease rcx, unless it's already 0 - prn b[r10] - inc r10 - dec.cxnz rcx + mov r12, b[r10] + prn r12 + add r10, r10, 1 + sub.cxnz rcx, rcx, 1 jmp .print_ext.1 @@ -88,10 +89,9 @@ builtins.dir: shr rax, rdx, 10 and rdx, rdx, 1023 - mov ax0, .bytesstr push rdx push rax - call printf + call printf, .bytesstr add rsp, rsp, 16 .bytesstr = "%d kilobytes + %d bytes" @@ -102,14 +102,11 @@ builtins.dir: jmp .next .end: - mov ax0, .endstr1 push nx0 - call printf + call printf, .endstr1 add rsp, rsp, 8 - mov rcx, STRLEN_MAX - mov rdx, .endstr2 - prns.rep.nz rdx + call print, .endstr2 pop nx0 ret diff --git a/ka/usr/cmd/main.k b/ka/usr/cmd/main.k index 4846ff9..32554b3 100644 --- a/ka/usr/cmd/main.k +++ b/ka/usr/cmd/main.k @@ -13,9 +13,7 @@ ps1 = "C:\\> " main: .print_prompt: - mov rcx, STRLEN_MAX - mov rdx, ps1 - prns.rep.nz rdx + call print, ps1 ; empty argbuf mov rcx, argbuf.size @@ -43,7 +41,7 @@ main: b.z rcx, zero, .input_loop ; delete it - dec rcx + sub rcx, rcx, 1 add rdx, rcx, argbuf mov b[rdx], zero @@ -65,7 +63,7 @@ main: ; add character to buffer and increase iterator (rcx) add rdx, rcx, argbuf mov b[rdx], rax - inc rcx + add rcx, rcx, 1 ; another one jmp .input_loop @@ -83,7 +81,7 @@ main: ; argv1 exists? if so, save its position mov r11, rdx b.z b[r11], zero, .no_argv1 - inc r11 + add r11, r11, 1 .next_space: mov r10, b[r11] @@ -91,7 +89,7 @@ main: ; skip spaces cmp r10, ' ' - inc.z r11 + add.z r11, r11, 1 jmp.z .next_space mov q[argv1pos], r11 @@ -108,68 +106,59 @@ main: sub rcx, rdx, argbuf mov rdx, argbuf 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: .builtin_cls = "cls" - mov ax0, argv0 - mov ax1, .builtin_cls - call strcmp + call strcmp, argv0, .builtin_cls b.z rax, 0, .handle_CLS .builtin_date = "date" - mov ax0, argv0 - mov ax1, .builtin_date - call strcmp + call strcmp, argv0, .builtin_date b.z rax, 0, .handle_DATE .builtin_dir = "dir" - mov ax0, argv0 - mov ax1, .builtin_dir - call strcmp + call strcmp, argv0, .builtin_dir b.z rax, 0, .handle_DIR .builtin_dump = "dump" - mov ax0, argv0 - mov ax1, .builtin_dump - call strcmp + call strcmp, argv0, .builtin_dump b.z rax, 0, .handle_DUMP .builtin_echo = "echo" - mov ax0, argv0 - mov ax1, .builtin_echo - call strcmp + call strcmp, argv0, .builtin_echo b.z rax, 0, .handle_ECHO .builtin_exit = "exit" - mov ax0, argv0 - mov ax1, .builtin_exit - call strcmp + call strcmp, argv0, .builtin_exit b.z rax, 0, .handle_EXIT .builtin_help = "help" - mov ax0, argv0 - mov ax1, .builtin_help - call strcmp + call strcmp, argv0, .builtin_help b.z rax, 0, .handle_HELP .builtin_print = "print" - mov ax0, argv0 - mov ax1, .builtin_print - call strcmp + call strcmp, argv0, .builtin_print b.z rax, 0, .handle_PRINT .builtin_time = "time" - mov ax0, argv0 - mov ax1, .builtin_time - call strcmp + call strcmp, argv0, .builtin_time b.z rax, 0, .handle_TIME .builtin_ver = "ver" - mov ax0, argv0 - mov ax1, .builtin_ver - call strcmp + call strcmp, argv0, .builtin_ver b.z rax, 0, .handle_VER jmp .command_not_found @@ -182,19 +171,17 @@ main: jmp .print_prompt .handle_DATE: - time ax0 call GetTimeUTC push b[rax+3] mov rcx, b[rax+4] - inc rcx + add rcx, rcx, 1 push rcx push w[rax+6] - mov ax0, .datefmt - call printf + call printf, .datefmt - add rsp, rsp, 5*8 + add rsp, rsp, 40 jmp .print_prompt @@ -252,53 +239,36 @@ main: jmp .print_prompt .handle_TIME: - time ax0 call GetTimeUTC push b[rax] push b[rax+1] push b[rax+2] - mov ax0, .timefmt - call printf - add rsp, rsp, 3*8 + call printf, .timefmt + add rsp, rsp, 24 jmp .print_prompt .timefmt = "%d:%d:%d\n" .handle_VER: - mov rcx, STRLEN_MAX - mov rdx, cmd.versionstr - prns.rep.nz rdx + call print, cmd.versionstr prn 10 jmp .print_prompt .handle_HELP: - mov rcx, STRLEN_MAX - - mov rdx, .helpmsg - prns.rep.nz rdx - mov rdx, .helpmsg.cls - prns.rep.nz rdx - mov rdx, .helpmsg.date - prns.rep.nz rdx - mov rdx, .helpmsg.dir - prns.rep.nz rdx - mov rdx, .helpmsg.dump - 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 + call print, .helpmsg + call print, .helpmsg.cls + call print, .helpmsg.date + call print, .helpmsg.dir + call print, .helpmsg.dump + call print, .helpmsg.echo + call print, .helpmsg.exit + call print, .helpmsg.help + call print, .helpmsg.print + call print, .helpmsg.time + call print, .helpmsg.ver jmp .print_prompt @@ -315,22 +285,17 @@ main: .helpmsg.ver = " VER Display current COMMAND.COM and DOS kernel versions\n" .command_not_found: - mov rcx, STRLEN_MAX - mov rdx, argv0 - prns.rep.nz rdx - - mov rdx, .cnf_errmsg - prns.rep.nz rdx + call print, argv0 + call print, .cnf_errmsg jmp .print_prompt .cnf_errmsg = ": command not found\n" .file_not_found: - mov ax0, .fnf_errmsg push q[argv1pos] push argv0 - call printf + call printf, .fnf_errmsg add rsp, rsp, 16 jmp .print_prompt @@ -338,10 +303,9 @@ main: .fnf_errmsg = "%s: %s: file not found\n" .empty_file: - mov ax0, .ef_errmsg push q[argv1pos] push argv0 - call printf + call printf, .ef_errmsg add rsp, rsp, 16 jmp .print_prompt @@ -349,10 +313,9 @@ main: .ef_errmsg = "%s: %s: file is empty\n" .couldnt_read: - mov ax0, .cno_errmsg push q[argv1pos] push argv0 - call printf + call printf, .cno_errmsg add rsp, rsp, 16 jmp .print_prompt @@ -360,12 +323,8 @@ main: .cno_errmsg = "%s: %s: an error occured while reading file\n" .need_params: - mov rcx, STRLEN_MAX - mov rdx, argv0 - prns.rep.nz rdx - - mov rdx, .np_errmsg - prns.rep.nz rdx + call print, argv0 + call print, .np_errmsg jmp .print_prompt diff --git a/vm/Makefile b/vm/Makefile index 7436d4c..6aee436 100644 --- a/vm/Makefile +++ b/vm/Makefile @@ -46,14 +46,14 @@ $(OBJDIR)/%.d: %.c # echo ${CL2}[$@] ${CL}dependencies generated.${CL3};\ # fi -in/instrs.lst: in/INSTRS in/arch_i.py +ob/instrs.lst: in/arch_i.py @cd in && python3 arch_i.py 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 -$(KEXE): in/instrs.lst $(obj) +$(KEXE): ob/instrs.lst $(obj) @gcc -O2 -lSDL2 -lSDL2_ttf -Wall $(obj) -o $(KEXE) @echo ${CL2}[$@] ${CL}made successfully.${CL3} diff --git a/vm/in/ALU b/vm/in/ALU index b3d07e9..9282191 100644 --- a/vm/in/ALU +++ b/vm/in/ALU @@ -5,15 +5,6 @@ # Logical instructions # #---------------------------------------------------------------------------# -# -# Bitwise NOT operation -# -# $1 = NOT($2) -# -# Preserves all flags -# -not r r - # # Bitwise OR operation # @@ -22,10 +13,6 @@ not r r # Preserves all flags # 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 @@ -35,10 +22,6 @@ nor r r ri # Preserves all flags # 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 @@ -48,10 +31,6 @@ nand r r ri # Preserves all flags # 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) @@ -91,50 +70,6 @@ sar r r ri cmp r 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 # @@ -146,7 +81,6 @@ dec r # add r r ri addf r r ri -addo r r ri # # Arithmetical SUB operation @@ -159,26 +93,22 @@ addo r r ri # sub r r ri subf r r ri -subo r r ri # # Arithmetical ADD/SUB operation, with carry/overflow # # $dest = $src1 + $src2 + CF (ADC) -# $dest = $src1 + $src2 + OF (ADO) # $dest = $src1 - $src2 - CF (SBB) -# $dest = $src1 - $src2 - OF (SBO) # -# Preserves ZF and SF -# Flags CF and OF are undefined for now +# Sets CF if unsigned integer overflow occur, clears it otherwise +# Sets OF is signed integer overflow occur, clears it otherwise +# Sets ZF and SF according to the result # adcx r r ri -adox r r ri sbbx r r ri -sbox r r ri # -# Arithmetical unsigned MUL operation +# Arithmetical MUL operation # # $dest = LO($src1 * $src2) # @@ -187,31 +117,47 @@ sbox r r ri # mul r r ri mulf r r ri -mulo r r ri # Arithmetical unsigned MUL operation # # $dest1 = HI($dest2 * $src) # $dest2 = LO($dest2 * $src) # -# Sets CF and OF if HI($2 * $3) > 0, clears them otherwise -# Preserves ZF and SF +# Preserves all flags # 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 # -# $dest1 = $1 DIV $2 +# $dest = $src1 DIV $src2 # # Preserves all flags # 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 # diff --git a/vm/in/MISC b/vm/in/MISC index 56d2646..7397baf 100644 --- a/vm/in/MISC +++ b/vm/in/MISC @@ -24,36 +24,21 @@ dump # Misc. instructions # #---------------------------------------------------------------------------# -# -# Do nothing (NOOP) -# -# (nothing) -# -# Throws: -# (nothing) -# -# Preserves all flags -# -nop - # # Pause the CPU for a very short amount of time (PAUSE) -# Used in spin-like loops +# Used in spin-type loops # pause # -# Pause the CPU for a relatively long time (XPAUSE) +# Throw #OVF when RFX.OF=1 (INTO) # -# Throws: -# #SYS if not in supervisor mode -# -xpause +into # -# Get timestamp in seconds +# Get timestamp in µseconds # -time r +utime r r # # $1 = seconds since start of month @@ -62,68 +47,11 @@ time 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 # 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 # #---------------------------------------------------------------------------# @@ -144,7 +72,7 @@ dswap r r # # Send a character to standard output (PRN) # -prn rim +prn ri # # Print a string to standard output (PRN) diff --git a/vm/in/MOV b/vm/in/MOV index 17b4cd9..9d94547 100644 --- a/vm/in/MOV +++ b/vm/in/MOV @@ -52,6 +52,8 @@ b rm ri ri # JMP(RIP) # call ri +call i ri +call i ri ri # # Return to caller (RET) @@ -103,9 +105,9 @@ pop r # $1 = ADDR($2) # # For instance: -# LEA RAX, [RBX + RCX + 4] +# LEA RAX, [RBX + RCX * 2 + 4] # will result in: -# RAX = RBX + RCX + 4 +# RAX = RBX + RCX * 2 + 4 # # Preserves all flags # diff --git a/vm/in/STRING b/vm/in/STRING index 4dd3f08..3fa33ff 100644 --- a/vm/in/STRING +++ b/vm/in/STRING @@ -20,24 +20,6 @@ stosw r ri stosl 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) # @@ -65,61 +47,5 @@ scasw r ri scasl 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 - #---------------------------------------------------------------------------# diff --git a/vm/in/SUPER b/vm/in/SUPER index 519998a..4197855 100644 --- a/vm/in/SUPER +++ b/vm/in/SUPER @@ -58,6 +58,15 @@ trap ri # iret +# +# Clear or set interrupt flag (CLI/STI) +# +# Throws: +# #SYS if not in supervisor mode +# +cli +sti + #---------------------------------------------------------------------------# # Device control instructions # #---------------------------------------------------------------------------# @@ -70,7 +79,7 @@ iret # Throws: # #SYS if not in supervisor mode # -devctl ri ri +devctl r r # # Call a device-defined function slot of device (IOCALL) diff --git a/vm/in/alu.c b/vm/in/alu.c index e1d2378..d68db41 100644 --- a/vm/in/alu.c +++ b/vm/in/alu.c @@ -4,26 +4,16 @@ #include #define _NEED_ARCH_I -#include +#include //----------------------------------------------------------------------------// -IMPL_START_2(not) { v1 = ~v2; } IMPL_OUT; IMPL_START_3(or) { 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(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(shr) { v1 = v2 >> 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(addf) { COMPARE(v2, ~v3+1); v1 = v2 + v3; } IMPL_OUT; -IMPL_START_3(addo) { COMPARE(v2, ~v3+1); v1 = v2 + v3; INTO(); } IMPL_OUT; +IMPL_START_3(addf) { COMPARE_ADD(v2, v3); v1 = v2 + v3; } 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(subf){ COMPARE(v2, v3); v1 = v2 - v3; } IMPL_OUT; -IMPL_START_3(subo){ COMPARE(v2, v3); v1 = v2 - v3; INTO(); } IMPL_OUT; +IMPL_START_3(subf){ COMPARE_SUB(v2, v3); v1 = v2 - v3; } IMPL_OUT; //----------------------------------------------------------------------------// -IMPL_START_3(adcx) { v1 = v2 + v3 + !!(R(RFX)&CF); } IMPL_OUT; -IMPL_START_3(adox) { v1 = v2 + v3 + !!(R(RFX)&OF); } 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(adcx) { v3 += !!(R(RFX)&CF); COMPARE_ADD(v2, v3); v1 = v2 + v3; } IMPL_OUT; +IMPL_START_3(sbbx) { v3 += !!(R(RFX)&CF); COMPARE_SUB(v2, v3); v1 = v2 - v3; } IMPL_OUT; //----------------------------------------------------------------------------// +IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT; IMPL_START_3(rem) { v1 = v2 % v3; } IMPL_OUT; IMPL_START_3(div) { if (!v3) _except(ctx, E_DIV, "DIV by 0"); v1 = v2 / v3; } IMPL_OUT; +IMPL_START_3(idiv) { + if (!v3) + _except(ctx, E_DIV, "IDIV by 0"); + v1 = (ulong)((long)v2/(long)v3); +} IMPL_OUT; //----------------------------------------------------------------------------// -// -// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring -// -static void multiply(ulong u, ulong v, ulong *hi, ulong *lo) +static void __unsigned_multiply128(ulong u, ulong v, ulong *hi, ulong *lo) { - ulong u1 = (u & 0xffffffff); - ulong v1 = (v & 0xffffffff); - ulong t = (u1 * v1); - ulong w3 = (t & 0xffffffff); - 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; + __uint128_t r = (__uint128_t)u * (__uint128_t)v; + + *hi = r >> 64; + *lo = r; } -IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT; -IMPL_START_3(mulhi) { multiply(v2, v3, &v1, &v2); } IMPL_OUT_2; +IMPL_START_3(mulhi) { __unsigned_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2; IMPL_START_3(mulf) { ulong tmp; - multiply(v2, v3, &tmp, &v1); + __unsigned_multiply128(v2, v3, &tmp, &v1); R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF); } IMPL_OUT; -IMPL_START_3(mulo) { - ulong tmp; - multiply(v2, v3, &tmp, &v1); - R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF); - INTO(); -} IMPL_OUT; - +//----------------------------------------------------------------------------// + +static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo) +{ + __int128_t r = (__int128_t)(long)u * (__int128_t)(long)v; + + *hi = r >> 64; + *lo = r; +} + +IMPL_START_3(imulhi) { __signed_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2; + //----------------------------------------------------------------------------// diff --git a/vm/in/arch_i.py b/vm/in/arch_i.py index 5888a4d..15f6126 100644 --- a/vm/in/arch_i.py +++ b/vm/in/arch_i.py @@ -131,8 +131,8 @@ def parse_2(fp): count = count + 1 fi = open("INSTRS") -hd = open("arch_i.h", "w") -ls = open("instrs.lst", "w") +hd = open("../ob/arch_i.h", "w") +ls = open("../ob/instrs.lst", "w") count = 0 diff --git a/vm/in/instrs.h b/vm/in/instrs.h index 3fff8d2..c52e564 100644 --- a/vm/in/instrs.h +++ b/vm/in/instrs.h @@ -2,7 +2,6 @@ // See the LICENSE file in the project root for more information. #include -#include //----------------------------------------------------------------------------// @@ -108,18 +107,29 @@ IMPL_START_2(name) \ //----------------------------------------------------------------------------// -#define COMPARE(v1, v2) \ - ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \ - long _s1 = (long)v1, _s2 = (long)v2; \ +#define COMPARE_ADD(v1, v2) \ + ulong _u1 = (ulong)v1, _u2 = (ulong)v2, _u3 = (_u1 + _u2); \ + \ + 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; \ else R(RFX) &= ~CF; \ \ - if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \ - || ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \ + if (((_u1 ^ _u3) & (_u1 ^ _u2)) >> 63) \ R(RFX) |= OF; \ else R(RFX) &= ~OF; \ - SET_ZSF(_u1 - _u2); + \ + SET_ZSF(_u3); //----------------------------------------------------------------------------// diff --git a/vm/in/misc.c b/vm/in/misc.c index 905fd6c..62dc4ba 100644 --- a/vm/in/misc.c +++ b/vm/in/misc.c @@ -9,11 +9,8 @@ //----------------------------------------------------------------------------// -IMPL_START_0(nop) {} IMPL_END; -IMPL_START_0(cpuid) { rax = rdx = 0; } IMPL_END; - +IMPL_START_0(into) { INTO(); } 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) { time_t t = time(NULL); @@ -77,24 +72,6 @@ IMPL_START_0(cls) { for (int i = R10; i <= NX7; i++) R(i) = 0; } 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) @@ -151,7 +128,7 @@ IMPL_START_0(prns) { uchar ch = readmemzx(ctx, R(p1->reg), 1); - COMPARE(ch, 0); + COMPARE_SUB(ch, 0); if ((R(RFX) & ZF) == 0) { diff --git a/vm/in/mov.c b/vm/in/mov.c index cec4ee4..10b524b 100644 --- a/vm/in/mov.c +++ b/vm/in/mov.c @@ -15,7 +15,7 @@ IMPL_START_1(loop) { IMPL_END; IMPL_START_3(b) { - COMPARE(v1, v2); + COMPARE_SUB(v1, v2); if (eval_cond(ctx, ctx->cond)) R(RIP) = v3; @@ -51,11 +51,32 @@ IMPL_START_1(pop) { R(RSP) += 8; } IMPL_OUT; +/* IMPL_START_1(call) { R(RSP) -= 8; writemem(ctx, R(RIP), R(RSP), 8); R(RIP) = v1; } 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) { R(RIP) = readmem(ctx, R(RSP), 8); R(RSP) += 8; diff --git a/vm/in/string.c b/vm/in/string.c index 8bfe35a..edc850d 100644 --- a/vm/in/string.c +++ b/vm/in/string.c @@ -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) { DECV(v2, p2); ulong x = readmem(ctx, R(p1->reg), len); - COMPARE(x, v2); + COMPARE_SUB(x, v2); if (x == 0) { 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) { ulong x = readmem(ctx, R(p2->reg), len); diff --git a/vm/in/super.c b/vm/in/super.c index cb362d4..9ccfa34 100644 --- a/vm/in/super.c +++ b/vm/in/super.c @@ -42,7 +42,6 @@ IMPL_START_1(trap) { _except(ctx, v1 + 256, "TRAP instruction"); } IMPL_END; -IMPL_START_0(into) { INTO(); } IMPL_END; IMPL_START_0(iret) { if (ctx->dumpsw) @@ -55,6 +54,9 @@ IMPL_START_0(iret) { } IMPL_END; +IMPL_START_0(cli) { CHK_SUPERV(); R(CR0) &= ~IF; } IMPL_END; +IMPL_START_0(sti) { CHK_SUPERV(); R(CR0) |= IF; } IMPL_END; + //----------------------------------------------------------------------------// // diff --git a/vm/pc/arch.h b/vm/pc/arch.h index 87fd207..6ab9981 100644 --- a/vm/pc/arch.h +++ b/vm/pc/arch.h @@ -102,7 +102,7 @@ extern void do_hlt(ctx_t *ctx); #include #include #include -#include +#include extern ctx_t main_ctx; extern reg_t arch_r[NREGS]; diff --git a/vm/pc/exec.c b/vm/pc/exec.c index 093f079..01412f9 100644 --- a/vm/pc/exec.c +++ b/vm/pc/exec.c @@ -2,7 +2,6 @@ // See the LICENSE file in the project root for more information. #include -#include #define rfx R(RFX)