mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
vm
This commit is contained in:
parent
ce8411be8e
commit
9eee4817cd
34
as/k-as.py
34
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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
20
ka/crt/mem/memcpy.k
Normal file
20
ka/crt/mem/memcpy.k
Normal file
@ -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
|
||||
|
5
ka/crt/mem/memory.k
Normal file
5
ka/crt/mem/memory.k
Normal file
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -26,6 +26,10 @@ start:
|
||||
mov rsp, DOSKRNL_STACK
|
||||
mov rbp, zero
|
||||
|
||||
dump
|
||||
mov rcx, 44
|
||||
crash.cxz
|
||||
|
||||
call main
|
||||
|
||||
crash
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
19
vm/pc/DECD
19
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:
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
"?"
|
||||
};
|
||||
|
||||
|
13
vm/pc/exec.c
13
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));
|
||||
|
Loading…
Reference in New Issue
Block a user