From 9eee4817cd1649f088c707cd342efcfbd7c80dc0 Mon Sep 17 00:00:00 2001 From: julianb0 Date: Mon, 22 Jul 2019 14:41:50 +0200 Subject: [PATCH] vm --- as/k-as.py | 34 ++++++++++++++++++--------- ka/crt/crt.k | 4 ++++ ka/crt/fmt/doprnt.k | 3 +-- ka/crt/fmt/ltostr.k | 9 +++----- ka/crt/fmt/strtol.k | 2 +- ka/crt/lib/arith128.k | 4 ++-- ka/crt/lib/time.k | 6 ++--- ka/crt/mem/memcpy.k | 20 ++++++++++++++++ ka/crt/mem/memory.k | 5 ++++ ka/crt/str/strcmp.k | 27 ++++++++-------------- ka/crt/str/strcpy.k | 33 ++++++++++++--------------- ka/doskrnl.k | 4 ++++ ka/usr/cmd/dir.k | 3 +-- ka/usr/cmd/main.k | 53 +++++++++++++++++++++---------------------- vm/pc/DECD | 19 +++++++--------- vm/pc/decode.h | 17 ++++++++++---- vm/pc/dump.c | 5 ++-- vm/pc/exec.c | 13 ++++------- 18 files changed, 143 insertions(+), 118 deletions(-) create mode 100644 ka/crt/mem/memcpy.k create mode 100644 ka/crt/mem/memory.k diff --git a/as/k-as.py b/as/k-as.py index 4ced98b..9fe2449 100755 --- a/as/k-as.py +++ b/as/k-as.py @@ -374,17 +374,29 @@ pconds = { 'z': 0b00011, 'e': 0b00011, 's': 0b00100, - 'p': 0b00101, - 'a': 0b00110, - 'ae': 0b00111, - 'b': 0b01000, - 'be': 0b01001, - 'g': 0b01010, - 'ge': 0b01011, - 'l': 0b01100, - 'le': 0b01101, - 'cxz': 0b01110, - 'cxnz': 0b11110, + + 'pe': 0b00101, + 'po': 0b10101, + + 'b': 0b00001, + 'be': 0b00110, + 'l': 0b00111, + 'le': 0b01000, + + 'a': 0b10110, # nbe + 'ae': 0b10001, # nb + 'g': 0b11000, # nle + 'ge': 0b10111, # nl + + 'axz': 0b01001, + 'bxz': 0b01010, + 'cxz': 0b01011, + 'dxz': 0b01100, + + 'axnz': 0b11001, + 'bxnz': 0b11010, + 'cxnz': 0b11011, + 'dxnz': 0b11100, } def get_cond_mask(cond, line): diff --git a/ka/crt/crt.k b/ka/crt/crt.k index 81a369a..bd91421 100644 --- a/ka/crt/crt.k +++ b/ka/crt/crt.k @@ -9,6 +9,10 @@ include "crt/limits.k" include "crt/err/errno.k" include "crt/fmt/format.k" include "crt/str/string.k" +include "crt/mem/memory.k" include "crt/lib/time.k" include "crt/lib/arith128.k" +abort: + crash + diff --git a/ka/crt/fmt/doprnt.k b/ka/crt/fmt/doprnt.k index 444531e..b67a4f3 100644 --- a/ka/crt/fmt/doprnt.k +++ b/ka/crt/fmt/doprnt.k @@ -178,8 +178,7 @@ doprnt: call r17 ; did putc fail? - cmp rax, zero - mov.nz r15, zero ; yes, so artificially set n=0 + mov.axnz r15, zero ; yes, so artificially set n=0 ret diff --git a/ka/crt/fmt/ltostr.k b/ka/crt/fmt/ltostr.k index 5ae23d9..dff2785 100644 --- a/ka/crt/fmt/ltostr.k +++ b/ka/crt/fmt/ltostr.k @@ -20,7 +20,6 @@ utoa: ; ltostr: mov rax, ax0 - mov rcx, zero ; make sure base is in [2, 32] b.b ax2, 2, .bad @@ -35,8 +34,7 @@ ltostr: b.nz ax2, 10, .conv ; base 10 shr rcx, ax1, 63 ; extract ax1 sign - cmp rcx, zero ; negative? - sub.nz ax1, zero, ax1 ; yes + sub.cxnz ax1, zero, ax1 ; NEG if negative ; main loop .conv: @@ -61,9 +59,8 @@ ltostr: ; add minus flag, null-terminate and reverse .fini: - cmp rcx, -1 - mov.z b[ax0], '-' - add.z ax0, ax0, 1 + mov.cxnz b[ax0], '-' + add.cxnz ax0, ax0, 1 mov b[ax0], zero diff --git a/ka/crt/fmt/strtol.k b/ka/crt/fmt/strtol.k index 9b7d82d..508502e 100644 --- a/ka/crt/fmt/strtol.k +++ b/ka/crt/fmt/strtol.k @@ -68,7 +68,7 @@ strtoq: movzx rcx, b[rdx] ; "0x"/"0b" prefix - b.z rcx, zero, .done ; "0" + jmp.cxz .done ; "0" b.z rcx, 'x', .parsed_0x b.z rcx, 'b', .parsed_0b diff --git a/ka/crt/lib/arith128.k b/ka/crt/lib/arith128.k index 6023875..4b0ca66 100644 --- a/ka/crt/lib/arith128.k +++ b/ka/crt/lib/arith128.k @@ -42,7 +42,7 @@ sub_lq_lq: ret ; -; int:int mul_lq_q(int x, int y) +; int:int mul_q_q(int x, int y) ; mul_q_q: mov rax, ax0 @@ -50,7 +50,7 @@ mul_q_q: ret ; -; int:int imul_lq_q(int x, int y) +; int:int imul_q_q(int x, int y) ; imul_q_q: mov rax, ax0 diff --git a/ka/crt/lib/time.k b/ka/crt/lib/time.k index 0916481..bed77ef 100644 --- a/ka/crt/lib/time.k +++ b/ka/crt/lib/time.k @@ -25,15 +25,15 @@ DaysInYear: ; divisible by 4? rem rcx, ax0, 4 - b.nz rcx, zero, .end + jmp.cxnz .end ; divisible by 100? rem rcx, ax0, 100 - b.nz rcx, zero, .leap + jmp.cxnz .leap ; divisible by 400? rem rcx, ax0, 400 - b.nz rcx, zero, .end + jmp.cxnz .end .leap: add rax, rax, 1 diff --git a/ka/crt/mem/memcpy.k b/ka/crt/mem/memcpy.k new file mode 100644 index 0000000..f5e30e1 --- /dev/null +++ b/ka/crt/mem/memcpy.k @@ -0,0 +1,20 @@ +; The OS/K Team licenses this file to you under the MIT license. +; See the LICENSE file in the project root for more information. + +; +; void memcpy(void *, const void *, int) +; +memcpy: + mov rcx, ax2 + ret.cxz + +.l: + sub rdx, ax2, rcx + + mov rax, b[ax1+rdx] + mov b[ax0+rdx], rax + + loop .l + + ret + diff --git a/ka/crt/mem/memory.k b/ka/crt/mem/memory.k new file mode 100644 index 0000000..c6034d5 --- /dev/null +++ b/ka/crt/mem/memory.k @@ -0,0 +1,5 @@ +; The OS/K Team licenses this file to you under the MIT license. +; See the LICENSE file in the project root for more information. + +include "crt/mem/memcpy.k" + diff --git a/ka/crt/str/strcmp.k b/ka/crt/str/strcmp.k index c7566c3..c979238 100644 --- a/ka/crt/str/strcmp.k +++ b/ka/crt/str/strcmp.k @@ -10,27 +10,22 @@ ; <0 if the first character that does not match has a lower value in str1 than in str2 ; strcmp: - mov rcx, STRLEN_MAX - -.1: - jmp.cxz .2 - +.l: movzx rax, b[ax0] movzx rdx, b[ax1] cmp rax, rdx - jmp.nz .2 + jmp.nz .r ; both zero? add rbx, rax, rdx - b.z rbx, zero, .2 + jmp.bxz .r add ax0, ax0, 1 add ax1, ax1, 1 - sub rcx, rcx, 1 - jmp .1 + jmp .l -.2: +.r: sub rax, rax, rdx ret @@ -39,22 +34,20 @@ strcmp: ; strncmp: mov rcx, ax2 + jmp.cxz .r -.1: - jmp.cxz .2 - +.l: mov rax, b[ax0] mov rdx, b[ax1] cmp rax, rdx - jmp.nz .2 + jmp.nz .r add ax0, ax0, 1 add ax1, ax1, 1 - sub rcx, rcx, 1 - jmp .1 + loop .l -.2: +.r: sub rax, rax, rdx ret diff --git a/ka/crt/str/strcpy.k b/ka/crt/str/strcpy.k index 52093c9..67ebcc2 100644 --- a/ka/crt/str/strcpy.k +++ b/ka/crt/str/strcpy.k @@ -5,60 +5,55 @@ ; void strcpy(char *, const char *) ; strcpy: - mov rax, b[ax1] - mov b[ax0], rax +.l: + mov rcx, b[ax1] + mov b[ax0], rcx - b.z rax, zero, .1 + ret.cxz add ax0, ax0, 1 add ax1, ax1, 1 - jmp strcpy - -.1: - ret + jmp .l ; ; void strncpy(char *, const char *, int) ; strncpy: mov rcx, ax2 - -.1: ret.cxz +.l: mov rax, b[ax1] mov b[ax0], rax add ax0, ax0, 1 add ax1, ax1, 1 - sub rcx, rcx, 1 - jmp .1 + loop .l + ret ; ; void strnzcpy(char *, const char *, int) ; strnzcpy: mov rcx, ax2 + ret.cxz -.1: - jmp.cxz .2 - +.l: mov rax, b[ax1] mov b[ax0], rax - b.z rax, zero, .3 + jmp.axz .r add ax0, ax0, 1 add ax1, ax1, 1 - sub rcx, rcx, 1 - jmp .1 + loop .l -.2: +.z: mov b[ax0], zero -.3: +.r: ret diff --git a/ka/doskrnl.k b/ka/doskrnl.k index cf6b4e3..dad77e9 100644 --- a/ka/doskrnl.k +++ b/ka/doskrnl.k @@ -26,6 +26,10 @@ start: mov rsp, DOSKRNL_STACK mov rbp, zero + dump + mov rcx, 44 + crash.cxz + call main crash diff --git a/ka/usr/cmd/dir.k b/ka/usr/cmd/dir.k index 63a7507..854a6cb 100644 --- a/ka/usr/cmd/dir.k +++ b/ka/usr/cmd/dir.k @@ -8,7 +8,6 @@ builtins.dir: mov rbp, rsp push r12 - mov r12, zero # no. of files found mov rcx, STRLEN_MAX @@ -32,7 +31,7 @@ builtins.dir: trap 0 .list: - b.z rax, 0, .end + jmp.axz .end ; found something add r12, r12, 1 diff --git a/ka/usr/cmd/main.k b/ka/usr/cmd/main.k index f629a41..e7672c9 100644 --- a/ka/usr/cmd/main.k +++ b/ka/usr/cmd/main.k @@ -18,7 +18,7 @@ main: ; empty argbuf mov rcx, argbuf.size mov rdx, argbuf - stosb.rep rdx, 0 + stosb.rep rdx, zero ; iterator through argbuf mov rcx, zero @@ -32,15 +32,15 @@ main: ; Fill .buf with user input scan rax - b.z rax, zero, .input_loop + jmp.axz .input_loop ; backspace character? b.nz rax, 8, .handle_input ; anything to delete? - b.z rcx, zero, .input_loop + jmp.cxz .input_loop ; no - ; delete it + ; yes, delete it sub rcx, rcx, 1 add rdx, rcx, argbuf mov b[rdx], zero @@ -71,7 +71,7 @@ main: .extract_argv0: ; did we read anything at all? ; if not, just go back to waiting input - b.z rcx, zero, .print_prompt + jmp.cxz .print_prompt ; find first whitespace or null-terminator mov rcx, argbuf.size @@ -80,44 +80,44 @@ main: ; argv1 exists? if so, save its position mov rsi, rdx - b.z b[rsi], zero, .no_argv1 - add rsi, rsi, 1 .next_space: mov rcx, b[rsi] - b.z rdx, zero, .no_argv1 + jmp.cxz .do_extract ; skip spaces - cmp rdx, ' ' + cmp rcx, ' ' add.z rsi, rsi, 1 jmp.z .next_space + ; if we're here, we found a + ; non-zero non-space character mov q[argv1pos], rsi ; fallthrough -.no_argv1: +.do_extract: ; empty argv0 mov rcx, argbuf.size mov rax, argv0 - stosb.rep rax, 0 + stosb.rep rax, zero - ; extract argv0 + ; how much do we copy? sub rcx, rdx, argbuf - mov rdx, argbuf - mov rax, argv0 - -.mmove: jmp.cxz .detect_builtin - - mov rsi, b[rdx] - mov b[rax], rsi - - add rdx, rdx, 1 - add rax, rax, 1 sub rcx, rcx, 1 - jmp .mmove + mov rdi, argbuf + mov rsi, argv0 + +.copy_loop: + mov rax, b[rdi] + mov b[rsi], rax + + add rdi, rdi, 1 + add rsi, rsi, 1 + + loop .copy_loop .detect_builtin: @@ -230,8 +230,8 @@ main: mov rax, Sys.CloseFile trap 0 - b.l rax, zero, .couldnt_read - b.z rax, zero, .empty_file + b.l rcx, zero, .couldnt_read + jmp.cxz .empty_file mov rdx, FILE_LOADP prns.rep rdx @@ -287,7 +287,6 @@ main: .command_not_found: call print, argv0 call print, .cnf_errmsg - jmp .print_prompt .cnf_errmsg = ": command not found\n" @@ -310,7 +309,7 @@ main: jmp .print_prompt -.ef_errmsg = "%s: %s: file is empty\n" +.ef_errmsg = "%s: %s: file was empty\n" .couldnt_read: push q[argv1pos] diff --git a/vm/pc/DECD b/vm/pc/DECD index b91b175..8080f41 100644 --- a/vm/pc/DECD +++ b/vm/pc/DECD @@ -19,21 +19,18 @@ FT2 Second operand format Values for COND: 00000 (none) -00001 .C +00001 .C .B 00010 .O 00011 .Z .E 00100 .S 00101 .P -00110 .A -00111 .AE -01000 .B -01001 .BE -01010 .G -01011 .GE -01100 .L -01101 .LE -01110 .CXZ -01111 (reserved) +00110 .BE +00111 .L +01000 .LE +01001 .AXZ +01010 .BXZ +01011 .CXZ +01100 .DXZ Highest (6th) bit of COND indicates negation Fx values: diff --git a/vm/pc/decode.h b/vm/pc/decode.h index 313ccd0..7c35247 100644 --- a/vm/pc/decode.h +++ b/vm/pc/decode.h @@ -4,11 +4,18 @@ enum { CD_NONE, - - CD_C, CD_O, CD_Z, CD_S, CD_P, - CD_A, CD_AE, CD_B, CD_BE, - CD_G, CD_GE, CD_L, CD_LE, - CD_CXZ, COND_RES, + CD_C, + CD_O, + CD_Z, + CD_S, + CD_P, + CD_BE, + CD_L, + CD_LE, + CD_AXZ, + CD_BXZ, + CD_CXZ, + CD_DXZ, }; enum diff --git a/vm/pc/dump.c b/vm/pc/dump.c index ec811b6..19700f8 100644 --- a/vm/pc/dump.c +++ b/vm/pc/dump.c @@ -9,9 +9,8 @@ char *cond_suffixes[] = { "-", "c", "o", "z", "s", "p", - "a", "ae", "b", "be", - "g", "ge", "l", "le", - "cxz", + "be", "l", "le", "axz", + "bxz", "cxz", "?" }; diff --git a/vm/pc/exec.c b/vm/pc/exec.c index bd8bd5e..2ee9a26 100644 --- a/vm/pc/exec.c +++ b/vm/pc/exec.c @@ -21,20 +21,15 @@ bool eval_cond(ctx_t *ctx, uint cond) case CD_Z: ok = rfx&ZF; break; case CD_S: ok = rfx&SF; break; case CD_P: ok = rfx&PF; break; - - case CD_A: ok = !(rfx&CF || rfx&ZF); break; - case CD_AE: ok = !(rfx&CF); break; - case CD_B: ok = rfx&CF; break; - case CD_BE: ok = rfx&CF || rfx&ZF; break; - - case CD_G: ok = !(rfx&ZF) && (!(rfx&SF) == !(rfx&OF)); break; - case CD_GE: ok = !(rfx&SF) == !(rfx&OF); break; - + case CD_BE: ok = rfx&CF || rfx&ZF; break; case CD_L: ok = !(rfx&SF) != !(rfx&OF); break; case CD_LE: ok = rfx&ZF || (!(rfx&SF) != !(rfx&OF)); break; + case CD_AXZ: ok = !R(RAX); break; + case CD_BXZ: ok = !R(RBX); break; case CD_CXZ: ok = !R(RCX); break; + case CD_DXZ: ok = !R(RDX); break; default: _except(ctx, E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond));