This commit is contained in:
julianb0 2019-08-14 20:23:05 +02:00
parent 3d002108a4
commit cbd079d2a0
No known key found for this signature in database
GPG Key ID: 9C7ACF0C053FB8A1
50 changed files with 535 additions and 921 deletions

View File

@ -369,52 +369,6 @@ def parse_preproc(line):
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
pconds = {
'c': 0b00001,
'o': 0b00010,
'z': 0b00011,
'e': 0b00011,
's': 0b00100,
'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):
mask = 0
if cond[0] == 'n':
cond = cond[1:]
mask = 0b10000
if cond not in pconds:
print("Invalid condition suffix: {}".format(line))
leave(1)
return (mask | pconds[cond])
#-------------------------------------------------------------------------------
fmts = { fmts = {
"r": 0b00000000, "r": 0b00000000,
"m_r": 0b00100000, "m_r": 0b00100000,
@ -456,40 +410,11 @@ def parse_instr(line):
params = None params = None
size = 1 size = 1
# Byte 2 (rep|lock|0|cond)
b2 = 0
if len(instr) > 2 and '.' in instr:
instr, suf = instr.split('.', 1)
if len(instr) == 0:
print("Missing instruction name before suffixes: {}".format(line))
if len(suf) > 2 and suf[:3] == "rep":
if len(suf) > 3:
suf = suf[3:]
if len(suf) > 0 and suf[0] == '.':
suf = suf[1:]
else:
suf = ''
b2 |= 1<<7 # REP
if len(suf) > 0:
b2 |= get_cond_mask(suf, line)
instr_name = instr instr_name = instr
instr_args = '' instr_args = ''
if params == None or len(params) == 0: if params == None or len(params) == 0:
if b2 == 0: instrs.write("{}_0".format(instr_name))
instrs.write("{}_0".format(instr_name))
else:
size += 1
instrs.write("%%suff {}_0 %%imm8 {}".format(instr_name, b2))
return size return size
@ -721,19 +646,13 @@ def parse_instr(line):
instr_args += word instr_args += word
if b2 == 0: instrs.write("{}{}".format(instr_name, instr_args))
instrs.write("{} {}".format(instr_name, instr_args))
else:
size += 1
instrs.write("%%suff {} %%imm8 {} {}".format(instr_name, b2, instr_args))
return size return size
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
special_syms = { special_syms = {
"%%suff",
"%%imm8", "%%imm8",
"%%imm16", "%%imm16",
"%%imm32", "%%imm32",
@ -749,7 +668,6 @@ def gentext():
data_start += (8 - data_start % 8) data_start += (8 - data_start % 8)
instrs.seek(0) instrs.seek(0)
suff_mask = 0
for _, line in enumerate(instrs): for _, line in enumerate(instrs):
tok = line.strip().split() tok = line.strip().split()
@ -769,9 +687,8 @@ def gentext():
continue continue
if word in pinstrs: if word in pinstrs:
idx = pinstrs.index(word) | suff_mask idx = pinstrs.index(word)
b_text.write(idx.to_bytes(1, byteorder='little', signed=False)) b_text.write(idx.to_bytes(1, byteorder='little', signed=False))
suff_mask = 0
continue continue
if word in plabels_text: if word in plabels_text:
@ -785,9 +702,7 @@ def gentext():
continue continue
if word in special_syms: if word in special_syms:
if word == "%%suff": if word == "%%imm8":
suff_mask = 1<<7
elif word == "%%imm8":
lastimm = 1 lastimm = 1
elif word == "%%imm16": elif word == "%%imm16":
lastimm = 2 lastimm = 2

View File

@ -1,18 +1,10 @@
$rzx $zero
$cr0
$cr1
$cr2
$rfx
$rip
$rbp
$rsp
$rax $r0 $rax $r0
$rbx $r1 $rbx $r1
$rcx $r2 $rcx $r2
$rdx $r3 $rdx $r3
$rsi $r4 $rsi $r4
$rdi $r5 $rdi $r5
$ax0 $r6 $ax0 $r6
$ax1 $r7 $ax1 $r7
$ax2 $r8 $ax2 $r8
@ -29,6 +21,19 @@ $nx5 $r17
$nx6 $r18 $nx6 $r18
$nx7 $r19 $nx7 $r19
$nx8 $r20 $nx8 $r20
$grp $r21 $grp $r21
$trp $r22 $trp $r22
$srp $r22 $srp $r23
$tmp $r24
$rad $r25
$cr0 $r26
$cr1 $r27
$rip $r28
$rbp $r29
$rsp $r30
$zero $r31

View File

@ -5,47 +5,49 @@
; Limits ; Limits
; ;
CHAR_MIN := 0x0000000000000080 CHAR_MIN := 0x80
SHRT_MIN := 0x0000000000008000 SHRT_MIN := 0x8000
INT_MIN := 0x0000000080000000 INT_MIN := 0x80000000
LONG_MIN := 0x8000000000000000 LONG_MIN := 0x8000000000000000
XCHAR_MIN := 0xFFFFFFFFFFFFFF80 XCHAR_MIN := 0xFFFFFFFFFFFFFF80
XSHRT_MIN := 0xFFFFFFFFFFFF8000 XSHRT_MIN := 0xFFFFFFFFFFFF8000
XINT_MIN := 0xFFFFFFFF80000000 XINT_MIN := 0xFFFFFFFF80000000
CHAR_MAX := 0x000000000000007F CHAR_MAX := 0x7F
SHRT_MAX := 0x0000000000007FFF SHRT_MAX := 0x7FFF
INT_MAX := 0x000000007FFFFFFF INT_MAX := 0x7FFFFFFF
LONG_MAX := 0x7FFFFFFFFFFFFFFF LONG_MAX := 0x7FFFFFFFFFFFFFFF
BYTE_MAX := 0x00000000000000FF BYTE_MAX := 0xFF
WORD_MAX := 0x000000000000FFFF WORD_MAX := 0xFFFF
LWORD_MAX := 0x00000000FFFFFFFF LWORD_MAX := 0xFFFFFFFF
QWORD_MAX := 0xFFFFFFFFFFFFFFFF QWORD_MAX := 0xFFFFFFFFFFFFFFFF
FILE_MAXSZ := 0x0000000000008000 FNAME_MAX := 0x80
STRLEN_MAX := 0x000000007AFFFFFF FILE_MAXSZ := 0x8000
FNAME_MAX := 0x0000000000000080 STRLEN_MAX := 0x7AFFFFFF
; ;
; Magic numbers ; Magic numbers
; ;
PRN_CLEAR := 0x000000008BF00001 PRN_CLEAR := 0x8BF00001
PRN_FLUSH := 0x000000008BF00002 PRN_FLUSH := 0x8BF00002
; ;
; CRT librairies ; CRT librairies
; ;
include "crt/sys.k" include "crt/sys.k"
include "crt/err/errno.k" include "crt/str.k"
include "crt/fmt/format.k" include "crt/mem.k"
include "crt/str/string.k" include "crt/time.k"
include "crt/mem/memory.k"
include "crt/lib/time.k"
include "crt/fmt/ltostr.k"
include "crt/fmt/strtol.k"
include "crt/fmt/doprnt.k"
include "crt/fmt/printf.k"
abort: abort:
crash crash

View File

@ -1,7 +0,0 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
EINVAL := 1
errno = 0
EOK := 0

View File

@ -15,14 +15,14 @@ doprnt:
mov r12, ax2 ; fmt mov r12, ax2 ; fmt
mov r14, ax3 ; va_list mov r14, ax3 ; va_list
mov r15, ax1 ; n mov r15, ax1 ; n
mov r16, zero ; return value
mov r17, ax0 ; putc mov r17, ax0 ; putc
nul r16 ; return value
.main_loop: .main_loop:
; find '%' or null-terminator ; find '%' or null-terminator
mov rcx, STRLEN_MAX mov rcx, STRLEN_MAX
mov r13, r12 mov r13, r12
scasb.rep.nz r13, '%' scasb r13, '%'
; everything below r13 is a regular character; print it ; everything below r13 is a regular character; print it
.print_regular: .print_regular:
@ -62,7 +62,7 @@ doprnt:
bzr r13, .nullstring bzr r13, .nullstring
.print_string: .print_string:
mov ax0, b[r13] movzx ax0, b[r13]
bzr ax0, .main_loop bzr ax0, .main_loop
inc r13, 1 inc r13, 1
@ -107,7 +107,7 @@ doprnt:
inc r14, 8 inc r14, 8
.print_itoa_buf: .print_itoa_buf:
mov ax0, b[r13] movzx ax0, b[r13]
bzr ax0, .pib_end_loop bzr ax0, .pib_end_loop
inc r13, 1 inc r13, 1
@ -144,8 +144,9 @@ doprnt:
.epilogue: .epilogue:
mov rax, r16 mov rax, r16
pop r17, r16, r15 pop r17, r16
pop r14, r13, r12 pop r15, r14
pop r13, r12
leave leave
ret ret
@ -170,7 +171,7 @@ doprnt:
jraxz .r jraxz .r
; yes, so artificially set n=0 ; yes, so artificially set n=0
mov r15, zero nul r15
.r: .r:
ret ret

View File

@ -1,8 +0,0 @@
; 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/fmt/ltostr.k"
include "crt/fmt/strtol.k"
include "crt/fmt/doprnt.k"
include "crt/fmt/printf.k"

View File

@ -12,7 +12,7 @@ itoa:
; void utoa(char *buf, int num, int base) ; void utoa(char *buf, int num, int base)
; ;
utoa: utoa:
mov ax3, zero nul ax3
jmp ltostr jmp ltostr
; ;
@ -20,7 +20,7 @@ utoa:
; ;
ltostr: ltostr:
mov rax, ax0 mov rax, ax0
mov rcx, zero nul rcx
; make sure base is in [2, 32] ; make sure base is in [2, 32]
bltu ax2, 2, .bad bltu ax2, 2, .bad
@ -37,7 +37,7 @@ ltostr:
shr rcx, ax1, 63 ; extract ax1 sign shr rcx, ax1, 63 ; extract ax1 sign
jrcxz .conv jrcxz .conv
sub ax1, zero, ax1 ; NEG if negative neg ax1 ; NEG if negative
; main loop ; main loop
.conv: .conv:
@ -68,7 +68,7 @@ ltostr:
inc ax0, 1 inc ax0, 1
.cxz: .cxz:
mov b[ax0], zero nul b[ax0]
call strrev2, rax call strrev2, rax
ret ret
@ -77,7 +77,6 @@ ltostr:
; exceptional cases ; exceptional cases
; ;
.bad: .bad:
mov q[errno], EINVAL
mov b[ax0], 0 mov b[ax0], 0
ret ret

View File

@ -6,7 +6,7 @@
; ;
putc: putc:
prn ax0 prn ax0
mov rax, zero nul rax
ret ret
; ;

View File

@ -18,7 +18,7 @@ strtol:
; rdx = pointer to first invalid byte ; rdx = pointer to first invalid byte
; ;
strtoul: strtoul:
mov ax2, zero nul ax2
jmp strtoq jmp strtoq
; ;
@ -27,8 +27,7 @@ strtoul:
; guesses base when 'base'=0 ; guesses base when 'base'=0
; ;
strtoq: strtoq:
mov rax, zero nul rax, rsi
mov rsi, zero
mov rdx, ax0 mov rdx, ax0
; make sure base is in [2, 32] ; make sure base is in [2, 32]
@ -158,12 +157,11 @@ strtoq:
bzr rsi, .r bzr rsi, .r
; yes ; yes
sub rax, zero, rax neg rax
.r: .r:
ret ret
.bad: .bad:
mov q[errno], EINVAL
ret ret

View File

@ -24,7 +24,7 @@ memzero:
jrcxz .r jrcxz .r
.l: .l:
mov b[ax0], zero nul b[ax0]
inc ax0, 1 inc ax0, 1
loop .l loop .l

222
ka/crt/str.k Normal file
View File

@ -0,0 +1,222 @@
; 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 strnlen(char *, int)
;
strnlen:
mov rcx, ax1
scasb ax0, zero
sub rax, ax1, rcx
ret
;
; int strlen(char *)
;
strlen:
mov rcx, STRLEN_MAX
mov rdx, rcx
scasb ax0, zero
sub rax, rdx, rcx
ret
;
; void strcpy(char *, const char *)
;
strcpy:
.l:
mov rcx, b[ax1]
mov b[ax0], rcx
jrcxz .r
inc ax0, 1
inc ax1, 1
jmp .l
.r:
ret
;
; void strncpy(char *, const char *, int)
;
strncpy:
mov rcx, ax2
jrcxz .r
.l:
mov b[ax0], b[ax1]
inc ax0, 1
inc ax1, 1
loop .l
.r:
ret
;
; void strnzcpy(char *, const char *, int)
;
strnzcpy:
mov rcx, ax2
jrcxz .r
.l:
mov rax, b[ax1]
mov b[ax0], rax
jraxz .r
inc ax0, 1
inc ax1, 1
loop .l
.z:
nul b[ax0]
.r:
ret
;
; int strcmp(const char *str1, const char *str2)
;
; Returns:
; 0 if the contents of both strings are equal
; >0 if the first character that does not match has a greater value in str1 than in str2
; <0 if the first character that does not match has a lower value in str1 than in str2
;
strcmp:
nul rsi
.l:
movzx rax, b[ax0+rsi]
movzx rdx, b[ax1+rsi]
bne rax, rdx, .r
; both zero?
add rcx, rax, rdx
jrcxz .r
inc rsi, 1
jmp .l
.r:
dec rax, rdx
ret
;
; int strncmp(const char *str1, const char *str2, int maxn)
;
strncmp:
mov rcx, ax2
jrcxz .r
.l:
movzx rax, b[ax0]
movzx rdx, b[ax1]
bne rax, rdx, .r
inc ax0, 1
inc ax1, 1
loop .l
.r:
dec rax, rdx
ret
;
; char *strchrnul(const char *str, int ch)
;
strchrnul:
mov rcx, STRLEN_MAX
scasb ax0, ax1
mov rax, ax0
ret
;
; char *strchr(const char *str, int ch)
;
strchr:
mov rcx, STRLEN_MAX
scasb ax0, ax1
bnz b[ax0], .r
nul rax
ret
.r:
mov rax, ax0
ret
;
; void strrev(char *buf, const char *str)
;
; buf and src must NOT overlap
;
strrev:
bzr b[ax1], .z
; save str's location
mov rsi, ax1
; go to str's end, just before
; the null terminator
mov rcx, STRLEN_MAX
scasb ax1, zero
dec ax1, 1
.l:
; copy, going backward though str
; and forward through buf
mov b[ax0], b[ax1]
beq ax1, rsi, .r
inc ax0, 1
dec ax1, 1
jmp .l
.r:
nul b[ax0+1]
ret
.z:
nul b[ax0]
ret
;
; void strrev2(char *str)
;
; Inverses str
;
strrev2:
bzr b[ax0], .r
mov ax1, ax0
; go to str's end, just before
; the null terminator
mov rcx, STRLEN_MAX
scasb ax1, zero
dec ax1, 1
; increase ax0 while decreasing ax1, performing exchanges
.l:
blteu ax1, ax0, .r
xchg b[ax0], b[ax1]
inc ax0, 1
dec ax1, 1
jmp .l
.r:
ret

View File

@ -1,27 +0,0 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; char *strchrnul(const char *str, int ch)
;
strchrnul:
mov rcx, STRLEN_MAX
scasb.rep.nz ax0, ax1
mov rax, ax0
ret
;
; char *strchr(const char *str, int ch)
;
strchr:
mov rcx, STRLEN_MAX
scasb.rep.nz ax0, ax1
bnz b[ax0], .r
mov rax, zero
ret
.r:
mov rax, ax0
ret

View File

@ -1,51 +0,0 @@
; 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 strcmp(const char *str1, const char *str2)
;
; Returns:
; 0 if the contents of both strings are equal
; >0 if the first character that does not match has a greater value in str1 than in str2
; <0 if the first character that does not match has a lower value in str1 than in str2
;
strcmp:
mov rsi, zero
.l:
movzx rax, b[ax0+rsi]
movzx rdx, b[ax1+rsi]
bne rax, rdx, .r
; both zero?
add rcx, rax, rdx
jrcxz .r
inc rsi, 1
jmp .l
.r:
dec rax, rdx
ret
;
; int strncmp(const char *str1, const char *str2, int maxn)
;
strncmp:
mov rcx, ax2
jrcxz .r
.l:
movzx rax, b[ax0]
movzx rdx, b[ax1]
bne rax, rdx, .r
inc ax0, 1
inc ax1, 1
loop .l
.r:
dec rax, rdx
ret

View File

@ -1,63 +0,0 @@
; 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 strcpy(char *, const char *)
;
strcpy:
.l:
mov rcx, b[ax1]
mov b[ax0], rcx
jrcxz .r
inc ax0, 1
inc ax1, 1
jmp .l
.r:
ret
;
; void strncpy(char *, const char *, int)
;
strncpy:
mov rcx, ax2
jrcxz .r
.l:
mov b[ax0], b[ax1]
inc ax0, 1
inc ax1, 1
loop .l
.r:
ret
;
; void strnzcpy(char *, const char *, int)
;
strnzcpy:
mov rcx, ax2
jrcxz .r
.l:
mov rax, b[ax1]
mov b[ax0], rax
jraxz .r
inc ax0, 1
inc ax1, 1
loop .l
.z:
mov b[ax0], zero
.r:
ret

View File

@ -1,9 +0,0 @@
; 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/str/strlen.k"
include "crt/str/strrev.k"
include "crt/str/strcpy.k"
include "crt/str/strcmp.k"
include "crt/str/strchr.k"

View File

@ -1,24 +0,0 @@
; 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 strnlen(char *, int)
;
strnlen:
mov rcx, ax1
scasb.rep.nz ax0, zero
sub rax, ax1, rcx
ret
;
; int strlen(char *)
;
strlen:
mov rcx, STRLEN_MAX
mov rdx, rcx
scasb.rep.nz ax0, zero
sub rax, rdx, rcx
ret

View File

@ -1,72 +0,0 @@
; 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 strrev(char *buf, const char *str)
;
; buf and src must NOT overlap
;
strrev:
bzr b[ax1], .z
; save str's location
mov rsi, ax1
; go to str's end, just before
; the null terminator
mov rcx, STRLEN_MAX
scasb.rep.nz ax1, zero
dec ax1, 1
.l:
; copy, going backward though str
; and forward through buf
mov b[ax0], b[ax1]
beq ax1, rsi, .r
inc ax0, 1
dec ax1, 1
jmp .l
.r:
mov b[ax0+1], zero
ret
.z:
mov b[ax0], zero
ret
;
; void strrev2(char *str)
;
; Inverses str
;
strrev2:
bzr b[ax0], .r
mov ax1, ax0
; go to str's end, just before
; the null terminator
mov rcx, STRLEN_MAX
scasb.rep.nz ax1, zero
dec ax1, 1
; increase ax0 while decreasing ax1, performing exchanges
.l:
blteu ax1, ax0, .r
xchg b[ax0], b[ax1]
inc ax0, 1
dec ax1, 1
jmp .l
.r:
ret

View File

@ -45,32 +45,33 @@ DaysInYear:
; TIME *GetTimeUTC(void) ; TIME *GetTimeUTC(void)
; ;
GetTimeUTC: GetTimeUTC:
ytime ax0, ax1, ax2 ytime
mov rdx, .buf
mov rdi, .buf
; seconds ; seconds
rem rcx, ax0, 60 rem rsi, rax, 60
mov b[rdx], rcx mov b[rdi], rsi
; minutes ; minutes
div rcx, ax0, 60 div rsi, rax, 60
rem rcx, 60 rem rsi, 60
mov b[rdx+1], rcx mov b[rdi+1], rsi
; hours ; hours
div rcx, ax0, 3600 div rsi, rax, 3600
rem rcx, 24 rem rsi, 24
mov b[rdx+2], rcx mov b[rdi+2], rsi
; month days ; month days
div rcx, ax0, 3600*24 div rsi, rax, 3600*24
mov b[rdx+3], rcx mov b[rdi+3], rsi
; month ; month
mov b[rdx+4], ax1 mov b[rdi+4], rbx
; years ; years
mov w[rdx+6], ax2 mov w[rdi+6], rcx
; ;
; ydays (TODO) ; ydays (TODO)

View File

@ -26,7 +26,7 @@ start:
mov rsp, DOSKRNL_STACK mov rsp, DOSKRNL_STACK
mov rbp, zero mov rbp, zero
; dump ;dump
call main call main

View File

@ -15,15 +15,13 @@ def mkstat(fp):
if len(tok) == 0: if len(tok) == 0:
continue continue
i = tok[0].split('.')[0] if len(tok[0]) == 0 or tok[0] in ';#@/':
if len(i) == 0 or i in ';#@/':
continue continue
if i in instrs: if tok[0] in instrs:
instrs[i] += 1 instrs[tok[0]] += 1
else: else:
instrs[i] = 1 instrs[tok[0]] = 1
for root, _, files in os.walk('.'): for root, _, files in os.walk('.'):
for f in files: for f in files:

View File

@ -9,18 +9,12 @@ dumprf:
mov r12, ax0 mov r12, ax0
mov r13, rsp mov r13, rsp
call RFS.LoadReg, r12, $cr2
push rax
call RFS.LoadReg, r12, $cr1 call RFS.LoadReg, r12, $cr1
push rax push rax
call RFS.LoadReg, r12, $cr0 call RFS.LoadReg, r12, $cr0
push rax push rax
call RFS.LoadReg, r12, $rfx
push rax
call RFS.LoadReg, r12, $rip call RFS.LoadReg, r12, $rip
push rax push rax
@ -33,7 +27,7 @@ dumprf:
call RFS.LoadReg, r12, $trp call RFS.LoadReg, r12, $trp
push rax push rax
push 0 # fixme push zero # fixme
call RFS.LoadReg, r12, $rbp call RFS.LoadReg, r12, $rbp
push rax push rax
@ -120,7 +114,7 @@ dumprf:
leave leave
ret ret
.dmp1 = "Environ #1:\nfrm=0d%d rip=0x%x rfx=0x%x\ncr0=0x%x cr1=0x%x cr2=0x%x\n\n" .dmp1 = "Environ #1:\nfrm=0d%d rip=0x%x\ncr0=0x%x cr1=0x%x\n\n"
.dmp2 = "Environ #2:\nrsp=0x%x rbp=0x%x ind=0d%d\ngrp=0x%x trp=0x%x srp=0x%x\n\n" .dmp2 = "Environ #2:\nrsp=0x%x rbp=0x%x ind=0d%d\ngrp=0x%x trp=0x%x srp=0x%x\n\n"
.dmp3 = "Argument:\nax0=0x%x ax1=0x%x ax2=0x%x\nax3=0x%x ax4=0x%x ax5=0x%x\n\n" .dmp3 = "Argument:\nax0=0x%x ax1=0x%x ax2=0x%x\nax3=0x%x ax4=0x%x ax5=0x%x\n\n"
.dmp4 = "Volatile:\nrax=0x%x rbx=0x%x rcx=0x%x\nrdx=0x%x rsi=0x%x rdi=0x%x\n\n" .dmp4 = "Volatile:\nrax=0x%x rbx=0x%x rcx=0x%x\nrdx=0x%x rsi=0x%x rdi=0x%x\n\n"

View File

@ -11,7 +11,7 @@ ScreenOfDeath:
push ax1 push ax1
call printf, .scr1 call printf, .scr1
pop zero pop
bnz r14, .not_con bnz r14, .not_con
push .scr2_con push .scr2_con

View File

@ -18,7 +18,7 @@ DefaultExceptionHandler:
.err_ukn = "Unknown exception number\0\0\0\0\0\0\0" .err_ukn = "Unknown exception number\0\0\0\0\0\0\0"
.err_udf = "Undefined behaviour exception\0\0" .err_udf = "Undefined behaviour exception\0\0"
.err_ill = "Ill-formed exception exception\0" .err_ill = "Illformed instruction exception"
.err_acc = "Invalid memory access exception" .err_acc = "Invalid memory access exception"
.err_sys = "Supervisor-only exception used\0" .err_sys = "Supervisor-only exception used\0"
.err_dbf = "Double fault exception~~~~~~~~\0" .err_dbf = "Double fault exception~~~~~~~~\0"

View File

@ -2,14 +2,14 @@
; See the LICENSE file in the project root for more information. ; See the LICENSE file in the project root for more information.
TrapHandlers.prolog: TrapHandlers.prolog:
mov rbp, zero nul rbp
; rax = caller's cr2 ; rax = caller's cr1
call RFS.LoadReg, r14, $cr2 call RFS.LoadReg, r14, $cr1
; we don't preserve the r12 we got ; we don't preserve the r12 we got
mov r12, rax mov r12, rax
mov rdx, zero nul rdx
jmp rcx jmp rcx
@ -105,12 +105,8 @@ DefaultTrapHandler:
mov ax2, rcx mov ax2, rcx
call RFS.StoreReg, zero, $cr1 call RFS.StoreReg, zero, $cr1
; Data offset
mov ax2, rcx
call RFS.StoreReg, zero, $cr2
; Return frame ; Return frame
mov r14, zero nul r14
jmp .fini jmp .fini

View File

@ -10,9 +10,9 @@ builtins.dir:
push r12, r13 push r12, r13
push r14, r15 push r14, r15
mov r12, zero # no. of files found nul r12 # no. of files found
mov r13, zero # no. of directories found nul r13 # no. of directories found
mov r14, zero # total amount of bytes found nul r14 # total amount of bytes found
call print, .dirmsg call print, .dirmsg
@ -46,7 +46,7 @@ builtins.dir:
mov rcx, FNAME_MAX mov rcx, FNAME_MAX
mov rsi, .buf mov rsi, .buf
mov rdi, rsi mov rdi, rsi
scasb.rep.nz rsi, '.' scasb rsi, '.'
; print file name ; print file name
sub ax1, rsi, rdi sub ax1, rsi, rdi

View File

@ -21,14 +21,16 @@ main:
.print_prompt: .print_prompt:
call print, prompt call print, prompt
; empty argbuf ; empty stuff
call memzero, argbuf, argbuf.size call memzero, argbuf, argbuf.size
call nprint, argbuf, argbuf.size call memzero, argv0, argbuf.size
nul q[argv1pos]
# call nprint, argv0, argbuf.size
; iterator through argbuf ; iterator through argbuf
mov rcx, zero nul rcx
mov q[argv1pos], zero
.input_loop: .input_loop:
pause pause
@ -51,7 +53,7 @@ main:
; yes, delete it ; yes, delete it
dec rcx, 1 dec rcx, 1
add rdx, rcx, argbuf add rdx, rcx, argbuf
mov b[rdx], zero nul b[rdx]
; update screen ; update screen
bzr b[stdin_echoing], .input_loop bzr b[stdin_echoing], .input_loop
@ -86,7 +88,7 @@ main:
; find first whitespace or null-terminator ; find first whitespace or null-terminator
mov rcx, argbuf.size mov rcx, argbuf.size
mov rdx, argbuf mov rdx, argbuf
scasb.rep.nz rdx, ' ' scasb rdx, ' '
; argv1 exists? if so, save its position ; argv1 exists? if so, save its position
mov rsi, rdx mov rsi, rdx
@ -108,9 +110,6 @@ main:
; fallthrough ; fallthrough
.do_extract: .do_extract:
; empty argv0
call memzero, argv0, argbuf.size
; how much do we copy? ; how much do we copy?
sub rcx, rdx, argbuf sub rcx, rdx, argbuf
jrcxz .detect_builtin jrcxz .detect_builtin

View File

@ -250,6 +250,8 @@ long cpudev_idtdone(dev_t *dev)
if (idt_handling[R(AX0)] == 0) if (idt_handling[R(AX0)] == 0)
_except(E_UDF, "cpudev: idtdone, not handling E/I #%u", R(AX0)); _except(E_UDF, "cpudev: idtdone, not handling E/I #%u", R(AX0));
//trace("IDT.DONE %lu\n", R(AX0));
idt_handling[R(AX0)]--; idt_handling[R(AX0)]--;
return 0; return 0;

102
vm/in/ALU
View File

@ -5,113 +5,83 @@
# Logical instructions # # Logical instructions #
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# # Bitwise NOT
# Bitwise OR operation not 1
#
# $dest = $src1 OR $src2 # Bitwise OR
#
or 2 or 2
or 3 or 3
# # Bitwise AND
# Bitwise AND operation
#
# $dest = $src1 AND $src2
#
and 2 and 2
and 3 and 3
# # Bitwise XOR
# Bitwise XOR operation
#
# $dest = $src1 XOR $src2
#
xor 2 xor 2
xor 3 xor 3
# # Logical left/right shift
# Logical left/right shift (SHL/SHR)
#
# $dest = $src1 << $src2 (SHL)
# $dest = $src1 >> $src2 (SHR)
#
shl 2 shl 2
shl 3 shl 3
shr 2 shr 2
shr 3 shr 3
# # Arithmetical right shift
# Arithmetical right shift (SAR)
#
# $dest = $src1 >>> $src2 (SAR)
#
sar 2 sar 2
sar 3 sar 3
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# Arithmetic instructions # # Arithmetic instructions #
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
#
# Arithmetical ADD operation # Negation
# neg 1
# $dest1 = $src1 + $src2
# # Negation but traps on $src == -2^N
negv 1
# Addition
add 2 add 2
add 3 add 3
# # Addition but traps on overflow
# Arithmetical SUB operation addv 2
# addv 3
# $dest = $src1 - $src2
# # Substraction
sub 2 sub 2
sub 3 sub 3
# # Substraction but traps on underflow
# Arithmetical MUL operation subv 2
# subv 3
# $dest = LO($src1 * $src2)
# # Multiplication
# $dest = LO($src1 * $src2)
mul 2 mul 2
mul 3 mul 3
# Arithmetical unsigned MUL operation # Multiplication (unsigned)
# # $dest1 = HI($dest2 * $src)
# $dest1 = HI($dest2 * $src) # $dest2 = LO($dest2 * $src)
# $dest2 = LO($dest2 * $src)
# #
mulhi 3 mulhi 3
# Arithmetical signed MUL operation # Multiplication (signed)
# # $dest1 = HI($dest2 * $src)
# $dest1 = HI($dest2 ** $src) # $dest2 = LO($dest2 * $src)
# $dest2 = LO($dest2 ** $src)
# #
imulhi 3 imulhi 3
# # Division (unsigned)
# Arithmetical unsigned DIV operation
#
# $dest = $src1 DIV $src2
#
# Preserves all flags
#
div 2 div 2
div 3 div 3
# # Division (signed)
# Arithmetical signed DIV operation
#
# $dest = $src1 IDIV $src2
#
idiv 2 idiv 2
idiv 3 idiv 3
# # Modulo/remainder
# Arithmetical modulo operation (REM)
#
# $dest = $src1 MOD $src2
#
rem 2 rem 2
rem 3 rem 3

View File

@ -57,14 +57,17 @@ push 3
# $1 = *RSP # $1 = *RSP
# RSP = RSP + 8 # RSP = RSP + 8
# #
pop 0
pop 1 pop 1
pop 2 pop 2
pop 3
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# Movement instructions # # Movement instructions #
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
nul 1
nul 2
# #
# Load Effective Address (LEA) instruction # Load Effective Address (LEA) instruction
# #
@ -78,27 +81,22 @@ pop 3
lea 2 lea 2
# #
# Move data (MOV) instruction # Move data (MOV/MOVU) instructions
# #
# $1 = SignExtend($2) # $1 = SignExtend($2) (MOV)
# $1 = ZeroExtend($2) (MOVU)
# #
mov 2 mov 2
#
# Load from memory with zero-extension (MOVSX/MOVZX) instruction
#
# $1 = ZeroExtend($2)
#
movzx 2 movzx 2
# #
# Move with sign-extension (MOVSXx) instruction # Move with sign-extension (MOVx) instruction
# #
# $1 = SignExtend($2 & (2^(8 * sizeof(x)) - 1) # $1 = SignExtend($2 & (2^(8 * sizeof(x)) - 1)
# #
movsxb 2 movb 2
movsxw 2 movw 2
movsxd 2 movd 2
# #
# Exchange (XCHG) instruction # Exchange (XCHG) instruction

View File

@ -45,7 +45,7 @@ utime 1
# $2 = current month # $2 = current month
# $3 = current year # $3 = current year
# #
ytime 3 ytime 0
# #
# Clear all GPR registers except RBP/RSP # Clear all GPR registers except RBP/RSP

View File

@ -8,24 +8,18 @@
# #
# Scan string for a particular value (SCASx) # Scan string for a particular value (SCASx)
# #
# CMP([%1], $2) # WHILE RCX > 0 DO
# RCX = RCX - 1
# #
# IF ([%1] == 0) THEN # IF ([%1] == 0) OR ([%1] == $2) THEN
# ZF = 1 # BREAK
# ELIF (ZF == 0) THEN # ELSE
# IF (DF == 0) THEN # %1 = %1 + sizeof(x)
# %1 = %1 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# FI
# FI # FI
# DONE
# #
# Sets CF, OF and SF according to the result of the comparison
# Sets ZF according to whether [%1] and $2 are equal, OR if [%1] is null
# #
# Notes: # Note: Does not move past the value when found
# - Does not move past the value when found
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
# #
scasb 2 scasb 2
scasw 2 scasw 2

View File

@ -8,71 +8,103 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(or, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val | p2->val; return 1; } IMPL_START(not, 1) { SRCP(p1); *r1 = ~p1->val; return 1; }
IMPL_START(and, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val & p2->val; return 1; }
IMPL_START(xor, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val ^ p2->val; return 1; }
IMPL_START(or, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val | p2->val; return 1; }
IMPL_START(or, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val | p3->val; return 1; } IMPL_START(or, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val | p3->val; return 1; }
IMPL_START(and, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val & p2->val; return 1; }
IMPL_START(and, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; } IMPL_START(and, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; }
IMPL_START(xor, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val ^ p2->val; return 1; }
IMPL_START(xor, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val ^ p3->val; return 1; } IMPL_START(xor, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val ^ p3->val; return 1; }
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(shl, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val << p2->val; return 1; } IMPL_START(shl, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val << p2->val; return 1; }
IMPL_START(shr, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val >> p2->val; return 1; }
IMPL_START(sar, 2) { SRCP(p1); SRCP(p2); *r1 = (ulong)((long)p1->val >> (long)p2->val); return 1; }
IMPL_START(shl, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val << p3->val; return 1; } IMPL_START(shl, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val << p3->val; return 1; }
IMPL_START(shr, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val >> p2->val; return 1; }
IMPL_START(shr, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val >> p3->val; return 1; } IMPL_START(shr, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val >> p3->val; return 1; }
IMPL_START(sar, 3) { SRCP(p2); SRCP(p3); *r1 = (ulong)((long)p2->val >> (long)p3->val); return 1; }
IMPL_START(sar, 2) {
SRCP(p1); SRCP(p2);
*r1 = (ulong)((long)p1->val >> (long)p2->val);
return 1;
}
IMPL_START(sar, 3) {
SRCP(p2); SRCP(p3);
*r1 = (ulong)((long)p2->val >> (long)p3->val);
return 1;
}
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(neg, 1) { SRCP(p1); *r1 = ~p1->val + 1; return 1; }
IMPL_START(negv, 1) {
SRCP(p1);
if (p1->val == (1ul<<63))
_except(E_OVF, "Ineffective NEG operation (NEGV)");
*r1 = ~p1->val + 1;
return 1;
}
IMPL_START(add, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; } IMPL_START(add, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; }
IMPL_START(add, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val + p3->val; return 1; } IMPL_START(add, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val + p3->val; return 1; }
IMPL_START(addf, 3) { SRCP(p2); SRCP(p3); COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->val; return 1; }
IMPL_START(addv, 2) {
SRCP(p1); SRCP(p2);
ulong rs = p1->val + p2->val;
if (((p1->val ^ rs) & (p2->val ^ rs)) >> 63)
_except(E_OVF, "Signed addition overflow (ADDV#2)");
*r1 = rs;
return 1;
}
IMPL_START(addv, 3) {
SRCP(p2); SRCP(p3);
ulong rs = p2->val + p3->val;
if (((p2->val ^ rs) & (p3->val ^ rs)) >> 63)
_except(E_OVF, "Signed addition overflow (ADDV#3)");
*r1 = rs;
return 1;
}
//----------------------------------------------------------------------------//
IMPL_START(sub, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; } IMPL_START(sub, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; }
IMPL_START(sub, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val - p3->val; return 1; } IMPL_START(sub, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val - p3->val; return 1; }
IMPL_START(subf, 3) { SRCP(p2); SRCP(p3); COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->val; return 1; }
IMPL_START(adcx, 2) { IMPL_START(subv, 2) {
SRCP(p1); SRCP(p2); SRCP(p1); SRCP(p2);
p2->val += !!(R(RFX)&CF); ulong rs = p1->val - p2->val;
COMPARE_ADD(p1->val, p2->val);
*r1 = p1->val + p2->val;
if (((p1->val ^ rs) & (p1->val ^ p2->val)) >> 63)
_except(E_OVF, "Signed substraction underflow (SUBV#2)");
*r1 = rs;
return 1; return 1;
} }
IMPL_START(adcx, 3) { IMPL_START(subv, 3) {
SRCP(p2); SRCP(p3);
p3->val += !!(R(RFX)&CF);
COMPARE_ADD(p2->val, p3->val);
*r1 = p2->val + p3->val;
return 1;
}
IMPL_START(sbbx, 2) {
SRCP(p1); SRCP(p2); SRCP(p1); SRCP(p2);
p2->val += !!(R(RFX)&CF); ulong rs = p2->val - p3->val;
COMPARE_SUB(p1->val, p2->val);
*r1 = p1->val - p2->val;
return 1; if (((p2->val ^ rs) & (p2->val ^ p3->val)) >> 63)
} _except(E_OVF, "Signed substraction underflow (SUBV#3)");
IMPL_START(sbbx, 3) {
SRCP(p2); SRCP(p3);
p3->val += !!(R(RFX)&CF);
COMPARE_SUB(p2->val, p3->val);
*r1 = p2->val - p3->val;
*r1 = rs;
return 1; return 1;
} }

View File

@ -54,7 +54,7 @@ def parse_2(fp):
.format(deprecated, tok[0], n, tok[0], n)) .format(deprecated, tok[0], n, tok[0], n))
hd.write("#else\n") hd.write("#else\n")
hd.write("#define I_{}_{} {}\n".format(tok[0].upper(), n, count)) hd.write("#define I_{}_{} {}\n".format(tok[0].upper(), n, count))
hd.write("extern bool i_{}_{}(acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n" hd.write("extern bool i_{}_{}(acc_t *, acc_t *, acc_t *, ulong *, ulong *);\n"
.format(tok[0], n)) .format(tok[0], n))
hd.write("#endif\n\n") hd.write("#endif\n\n")

View File

@ -7,7 +7,7 @@
#define IMPL_START(name, n) \ #define IMPL_START(name, n) \
uint i_##name##_##n(acc_t *p1, acc_t *p2, acc_t *p3, \ uint i_##name##_##n(acc_t *p1, acc_t *p2, acc_t *p3, \
ulong *r1, ulong *r2, ulong *r3) \ ulong *r1, ulong *r2) \
#define XSRCP(v, p, x) \ #define XSRCP(v, p, x) \
if (ACC_FMT_IS_MEM(p->type)) \ if (ACC_FMT_IS_MEM(p->type)) \
@ -20,52 +20,6 @@ uint i_##name##_##n(acc_t *p1, acc_t *p2, acc_t *p3, \
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#define INTO() \
if (R(RFX) & OF) _except(E_OVF, "Overflow");
#define PARITY(v) __builtin_parity(v)
#define SET_ZF(v) \
R(RFX) = ((v) == 0 ? (R(RFX)|ZF) : (R(RFX)&~ZF))
#define SET_SF(v) \
R(RFX) = ((long)(v) < 0 ? (R(RFX)|SF) : (R(RFX)&~SF))
#define SET_PF(v) \
R(RFX) = (PARITY(v) == 1 ? (R(RFX)|PF) : (R(RFX)&~PF))
#define SET_ZSF(v) \
SET_ZF(v); \
SET_SF(v)
//----------------------------------------------------------------------------//
#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 (((_u1 ^ _u3) & (_u1 ^ _u2)) >> 63) \
R(RFX) |= OF; \
else R(RFX) &= ~OF; \
\
SET_ZSF(_u3);
//----------------------------------------------------------------------------//
#define CHK_SUPERV() \ #define CHK_SUPERV() \
do { \ do { \
if ((R(CR0) & UF) > 0) { \ if ((R(CR0) & UF) > 0) { \

View File

@ -13,6 +13,8 @@ IMPL_START(jrcxz, 1) { if (!R(RCX)) R(RIP) = p1->val; return 0; }
IMPL_START(jraxnz, 1) { if (R(RAX)) R(RIP) = p1->val; return 0; } IMPL_START(jraxnz, 1) { if (R(RAX)) R(RIP) = p1->val; return 0; }
IMPL_START(jrcxnz, 1) { if (R(RCX)) R(RIP) = p1->val; return 0; } IMPL_START(jrcxnz, 1) { if (R(RCX)) R(RIP) = p1->val; return 0; }
//----------------------------------------------------------------------------//
IMPL_START(loop, 1) { IMPL_START(loop, 1) {
if (R(RCX) > 0) { if (R(RCX) > 0) {
R(RCX)--; R(RCX)--;
@ -21,6 +23,17 @@ IMPL_START(loop, 1) {
return 0; return 0;
} }
IMPL_START(loop, 2) {
SRCP(p1);
if (p1->val > 0) {
*r1 = p1->val-1;
R(RIP) = p2->val;
}
return 0;
}
//----------------------------------------------------------------------------//
IMPL_START(bzr, 2) { SRCP(p1); if (p1->val == 0) R(RIP) = p2->val; return 0; } IMPL_START(bzr, 2) { SRCP(p1); if (p1->val == 0) R(RIP) = p2->val; return 0; }
IMPL_START(bnz, 2) { SRCP(p1); if (p1->val != 0) R(RIP) = p2->val; return 0; } IMPL_START(bnz, 2) { SRCP(p1); if (p1->val != 0) R(RIP) = p2->val; return 0; }
IMPL_START(bltz, 2) { SRCP(p1); if ((long)p1->val < 0) R(RIP) = p2->val; return 0; } IMPL_START(bltz, 2) { SRCP(p1); if ((long)p1->val < 0) R(RIP) = p2->val; return 0; }
@ -34,24 +47,5 @@ IMPL_START(bltu, 3) { SRCP(p1); if (p1->val < p2->val) R(RIP) = p3->val; return
IMPL_START(blte, 3) { SRCP(p1); if ((long)p1->val <= (long)p2->val) R(RIP) = p3->val; return 0; } IMPL_START(blte, 3) { SRCP(p1); if ((long)p1->val <= (long)p2->val) R(RIP) = p3->val; return 0; }
IMPL_START(blteu, 3) { SRCP(p1); if (p1->val <= p2->val) R(RIP) = p3->val; return 0; } IMPL_START(blteu, 3) { SRCP(p1); if (p1->val <= p2->val) R(RIP) = p3->val; return 0; }
IMPL_START(bch, 3) //----------------------------------------------------------------------------//
{
SRCP(p1);
SRCP(p2);
COMPARE_SUB(p1->val, p2->val);
if (eval_cond(ctx->cond))
R(RIP) = p3->val;
return 0;
}
IMPL_START(cmp, 2)
{
SRCP(p1);
COMPARE_SUB(p1->val, p2->val);
return 0;
}

View File

@ -6,12 +6,16 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(lea, 2) { *r1 = p2->addr; return 1; } IMPL_START(lea, 2) { *r1 = p2->addr; return 1; }
IMPL_START(mov, 2) { XSRCP(*r1, p2, sx); return 1; } IMPL_START(mov, 2) { XSRCP(*r1, p2, sx); return 1; }
IMPL_START(movzx, 2) { XSRCP(*r1, p2, zx); return 1; } IMPL_START(movzx, 2) { XSRCP(*r1, p2, zx); return 1; }
IMPL_START(movsxb, 2) { SRCP(p2); *r1 = (ulong)(long)(char)p2->val; return 1; } IMPL_START(movb, 2) { SRCP(p2); *r1 = (ulong)(long)(char)p2->val; return 1; }
IMPL_START(movsxw, 2) { SRCP(p2); *r1 = (ulong)(long)(short)p2->val; return 1; } IMPL_START(movw, 2) { SRCP(p2); *r1 = (ulong)(long)(short)p2->val; return 1; }
IMPL_START(movsxd, 2) { SRCP(p2); *r1 = (ulong)(long)(int)p2->val; return 1; } IMPL_START(movd, 2) { SRCP(p2); *r1 = (ulong)(long)(int)p2->val; return 1; }
IMPL_START(nul, 1) { *r1 = 0; return 1; }
IMPL_START(nul, 2) { *r1 = 0; *r2 = 0; return 2; }
IMPL_START(xchg, 2) IMPL_START(xchg, 2)
{ {
@ -64,6 +68,12 @@ IMPL_START(push, 3)
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(pop, 0)
{
R(RSP) += 8;
return 0;
}
IMPL_START(pop, 1) IMPL_START(pop, 1)
{ {
*r1 = readmemzx(R(RSP), 8); *r1 = readmemzx(R(RSP), 8);
@ -81,16 +91,6 @@ IMPL_START(pop, 2)
return 2; return 2;
} }
IMPL_START(pop, 3)
{
*r1 = readmemzx(R(RSP) + 0, 8);
*r2 = readmemzx(R(RSP) + 8, 8);
*r3 = readmemzx(R(RSP) + 16, 8);
R(RSP) += 24;
return 3;
}
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(call, 1) IMPL_START(call, 1)
@ -144,6 +144,14 @@ IMPL_START(ret, 0)
return 0; return 0;
} }
IMPL_START(ret, 1)
{
R(RIP) = readmemzx(R(RSP), 8);
R(RSP) += 8 + (p1->val * 8);
return 0;
}
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(enter, 0) IMPL_START(enter, 0)

View File

@ -9,7 +9,6 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(into, 0) { INTO(); return 0; }
IMPL_START(pause, 0) { usleep(5000); return 0; } IMPL_START(pause, 0) { usleep(5000); return 0; }
IMPL_START(udf, 0) { _except(E_UDF, "UDF instruction"); } IMPL_START(udf, 0) { _except(E_UDF, "UDF instruction"); }
@ -35,7 +34,7 @@ IMPL_START(dump, 0)
trace("0x%lX:\t...\n", ctx->cur_pc); trace("0x%lX:\t...\n", ctx->cur_pc);
else if (!ctx->dumpsw) else if (!ctx->dumpsw)
dump_instr(ctx->cur_in, p1, p2, p3, 0, 0); dump_instr(ctx->cur_in, p1, p2, p3);
ctx->dumpsw = !ctx->dumpsw; ctx->dumpsw = !ctx->dumpsw;
#endif #endif
@ -44,19 +43,19 @@ IMPL_START(dump, 0)
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(ytime, 3) IMPL_START(ytime, 0)
{ {
time_t t = time(NULL); time_t t = time(NULL);
struct tm *tm = localtime(&t); struct tm *tm = localtime(&t);
*r1 = tm->tm_sec + tm->tm_min * 60 R(RAX) = tm->tm_sec + tm->tm_min * 60
+ tm->tm_hour * 60 * 60 + tm->tm_hour * 60 * 60
+ tm->tm_mday * 60 * 60 * 24; + tm->tm_mday * 60 * 60 * 24;
*r2 = tm->tm_mon; R(RBX) = tm->tm_mon;
*r3 = tm->tm_year + 1900; R(RCX) = tm->tm_year + 1900;
return 3; return 0;
} }
IMPL_START(utime, 1) IMPL_START(utime, 1)
@ -72,7 +71,6 @@ IMPL_START(utime, 1)
IMPL_START(cls, 0) IMPL_START(cls, 0)
{ {
R(RFX) = 0;
for (int i = RAX; i <= R20; i++) R(i) = 0; for (int i = RAX; i <= R20; i++) R(i) = 0;
return 0; return 0;
@ -148,6 +146,8 @@ IMPL_START(prn, 1)
break; break;
default: default:
trace("PRN bad magic: %lx\n", v);
die(1);
_except(E_ILL, "Bad PRN magic"); _except(E_ILL, "Bad PRN magic");
} }
} }
@ -158,28 +158,6 @@ IMPL_START(prn, 1)
return 0; return 0;
} }
IMPL_START(prns, 1)
{
if (p1->type != A_REG)
_except(E_ILL, "PRNS given a non-REG operand");
uchar ch = readmemzx(R(p1->reg), 1);
COMPARE_SUB(ch, 0);
if ((R(RFX) & ZF) == 0)
{
console_putc(ch);
if (R(RFX) & DF)
R(p1->reg)--;
else
R(p1->reg)++;
}
return 0;
}
IMPL_START(scan, 1) IMPL_START(scan, 1)
{ {
*r1 = console_scankeybuf(); *r1 = console_scankeybuf();

View File

@ -11,36 +11,21 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
static void stos_impl(acc_t *p1, acc_t *p2, uint len)
{
if (p1->type != A_REG)
_except(E_ILL, "STOSX given a non-REG operand");
writemem(p2->val, R(p1->reg), len);
STR_MOVE(p1->reg, len);
}
IMPL_START(stosb, 2) { stos_impl(p1, p2, 1); return 0; }
IMPL_START(stosw, 2) { stos_impl(p1, p2, 2); return 0; }
IMPL_START(stosd, 2) { stos_impl(p1, p2, 4); return 0; }
IMPL_START(stosq, 2) { stos_impl(p1, p2, 8); return 0; }
//----------------------------------------------------------------------------//
static void scas_impl(acc_t *p1, acc_t *p2, uint len) static void scas_impl(acc_t *p1, acc_t *p2, uint len)
{ {
if (p1->type != A_REG) if (p1->type != A_REG)
_except(E_ILL, "SCASX given a non-REG operand"); _except(E_ILL, "SCASX given a non-REG operand");
ulong x = readmemsx(R(p1->reg), len); while (R(RCX) > 0)
COMPARE_SUB(x, p2->val); {
ulong x = readmemzx(R(p1->reg), len);
if (x == 0) { if (x == 0 || x == p2->val)
R(RFX) |= ZF; break;
}
else if (!(R(RFX)&ZF)) { R(p1->reg) += len;
STR_MOVE(p1->reg, len);
R(RCX)--;
} }
} }

View File

@ -3,11 +3,7 @@
Instruction encoding: Instruction encoding:
Byte 1: Instruction number Byte: Instruction number
Byte 2:
xx0xxxxx
|| └───┘
RL CND
Values for ModRMs: Values for ModRMs:
000xxxxx xxxxx = reg 000xxxxx xxxxx = reg
@ -24,19 +20,3 @@ Values for ModRMs:
11100100 imm32 (zero extended) 11100100 imm32 (zero extended)
11101000 imm64 (zero extended) 11101000 imm64 (zero extended)
Values for COND:
00000 (none)
00001 .C .B
00010 .O
00011 .Z .E
00100 .S
00101 .P
00110 .BE
00111 .L
01000 .LE
01001 .AXZ
01010 .BXZ
01011 .CXZ
01100 .DXZ
Highest (6th) bit of COND indicates negation

View File

@ -72,9 +72,6 @@ struct ctx_t
ulong ninstrs; // totally ulong ninstrs; // totally
ulong ni_thisfr; // this frame ulong ni_thisfr; // this frame
// Last COND field
uint cond;
// Dumpinstr switch // Dumpinstr switch
bool dumpsw; bool dumpsw;
}; };

View File

@ -195,8 +195,8 @@ static void extract_param(instr_t *in, acc_t *p)
// //
void decode(void) void decode(void)
{ {
ushort b;
instr_t *in; instr_t *in;
ushort b1, b2, rep = 0, lock;
acc_t p1 = { 0 }, p2 = { 0 }, p3 = { 0 }; acc_t p1 = { 0 }, p2 = { 0 }, p3 = { 0 };
//logerr("decodin'\n"); //logerr("decodin'\n");
@ -209,35 +209,20 @@ void decode(void)
_except(E_ACC, "Executing out of memory"); _except(E_ACC, "Executing out of memory");
// Instruction bytes // Instruction bytes
b1 = fetchb(); b = fetchb();
// Suffixes?
if (b1 & (1 << 7))
{
b1 &= ~(1 << 7);
b2 = fetchb();
}
else
b2 = 0;
// Renge check // Renge check
if (b1 >= NINSTRS) if (b >= NINSTRS)
_except(E_ILL, "No such INSTR: 0x%hhX", b1); _except(E_ILL, "No such INSTR: 0x%hhX", b);
// Find instruction // Find instruction
in = &ctx->i[b1]; in = &ctx->i[b];
ctx->cur_in = in; ctx->cur_in = in;
// Get flags/etc
rep = !!(b2 & SUFF_REP);
lock = !!(b2 & SUFF_LOCK);
ctx->cond = b2 & SUFF_COND;
// Operand 1? // Operand 1?
if (in->nprms == 0) if (in->nprms == 0)
{ {
exec_instr(in, NULL, NULL, NULL, lock, rep); exec_instr(in, NULL, NULL, NULL);
return; return;
} }
@ -246,7 +231,7 @@ void decode(void)
// Operand 2? // Operand 2?
if (in->nprms == 1) if (in->nprms == 1)
{ {
exec_instr(in, &p1, NULL, NULL, lock, rep); exec_instr(in, &p1, NULL, NULL);
return; return;
} }
@ -255,12 +240,12 @@ void decode(void)
// Operand 1? // Operand 1?
if (in->nprms == 2) if (in->nprms == 2)
{ {
exec_instr(in, &p1, &p2, NULL, lock, rep); exec_instr(in, &p1, &p2, NULL);
return; return;
} }
extract_param(in, &p3); extract_param(in, &p3);
exec_instr(in, &p1, &p2, &p3, lock, rep); exec_instr(in, &p1, &p2, &p3);
} }

View File

@ -1,30 +1,6 @@
// 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.
enum
{
CD_NONE,
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
{
SUFF_REP = (1 << 7),
SUFF_LOCK = (1 << 6),
SUFF_COND = 0b00011111,
};
enum enum
{ {
A_NONE = 0, A_NONE = 0,
@ -68,22 +44,16 @@ struct instr_t
char *name; char *name;
uint nprms; uint nprms;
uint (*func)(acc_t *, acc_t *, acc_t *, uint (*func)(acc_t *, acc_t *, acc_t *,
ulong *, ulong *, ulong *); ulong *, ulong *);
}; };
bool eval_cond(uint cond);
void exec_instr(instr_t *in, void exec_instr(instr_t *in,
acc_t *p1, acc_t *p1,
acc_t *p2, acc_t *p2,
acc_t *p3, acc_t *p3);
bool lock,
bool rep);
void dump_instr(instr_t *in, void dump_instr(instr_t *in,
acc_t *p1, acc_t *p1,
acc_t *p2, acc_t *p2,
acc_t *p3, acc_t *p3);
bool lock,
bool rep);

View File

@ -5,53 +5,15 @@
#define ABS(x) ((short)(x) < 0 ? -x : x) #define ABS(x) ((short)(x) < 0 ? -x : x)
static const char *cond_suffixes[] =
{
"-",
"c", "o", "z", "s", "p",
"be", "l", "le", "axz",
"bxz", "cxz",
"?"
};
static void dump_acc(acc_t *p); static void dump_acc(acc_t *p);
void dump_instr(instr_t *in, void dump_instr(instr_t *in,
acc_t *p1, acc_t *p1,
acc_t *p2, acc_t *p2,
acc_t *p3, acc_t *p3)
bool lock,
bool rep)
{ {
uint cond = ctx->cond;
trace("0x%lX:\t", ctx->cur_pc); trace("0x%lX:\t", ctx->cur_pc);
trace("%s\t", in->name);
if (lock)
trace("lock");
trace("%s", in->name);
if (rep)
trace(".rep");
if (cond)
{
trace(".");
if (cond & (1 << 4))
trace("n");
assert((cond & ~(1 << 4)) <= sizeof(cond_suffixes)/sizeof(char *));
trace("%s", cond_suffixes[cond & ~(1 << 4)]);
}
if (!rep && cond != ((1 << 4) | CD_CXZ))
trace("\t\t");
else
trace("\t");
if (p1) if (p1)
dump_acc(p1); dump_acc(p1);

View File

@ -75,7 +75,7 @@ void _except(int _code, char *fmt, ...)
{ {
if (ctx->dumpsw) if (ctx->dumpsw)
{ {
trace("\nException %u - ", code); trace("\n(Caught) Exception %u - ", code);
va_start(ap, fmt); va_start(ap, fmt);
vprintf(fmt, ap); vprintf(fmt, ap);

View File

@ -3,41 +3,6 @@
#include <pc/arch.h> #include <pc/arch.h>
#define rfx R(RFX)
bool eval_cond(uint cond)
{
bool neg = cond & (1 << 4);
bool ok;
cond &= ~(1 << 4);
switch (cond)
{
case CD_NONE: ok = 1; break;
case CD_C: ok = rfx&CF; break;
case CD_O: ok = rfx&OF; break;
case CD_Z: ok = rfx&ZF; break;
case CD_S: ok = rfx&SF; break;
case CD_P: ok = rfx&PF; 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(E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond));
}
return neg ? !ok : !!ok;
}
#define OUTPUT(p, r) { \ #define OUTPUT(p, r) { \
if (p->type == A_REG) \ if (p->type == A_REG) \
R(p->reg) = r; \ R(p->reg) = r; \
@ -52,54 +17,26 @@ bool eval_cond(uint cond)
void exec_instr(instr_t *in, void exec_instr(instr_t *in,
acc_t *p1, acc_t *p1,
acc_t *p2, acc_t *p2,
acc_t *p3, acc_t *p3)
bool lock,
bool rep)
{ {
uint out; uint out;
ulong r1 = 0, r2 = 0, r3 = 0; ulong r1 = 0, r2 = 0;
// Global instruction counter // Global instruction counter
ctx->ninstrs++; ctx->ninstrs++;
//
// For REPs we evaluate the condition AFTER running the instruction,
// in a do ... while(cond) fashion
//
if (ctx->cond)
if (!rep && !eval_cond(ctx->cond))
return;
if (ctx->dumpsw) if (ctx->dumpsw)
dump_instr(in, p1, p2, p3, lock, rep); dump_instr(in, p1, p2, p3);
do_rep: out = in->func(p1, p2, p3, &r1, &r2);
out = in->func(p1, p2, p3, &r1, &r2, &r3);
if (out) if (out)
{ {
OUTPUT(p1, r1); OUTPUT(p1, r1);
if (out >= 2) OUTPUT(p2, r2); if (__builtin_expect(out == 2, 0))
if (out >= 3) OUTPUT(p3, r3); OUTPUT(p2, r2);
R(RZX) = 0; R(RZX) = 0;
} }
if (rep)
{
// RCX remains untouched when condition fails
if (!eval_cond(ctx->cond))
return;
if (R(RCX) > 0)
R(RCX)--;
if (R(RCX) == 0)
return;
// Should we really count REP's in instruction count?
ctx->ninstrs++;
goto do_rep;
}
} }

View File

@ -106,7 +106,7 @@ static void writemem64(ulong val, ulong real, ulong addr)
} }
#define GETREAL() \ #define GETREAL() \
ulong real = addr2real(addr + R(CR2)) ulong real = addr2real(addr + R(CR1))
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -5,9 +5,6 @@
reg_t arch_r[] = reg_t arch_r[] =
{ {
{ "zero", GPR }, { "cr0", SYS }, { "cr1", SYS }, { "cr2", SYS },
{ "rfx", GPR }, { "rip", GPR }, { "rbp", GPR }, { "rsp", GPR },
{ "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR }, { "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR },
{ "rsi", GPR }, { "rdi", GPR }, { "ax0", GPR }, { "ax1", GPR }, { "rsi", GPR }, { "rdi", GPR }, { "ax0", GPR }, { "ax1", GPR },
{ "ax2", GPR }, { "ax3", GPR }, { "ax4", GPR }, { "ax5", GPR }, { "ax2", GPR }, { "ax3", GPR }, { "ax4", GPR }, { "ax5", GPR },
@ -15,6 +12,9 @@ reg_t arch_r[] =
{ "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR }, { "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR },
{ "r16", GPR }, { "r17", GPR }, { "r18", GPR }, { "r19", GPR }, { "r16", GPR }, { "r17", GPR }, { "r18", GPR }, { "r19", GPR },
{ "r20", GPR }, { "grp", GPR }, { "trp", GPR }, { "srp", SYS }, { "r20", GPR }, { "grp", GPR }, { "trp", GPR }, { "srp", SYS },
{ "tmp", GPR }, { "rad", GPR }, { "cr0", SYS }, { "cr1", SYS },
{ "rip", GPR }, { "rbp", GPR }, { "rsp", GPR }, { "zero", GPR },
}; };
static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, ""); static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, "");
@ -26,8 +26,8 @@ void dumpregs()
TRACE("Current RFRAME index: #%lu", rfs_current_idx); TRACE("Current RFRAME index: #%lu", rfs_current_idx);
TRACE("\n\nEnviron #1:"); TRACE("\n\nEnviron #1:");
TRACE("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", ctx->cur_pc, R(RIP), R(RFX)); TRACE("\nrpc=0x%-16lX rip=0x%-16lX", ctx->cur_pc, R(RIP));
TRACE("\ncr0=0x%-16lX cr1=0x%-16lX cr2=0x%-16lX", R(CR0), R(CR1), R(CR2)); TRACE("\ncr0=0x%-16lX cr1=0x%-16lX", R(CR0), R(CR1));
TRACE("\n\nEnviron #2:"); TRACE("\n\nEnviron #2:");
TRACE("\nrsp=0x%-16lX rbp=0x%-16lX ins=0d%-16lu", R(RSP), R(RBP), ctx->ninstrs); TRACE("\nrsp=0x%-16lX rbp=0x%-16lX ins=0d%-16lu", R(RSP), R(RBP), ctx->ninstrs);

View File

@ -37,10 +37,10 @@ struct reg_t
enum enum
{ {
RZX, CR0, CR1, CR2, RFX, RIP, RBP, RSP,
RAX, RBX, RCX, RDX, RSI, RDI, AX0, AX1, RAX, RBX, RCX, RDX, RSI, RDI, AX0, AX1,
AX2, AX3, AX4, AX5, R12, R13, R14, R15, AX2, AX3, AX4, AX5, R12, R13, R14, R15,
R16, R17, R18, R19, R20, GRP, TRP, SRP, R16, R17, R18, R19, R20, GRP, TRP, SRP,
TMP, RAD, CR0, CR1, RIP, RBP, RSP, RZX,
NREGS NREGS
}; };

View File

@ -18,9 +18,9 @@ int create_symtab(const char *name)
return -1; return -1;
} }
while (fscanf(tab, "%s %lu\n", buf, &addr) > 0 && it < SYMTAB_LEN) while (fscanf(tab, "%45s%*s %lu\n", buf, &addr) > 0 && it < SYMTAB_LEN)
{ {
// log("SYM: '%.*s' '%lu'\n", SYMLEN_MAX, buf, addr); //trace("SYM: '%.*s' '%lu'\n", SYMLEN_MAX, buf, addr);
if (prev_addr > addr) if (prev_addr > addr)
{ {
@ -38,7 +38,6 @@ int create_symtab(const char *name)
} }
fclose(tab); fclose(tab);
return 0; return 0;
} }

View File

@ -1,7 +1,7 @@
// 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.
#define SYMLEN_MAX 32 #define SYMLEN_MAX 46
#define SYMTAB_LEN 4096 #define SYMTAB_LEN 4096
typedef struct sym_t sym_t; typedef struct sym_t sym_t;
@ -9,7 +9,7 @@ typedef struct sym_t sym_t;
struct sym_t struct sym_t
{ {
ulong addr; ulong addr;
char name[SYMLEN_MAX]; char name[SYMLEN_MAX+1];
}; };
extern sym_t symtab[SYMTAB_LEN]; extern sym_t symtab[SYMTAB_LEN];