From b8d29210fb9c0aebaad114530c4ec761ca9fd1c5 Mon Sep 17 00:00:00 2001 From: julianb0 Date: Tue, 2 Jul 2019 20:13:05 +0200 Subject: [PATCH] stuff --- ka/crt/fmt/doprnt.k | 32 ++++++++++--------------- ka/crt/fmt/ltostr.k | 15 ++++-------- ka/crt/fmt/printf.k | 17 ++++--------- ka/crt/fmt/strtol.k | 44 ++++++++++++---------------------- ka/crt/str/strrev.k | 3 +-- ka/doskrnl.k | 4 +--- ka/sys/main.k | 5 ++-- ka/usr/cmd/dir.k | 34 +++++++++++--------------- vm/in/INOUT | 17 +++++++++++++ vm/in/INSTRS | 2 +- vm/in/JUMPS | 28 +++++++++++----------- vm/in/{KINSTRS => TERNARY} | 0 vm/in/inout.c | 18 ++++++++++++++ vm/in/jumps.c | 28 +++++++--------------- vm/in/{kinstrs.c => ternary.c} | 2 +- vm/pc/arch.h | 3 +++ vm/pc/decode.c | 18 +++++++------- vm/pc/decode.h | 8 +++---- vm/pc/dump.c | 11 ++------- vm/pc/exec.c | 21 +++++++--------- 20 files changed, 141 insertions(+), 169 deletions(-) rename vm/in/{KINSTRS => TERNARY} (100%) rename vm/in/{kinstrs.c => ternary.c} (95%) diff --git a/ka/crt/fmt/doprnt.k b/ka/crt/fmt/doprnt.k index 9a15d2c..aefe7f4 100644 --- a/ka/crt/fmt/doprnt.k +++ b/ka/crt/fmt/doprnt.k @@ -30,8 +30,7 @@ doprnt: .print_regular: ; everything below rdi is a regular character; print it - cmp rbx, rdi - j.z .check_modf + b.e rbx, rdi, .check_modf mov ax0, b[rbx] call .doput @@ -41,29 +40,22 @@ doprnt: .check_modf: ; did we find a '%' ? - cmp b[rbx], '%' - j.nz .epilogue ; no, we found fmt's null-terminator; we're done + ; if not, then we found fmt's null-terminator; we're done + b.nz b[rbx], '%', .epilogue ; we did find a modifier / '%' mov rax, b[rbx+1] add rbx, 2 - cmp rax, 's' - j.z .modf_s - cmp rax, 'c' - j.z .modf_c - cmp rax, 'p' - j.z .modf_p - cmp rax, 'x' - j.z .modf_x - cmp rax, 'd' - j.z .modf_d - cmp rax, 'o' - j.z .modf_o - cmp rax, 'b' - j.z .modf_b - cmp rax, '%' - j.z .modf_percent + b.e rax, 's', .modf_s + b.e rax, 'c', .modf_c + b.e rax, 'p', .modf_p + b.e rax, 'x', .modf_x + b.e rax, 'd', .modf_d + b.e rax, 'o', .modf_o + b.e rax, 'b', .modf_b + b.e rax, '%', .modf_percent + ; unrecognized jmp .bad_modifier diff --git a/ka/crt/fmt/ltostr.k b/ka/crt/fmt/ltostr.k index d8fbdee..e2b1bd6 100644 --- a/ka/crt/fmt/ltostr.k +++ b/ka/crt/fmt/ltostr.k @@ -23,14 +23,11 @@ ltostr: xor rx8, rx8 ; make sure base is in [2, 32] - cmp ax2, 2 - j.b .bad - cmp ax2, 36 - j.a .bad + b.b ax2, 2, .bad + b.a ax2, 36, .bad ; deal with zero - test ax1, ax1 - j.z .zero + b.e ax1, 0, .zero ; deal with base 10 signedness @@ -45,14 +42,12 @@ ltostr: ; main loop .conv: - test ax1, ax1 - j.z .fini + b.e ax1, 0, .fini mov r10, ax1 rem r10, ax2 ; ax1 % base - cmp r10, 9 ; r10 > 9 ? - j.a .nondec + b.a r10, 9, .nondec ; r10 > 9 ? add r10, '0' jmp .next diff --git a/ka/crt/fmt/printf.k b/ka/crt/fmt/printf.k index 7465da8..6279299 100644 --- a/ka/crt/fmt/printf.k +++ b/ka/crt/fmt/printf.k @@ -33,15 +33,9 @@ nprintf: ; print: mov rcx, STRLEN_MAX - + b.z b[ax0], 0, .1 + prns.rep.nz ax0 .1: - cmp b[ax0], 0 - ret.z - - prn b[ax0] - inc ax0 - loop .1 - ret ; @@ -49,11 +43,8 @@ print: ; print_n: mov rcx, ax1 - + b.z b[ax0], 0, .1 + prns.rep.nz ax0 .1: - prn b[ax0] - inc ax0 - loop .1 - ret diff --git a/ka/crt/fmt/strtol.k b/ka/crt/fmt/strtol.k index bbd4eef..85fa9c5 100644 --- a/ka/crt/fmt/strtol.k +++ b/ka/crt/fmt/strtol.k @@ -31,14 +31,11 @@ strtoq: mov rdx, ax0 ; make sure base is in [2, 32] - cmp ax1, 1 - j.z .bad - cmp ax1, 36 - j.a .bad + b.z ax1, 1, .bad + b.a ax1, 36, .bad ; empty string? - cmp b[rdx], 0 - jmp.z .done + b.z b[rdx], 0, .done .skip_spc: cmp b[rdx], ' ' @@ -62,36 +59,27 @@ strtoq: .unsigned: ; base 0 - test ax1, ax1 - jmp.z .base_0 + b.z ax1, 0, .base_0 ; base prefix? - cmp b[rdx], '0' - jmp.nz .main_loop + b.nz b[rdx], '0', .main_loop inc rdx + movzx rcx, b[rdx] - ; string is "0" - cmp b[rdx], 0 - jmp.z .done - - ; "0x" prefix - cmp b[rdx], 'x' - jmp.z .parsed_0x - - ; "0b" prefix - cmp b[rdx], 'b' - jmp.z .parsed_0b + ; "0x"/"0b" prefix + b.z rcx, 0, .done ; "0" + b.z rcx, 'x', .parsed_0x + b.z rcx, 'b', .parsed_0b ; may be octal, but we don't care - ; we accept "0110101010" (binary) for instance + ; we accept "0110101010" (despite base=2) for instance jmp .main_loop .parsed_0x: ; are we in base 16? ; if not, leave rax = 0 and *rdx = 'x' - cmp ax1, 16 - jmp.nz .done + b.nz ax1, 16, .done ; else inc rdx jmp .main_loop @@ -99,8 +87,7 @@ strtoq: .parsed_0b: ; are we in base 2? ; if not, leave rax = 0 and *rdx = 'b' - cmp ax1, 2 - jmp.nz .done + b.nz ax1, 2, .done ; else inc rdx jmp .main_loop @@ -126,7 +113,7 @@ strtoq: mov ax1, 8 .main_loop: - mov rx8, b[rdx] + movzx rx8, b[rdx] inc rdx cmp rx8, '0' @@ -148,8 +135,7 @@ strtoq: .next: ; too large for base? - cmp rx8, ax1 - jmp.ae .done + b.ae rx8, ax1, .done mul rax, ax1 add rax, rx8 diff --git a/ka/crt/str/strrev.k b/ka/crt/str/strrev.k index 8479f78..fd33fb2 100644 --- a/ka/crt/str/strrev.k +++ b/ka/crt/str/strrev.k @@ -53,8 +53,7 @@ strrev2: ; increase ax0 while decreasing ax1, performing exchanges .2: - cmp ax0, ax1 - j.ae .3 + b.ae ax0, ax1, .3 xchg b[ax0], b[ax1] diff --git a/ka/doskrnl.k b/ka/doskrnl.k index 8dacbec..0b4bb30 100644 --- a/ka/doskrnl.k +++ b/ka/doskrnl.k @@ -9,7 +9,6 @@ start: xor rbp, rbp call main - call CMD.builtins.dir hlt @@ -19,8 +18,7 @@ start: scan rax xpause - test rax, rax - j.z .1 + b.z rax, 0, .1 prn rax jmp .1 diff --git a/ka/sys/main.k b/ka/sys/main.k index 5d3cfe8..d0fec24 100644 --- a/ka/sys/main.k +++ b/ka/sys/main.k @@ -2,8 +2,9 @@ ; See the LICENSE file in the project root for more information. PrintBootMsg: - mov ax0, .bootmsg - call print + mov rcx, STRLEN_MAX + mov rdx, .bootmsg + prns.rep.nz rdx ret .bootmsg = "Starting DOS...\n\n" diff --git a/ka/usr/cmd/dir.k b/ka/usr/cmd/dir.k index 05e5ad7..6402ba6 100644 --- a/ka/usr/cmd/dir.k +++ b/ka/usr/cmd/dir.k @@ -5,8 +5,9 @@ CMD.builtins.dir: sub nx0, nx0 # no. of files found - mov ax0, .dirmsg - call print + mov rcx, STRLEN_MAX + mov rdx, .dirmsg + prns.rep.nz rdx .dirmsg = "Directory of C:\\\n\n" @@ -22,8 +23,7 @@ CMD.builtins.dir: call DISK.FindNext .list: - test rax, rax - j.z .end + b.z rax, 0, .end ; found something inc nx0 @@ -34,12 +34,9 @@ CMD.builtins.dir: mov r11, r10 scasb.rep.nz r10, '.' -.print_file_name: - prn b[r11] - inc r11 - - cmp r11, r10 - j.b .print_file_name + ; print file name + ksub rcx, r10, r11 + prns.rep r11 ; calculate where to put extension ksub r11, r10, .buf @@ -47,8 +44,7 @@ CMD.builtins.dir: .ext_pad: ; print at least 11 non-space characters before extension - cmp r11, 11 - j.ae .print_ext + b.ae r11, 11, .print_ext prn ' ' inc r11 jmp .ext_pad @@ -62,21 +58,18 @@ CMD.builtins.dir: inc.z r10 .print_ext.1: - cmp b[r10], 0 - j.z .print_ext.2 + b.z b[r10], 0, .print_ext.2 ; print and decrease rcx, unless it's already 0 prn b[r10] inc r10 - test rcx, rcx - dec.nz rcx + dec.cxnz rcx jmp .print_ext.1 .print_ext.2: ; did we print at least 4 bytes? - test rcx, rcx - j.z .print_bytes ; yes, carry on + j.cxz .print_bytes ; yes, carry on prn.rep ' ' @@ -109,8 +102,9 @@ CMD.builtins.dir: call printf add rsp, 8 - mov ax0, .endstr2 - call print + mov rcx, STRLEN_MAX + mov rdx, .endstr2 + prns.rep.nz rdx pop nx0 ret diff --git a/vm/in/INOUT b/vm/in/INOUT index 97c67fd..2bc0007 100644 --- a/vm/in/INOUT +++ b/vm/in/INOUT @@ -10,6 +10,23 @@ # prn rim +# +# Print a string to standard output (PRN) +# +# COMPARE([%1], 0) +# +# IF (ZF == 0) THEN +# PRN([%1]) +# IF (DF == 0) THEN +# %1 = %1 + 1 +# ELSE +# %1 = %1 - 1 +# FI +# FI +# +# +prns r + # # Scan a character from standard input (SCAN) # diff --git a/vm/in/INSTRS b/vm/in/INSTRS index 4cd75ca..584b155 100644 --- a/vm/in/INSTRS +++ b/vm/in/INSTRS @@ -13,5 +13,5 @@ include "FLAGS" include "INOUT" include "DEBUG" include "STRING" -include "KINSTRS" +include "TERNARY" diff --git a/vm/in/JUMPS b/vm/in/JUMPS index 8d0711a..00750ba 100644 --- a/vm/in/JUMPS +++ b/vm/in/JUMPS @@ -24,20 +24,20 @@ jmp ri loop ri # -# Relative jump (BCH) instruction ("branch") +# Conditional absolute jumps (B) # -# RIP = RIP + $1 +# COMPARE($1, $2) # -b ri -bch ri - -# -# RCX-dependent relative jump (BOOP) instruction -# -# IF (RCX > 0) THEN -# RCX = RCX - 1 -# RIP = RIP + $1 -# FI -# -boop ri +# IF (COND) THEN +# RIP = $3 +# FI +# +# Sets CF, OF, ZF and SF according to the comparison's results +# +# This instruction is special in that the COND field specified is not evaluated +# before the instruction is executed, but after the comparison it effectuates +# +# Suffixing B with the REP suffix results in undefined behavior +# +b rim rim ri diff --git a/vm/in/KINSTRS b/vm/in/TERNARY similarity index 100% rename from vm/in/KINSTRS rename to vm/in/TERNARY diff --git a/vm/in/inout.c b/vm/in/inout.c index 5bde55c..2d891b7 100644 --- a/vm/in/inout.c +++ b/vm/in/inout.c @@ -13,6 +13,24 @@ IMPL_START_1(prn) } IMPL_END +IMPL_START_0(prns) +{ + uchar ch = readmemzx(ctx, R(p1->reg), 1); + + COMPARE(ch, 0); + + if ((flg & ZF) == 0) + { + console_putc(ctx, ch); + + if (flg & DF) + R(p1->reg)--; + else + R(p1->reg)++; + } +} +IMPL_END + IMPL_START_1(scan) { v1 = console_scankeybuf(ctx); diff --git a/vm/in/jumps.c b/vm/in/jumps.c index 7d672a6..c7f7244 100644 --- a/vm/in/jumps.c +++ b/vm/in/jumps.c @@ -3,9 +3,7 @@ #include -// -// Jump instructions -// +//----------------------------------------------------------------------------// IMPL_START_1(j) { @@ -28,24 +26,16 @@ IMPL_START_1(loop) } IMPL_END; -IMPL_START_1(b) +//----------------------------------------------------------------------------// + +IMPL_START_3(b) { - rip += v1; + COMPARE(v1, v2); + + if (eval_cond(ctx, ctx->cond)) + rip = v3; } IMPL_END; -IMPL_START_1(bch) -{ - rip += v1; -} -IMPL_END; - -IMPL_START_1(boop) -{ - if (rcx > 0) { - rcx--; - rip += v1; - } -} -IMPL_END; +//----------------------------------------------------------------------------// diff --git a/vm/in/kinstrs.c b/vm/in/ternary.c similarity index 95% rename from vm/in/kinstrs.c rename to vm/in/ternary.c index 6897ed0..302428c 100644 --- a/vm/in/kinstrs.c +++ b/vm/in/ternary.c @@ -8,7 +8,7 @@ #define K_IMPL_ALU(name, expr) \ IMPL_START_3(k##name) \ { \ - v1 = expr; \ + v1 = (expr); \ } \ IMPL_OUT_ZSF diff --git a/vm/pc/arch.h b/vm/pc/arch.h index e476f93..99b712a 100644 --- a/vm/pc/arch.h +++ b/vm/pc/arch.h @@ -70,6 +70,9 @@ struct ctx_t // Instructions executed so far ulong ninstrs; + + // Last COND field + uint cond; }; #define R(X) ctx->rf[X] diff --git a/vm/pc/decode.c b/vm/pc/decode.c index 89dff9c..03b1961 100644 --- a/vm/pc/decode.c +++ b/vm/pc/decode.c @@ -7,7 +7,8 @@ // Read the "DECD" file before reading this code // -static void check_param_type(ctx_t *ctx, instr_t *in, uint prm, uchar fmt, int which) +static void check_param_type(ctx_t *ctx, instr_t *in, + uint prm, uchar fmt, int which) { bool ok; @@ -153,7 +154,6 @@ void decode(ctx_t *ctx) acc_t p3 = { 0 }; bool rep = 0; - uint cond = 0; bool lock, nomore; ushort w1, w2; @@ -172,9 +172,9 @@ void decode(ctx_t *ctx) nomore = !!(w1 & SUFF_NOMORE); if (w1 & SUFF_COND) - { - cond = ctx->get(ctx); - } + ctx->cond = ctx->get(ctx); + else + ctx->cond = 0; w1 &= ~(SUFF_LOCK|SUFF_NOMORE|SUFF_COND); @@ -217,7 +217,7 @@ void decode(ctx_t *ctx) f1, f2, f3, in->full); } - exec_instr(ctx, in, NULL, NULL, NULL, lock, rep, cond); + exec_instr(ctx, in, NULL, NULL, NULL, lock, rep); return; } @@ -237,7 +237,7 @@ void decode(ctx_t *ctx) f1, f2, f3, in->full); } - exec_instr(ctx, in, &p1, NULL, NULL, lock, rep, cond); + exec_instr(ctx, in, &p1, NULL, NULL, lock, rep); return; } @@ -257,13 +257,13 @@ void decode(ctx_t *ctx) f1, f2, f3, in->full); } - exec_instr(ctx, in, &p1, &p2, NULL, lock, rep, cond); + exec_instr(ctx, in, &p1, &p2, NULL, lock, rep); return; } check_param_type(ctx, in, in->prm3, f3, 3); extract_param(ctx, &p3, f3); - exec_instr(ctx, in, &p1, &p2, &p3, lock, rep, cond); + exec_instr(ctx, in, &p1, &p2, &p3, lock, rep); } diff --git a/vm/pc/decode.h b/vm/pc/decode.h index 217310e..5b42a39 100644 --- a/vm/pc/decode.h +++ b/vm/pc/decode.h @@ -81,14 +81,15 @@ struct instr_t ulong *, ulong *, ulong *); }; +bool eval_cond(ctx_t *ctx, uint cond); + void exec_instr(ctx_t *ctx, instr_t *in, acc_t *p1, acc_t *p2, acc_t *p3, bool lock, - bool rep, - uint cond); + bool rep); void extract_param(ctx_t *ctx, acc_t *p, @@ -100,6 +101,5 @@ void dump_instr(ctx_t *ctx, acc_t *p2, acc_t *p3, bool lock, - bool rep, - uint cond); + bool rep); diff --git a/vm/pc/dump.c b/vm/pc/dump.c index 685ff08..1829c7a 100644 --- a/vm/pc/dump.c +++ b/vm/pc/dump.c @@ -13,10 +13,6 @@ char *cond_suffixes[] = "?" }; -#ifndef _ATT_STYLE -#define _ATT_STYLE 0 -#endif - void dump_acc(ctx_t *ctx, acc_t *p); void dump_instr(ctx_t *ctx, @@ -25,12 +21,9 @@ void dump_instr(ctx_t *ctx, acc_t *p2, acc_t *p3, bool lock, - bool rep, - uint cond) + bool rep) { -/* - trace("%03lu 0x%lX:\t", ctx->ninstrs, pc); -*/ + uint cond = ctx->cond; trace("0x%lX:\t", rpc); diff --git a/vm/pc/exec.c b/vm/pc/exec.c index cbf3f03..563a088 100644 --- a/vm/pc/exec.c +++ b/vm/pc/exec.c @@ -2,6 +2,7 @@ // See the LICENSE file in the project root for more information. #include +#include bool eval_cond(ctx_t *ctx, uint cond) { @@ -50,8 +51,7 @@ void exec_instr(ctx_t *ctx, acc_t *p2, acc_t *p3, bool lock, - bool rep, - uint cond) + bool rep) { bool out; ulong r1 = 0, r2 = 0, r3 = 0; @@ -67,17 +67,12 @@ void exec_instr(ctx_t *ctx, // For REPs we evaluate the condition AFTER running the instruction, // in a do ... while(cond) fashion // - if (!rep && !eval_cond(ctx, cond)) - { -#ifndef NDEBUG - // Say something about ignored instruction? - //trace("0x%lX:\n", rpc); -#endif - return; - } + if (ctx->cond && in->func != i_b) // 'B' instruction is special + if (!rep && !eval_cond(ctx, ctx->cond)) + return; #ifndef NDEBUG - dump_instr(ctx, in, p1, p2, p3, lock, rep, cond); + dump_instr(ctx, in, p1, p2, p3, lock, rep); #endif do_rep: @@ -132,7 +127,7 @@ do_rep: if (rep) { // RCX remains untouched when condition fails - if (!eval_cond(ctx, cond)) + if (!eval_cond(ctx, ctx->cond)) return; if (rcx > 0) @@ -145,7 +140,7 @@ do_rep: #ifndef NDEBUG // Show that we're REP'ing - dump_instr(ctx, in, p1, p2, p3, lock, rep, cond); + dump_instr(ctx, in, p1, p2, p3, lock, rep); #endif goto do_rep;