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 = {
"r": 0b00000000,
"m_r": 0b00100000,
@ -456,40 +410,11 @@ def parse_instr(line):
params = None
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_args = ''
if params == None or len(params) == 0:
if b2 == 0:
instrs.write("{}_0".format(instr_name))
else:
size += 1
instrs.write("%%suff {}_0 %%imm8 {}".format(instr_name, b2))
instrs.write("{}_0".format(instr_name))
return size
@ -721,19 +646,13 @@ def parse_instr(line):
instr_args += word
if b2 == 0:
instrs.write("{} {}".format(instr_name, instr_args))
else:
size += 1
instrs.write("%%suff {} %%imm8 {} {}".format(instr_name, b2, instr_args))
instrs.write("{}{}".format(instr_name, instr_args))
return size
#-------------------------------------------------------------------------------
special_syms = {
"%%suff",
"%%imm8",
"%%imm16",
"%%imm32",
@ -749,7 +668,6 @@ def gentext():
data_start += (8 - data_start % 8)
instrs.seek(0)
suff_mask = 0
for _, line in enumerate(instrs):
tok = line.strip().split()
@ -769,9 +687,8 @@ def gentext():
continue
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))
suff_mask = 0
continue
if word in plabels_text:
@ -785,9 +702,7 @@ def gentext():
continue
if word in special_syms:
if word == "%%suff":
suff_mask = 1<<7
elif word == "%%imm8":
if word == "%%imm8":
lastimm = 1
elif word == "%%imm16":
lastimm = 2

View File

@ -1,18 +1,10 @@
$rzx $zero
$cr0
$cr1
$cr2
$rfx
$rip
$rbp
$rsp
$rax $r0
$rbx $r1
$rcx $r2
$rdx $r3
$rsi $r4
$rdi $r5
$ax0 $r6
$ax1 $r7
$ax2 $r8
@ -29,6 +21,19 @@ $nx5 $r17
$nx6 $r18
$nx7 $r19
$nx8 $r20
$grp $r21
$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
;
CHAR_MIN := 0x0000000000000080
SHRT_MIN := 0x0000000000008000
INT_MIN := 0x0000000080000000
CHAR_MIN := 0x80
SHRT_MIN := 0x8000
INT_MIN := 0x80000000
LONG_MIN := 0x8000000000000000
XCHAR_MIN := 0xFFFFFFFFFFFFFF80
XSHRT_MIN := 0xFFFFFFFFFFFF8000
XINT_MIN := 0xFFFFFFFF80000000
CHAR_MAX := 0x000000000000007F
SHRT_MAX := 0x0000000000007FFF
INT_MAX := 0x000000007FFFFFFF
CHAR_MAX := 0x7F
SHRT_MAX := 0x7FFF
INT_MAX := 0x7FFFFFFF
LONG_MAX := 0x7FFFFFFFFFFFFFFF
BYTE_MAX := 0x00000000000000FF
WORD_MAX := 0x000000000000FFFF
LWORD_MAX := 0x00000000FFFFFFFF
BYTE_MAX := 0xFF
WORD_MAX := 0xFFFF
LWORD_MAX := 0xFFFFFFFF
QWORD_MAX := 0xFFFFFFFFFFFFFFFF
FILE_MAXSZ := 0x0000000000008000
STRLEN_MAX := 0x000000007AFFFFFF
FNAME_MAX := 0x0000000000000080
FNAME_MAX := 0x80
FILE_MAXSZ := 0x8000
STRLEN_MAX := 0x7AFFFFFF
;
; Magic numbers
;
PRN_CLEAR := 0x000000008BF00001
PRN_FLUSH := 0x000000008BF00002
PRN_CLEAR := 0x8BF00001
PRN_FLUSH := 0x8BF00002
;
; CRT librairies
;
include "crt/sys.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/str.k"
include "crt/mem.k"
include "crt/time.k"
include "crt/fmt/ltostr.k"
include "crt/fmt/strtol.k"
include "crt/fmt/doprnt.k"
include "crt/fmt/printf.k"
abort:
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 r14, ax3 ; va_list
mov r15, ax1 ; n
mov r16, zero ; return value
mov r17, ax0 ; putc
nul r16 ; return value
.main_loop:
; find '%' or null-terminator
mov rcx, STRLEN_MAX
mov r13, r12
scasb.rep.nz r13, '%'
scasb r13, '%'
; everything below r13 is a regular character; print it
.print_regular:
@ -62,7 +62,7 @@ doprnt:
bzr r13, .nullstring
.print_string:
mov ax0, b[r13]
movzx ax0, b[r13]
bzr ax0, .main_loop
inc r13, 1
@ -107,7 +107,7 @@ doprnt:
inc r14, 8
.print_itoa_buf:
mov ax0, b[r13]
movzx ax0, b[r13]
bzr ax0, .pib_end_loop
inc r13, 1
@ -144,8 +144,9 @@ doprnt:
.epilogue:
mov rax, r16
pop r17, r16, r15
pop r14, r13, r12
pop r17, r16
pop r15, r14
pop r13, r12
leave
ret
@ -170,7 +171,7 @@ doprnt:
jraxz .r
; yes, so artificially set n=0
mov r15, zero
nul r15
.r:
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)
;
utoa:
mov ax3, zero
nul ax3
jmp ltostr
;
@ -20,7 +20,7 @@ utoa:
;
ltostr:
mov rax, ax0
mov rcx, zero
nul rcx
; make sure base is in [2, 32]
bltu ax2, 2, .bad
@ -37,7 +37,7 @@ ltostr:
shr rcx, ax1, 63 ; extract ax1 sign
jrcxz .conv
sub ax1, zero, ax1 ; NEG if negative
neg ax1 ; NEG if negative
; main loop
.conv:
@ -68,7 +68,7 @@ ltostr:
inc ax0, 1
.cxz:
mov b[ax0], zero
nul b[ax0]
call strrev2, rax
ret
@ -77,7 +77,6 @@ ltostr:
; exceptional cases
;
.bad:
mov q[errno], EINVAL
mov b[ax0], 0
ret

View File

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

View File

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

View File

@ -24,7 +24,7 @@ memzero:
jrcxz .r
.l:
mov b[ax0], zero
nul b[ax0]
inc ax0, 1
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)
;
GetTimeUTC:
ytime ax0, ax1, ax2
mov rdx, .buf
ytime
mov rdi, .buf
; seconds
rem rcx, ax0, 60
mov b[rdx], rcx
rem rsi, rax, 60
mov b[rdi], rsi
; minutes
div rcx, ax0, 60
rem rcx, 60
mov b[rdx+1], rcx
div rsi, rax, 60
rem rsi, 60
mov b[rdi+1], rsi
; hours
div rcx, ax0, 3600
rem rcx, 24
mov b[rdx+2], rcx
div rsi, rax, 3600
rem rsi, 24
mov b[rdi+2], rsi
; month days
div rcx, ax0, 3600*24
mov b[rdx+3], rcx
div rsi, rax, 3600*24
mov b[rdi+3], rsi
; month
mov b[rdx+4], ax1
mov b[rdi+4], rbx
; years
mov w[rdx+6], ax2
mov w[rdi+6], rcx
;
; ydays (TODO)

View File

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

View File

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

View File

@ -9,18 +9,12 @@ dumprf:
mov r12, ax0
mov r13, rsp
call RFS.LoadReg, r12, $cr2
push rax
call RFS.LoadReg, r12, $cr1
push rax
call RFS.LoadReg, r12, $cr0
push rax
call RFS.LoadReg, r12, $rfx
push rax
call RFS.LoadReg, r12, $rip
push rax
@ -33,7 +27,7 @@ dumprf:
call RFS.LoadReg, r12, $trp
push rax
push 0 # fixme
push zero # fixme
call RFS.LoadReg, r12, $rbp
push rax
@ -120,7 +114,7 @@ dumprf:
leave
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"
.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"

View File

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

View File

@ -18,7 +18,7 @@ DefaultExceptionHandler:
.err_ukn = "Unknown exception number\0\0\0\0\0\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_sys = "Supervisor-only exception used\0"
.err_dbf = "Double fault exception~~~~~~~~\0"

View File

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

View File

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

View File

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

View File

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

102
vm/in/ALU
View File

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

View File

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

View File

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

View File

@ -8,24 +8,18 @@
#
# Scan string for a particular value (SCASx)
#
# CMP([%1], $2)
# WHILE RCX > 0 DO
# RCX = RCX - 1
#
# IF ([%1] == 0) THEN
# ZF = 1
# ELIF (ZF == 0) THEN
# IF (DF == 0) THEN
# %1 = %1 + sizeof(x)
# ELSE
# %1 = %1 - sizeof(x)
# FI
# IF ([%1] == 0) OR ([%1] == $2) THEN
# BREAK
# ELSE
# %1 = %1 + sizeof(x)
# 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:
# - Does not move past the value when found
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
# Note: Does not move past the value when found
#
scasb 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(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(not, 1) { SRCP(p1); *r1 = ~p1->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(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(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(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(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(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, 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, 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);
p2->val += !!(R(RFX)&CF);
COMPARE_ADD(p1->val, p2->val);
*r1 = p1->val + p2->val;
ulong rs = 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;
}
IMPL_START(adcx, 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) {
IMPL_START(subv, 3) {
SRCP(p1); SRCP(p2);
p2->val += !!(R(RFX)&CF);
COMPARE_SUB(p1->val, p2->val);
*r1 = p1->val - p2->val;
ulong rs = p2->val - p3->val;
return 1;
}
IMPL_START(sbbx, 3) {
SRCP(p2); SRCP(p3);
p3->val += !!(R(RFX)&CF);
COMPARE_SUB(p2->val, p3->val);
*r1 = p2->val - p3->val;
if (((p2->val ^ rs) & (p2->val ^ p3->val)) >> 63)
_except(E_OVF, "Signed substraction underflow (SUBV#3)");
*r1 = rs;
return 1;
}

View File

@ -54,7 +54,7 @@ def parse_2(fp):
.format(deprecated, tok[0], n, tok[0], n))
hd.write("#else\n")
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))
hd.write("#endif\n\n")

View File

@ -7,7 +7,7 @@
#define IMPL_START(name, n) \
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) \
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() \
do { \
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(jrcxnz, 1) { if (R(RCX)) R(RIP) = p1->val; return 0; }
//----------------------------------------------------------------------------//
IMPL_START(loop, 1) {
if (R(RCX) > 0) {
R(RCX)--;
@ -21,6 +23,17 @@ IMPL_START(loop, 1) {
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(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; }
@ -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(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(mov, 2) { XSRCP(*r1, p2, sx); 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(movsxw, 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(movb, 2) { SRCP(p2); *r1 = (ulong)(long)(char)p2->val; return 1; }
IMPL_START(movw, 2) { SRCP(p2); *r1 = (ulong)(long)(short)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)
{
@ -64,6 +68,12 @@ IMPL_START(push, 3)
//----------------------------------------------------------------------------//
IMPL_START(pop, 0)
{
R(RSP) += 8;
return 0;
}
IMPL_START(pop, 1)
{
*r1 = readmemzx(R(RSP), 8);
@ -81,16 +91,6 @@ IMPL_START(pop, 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)
@ -144,6 +144,14 @@ IMPL_START(ret, 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)

View File

@ -9,7 +9,6 @@
//----------------------------------------------------------------------------//
IMPL_START(into, 0) { INTO(); return 0; }
IMPL_START(pause, 0) { usleep(5000); return 0; }
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);
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;
#endif
@ -44,19 +43,19 @@ IMPL_START(dump, 0)
//----------------------------------------------------------------------------//
IMPL_START(ytime, 3)
IMPL_START(ytime, 0)
{
time_t t = time(NULL);
struct tm *tm = localtime(&t);
*r1 = tm->tm_sec + tm->tm_min * 60
+ tm->tm_hour * 60 * 60
+ tm->tm_mday * 60 * 60 * 24;
R(RAX) = tm->tm_sec + tm->tm_min * 60
+ tm->tm_hour * 60 * 60
+ tm->tm_mday * 60 * 60 * 24;
*r2 = tm->tm_mon;
*r3 = tm->tm_year + 1900;
R(RBX) = tm->tm_mon;
R(RCX) = tm->tm_year + 1900;
return 3;
return 0;
}
IMPL_START(utime, 1)
@ -72,7 +71,6 @@ IMPL_START(utime, 1)
IMPL_START(cls, 0)
{
R(RFX) = 0;
for (int i = RAX; i <= R20; i++) R(i) = 0;
return 0;
@ -148,6 +146,8 @@ IMPL_START(prn, 1)
break;
default:
trace("PRN bad magic: %lx\n", v);
die(1);
_except(E_ILL, "Bad PRN magic");
}
}
@ -158,28 +158,6 @@ IMPL_START(prn, 1)
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)
{
*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)
{
if (p1->type != A_REG)
_except(E_ILL, "SCASX given a non-REG operand");
ulong x = readmemsx(R(p1->reg), len);
COMPARE_SUB(x, p2->val);
while (R(RCX) > 0)
{
ulong x = readmemzx(R(p1->reg), len);
if (x == 0) {
R(RFX) |= ZF;
}
if (x == 0 || x == p2->val)
break;
else if (!(R(RFX)&ZF)) {
STR_MOVE(p1->reg, len);
R(p1->reg) += len;
R(RCX)--;
}
}

View File

@ -3,11 +3,7 @@
Instruction encoding:
Byte 1: Instruction number
Byte 2:
xx0xxxxx
|| └───┘
RL CND
Byte: Instruction number
Values for ModRMs:
000xxxxx xxxxx = reg
@ -24,19 +20,3 @@ Values for ModRMs:
11100100 imm32 (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 ni_thisfr; // this frame
// Last COND field
uint cond;
// Dumpinstr switch
bool dumpsw;
};

View File

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

View File

@ -5,53 +5,15 @@
#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);
void dump_instr(instr_t *in,
acc_t *p1,
acc_t *p2,
acc_t *p3,
bool lock,
bool rep)
acc_t *p3)
{
uint cond = ctx->cond;
trace("0x%lX:\t", ctx->cur_pc);
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");
trace("%s\t", in->name);
if (p1)
dump_acc(p1);

View File

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

View File

@ -3,41 +3,6 @@
#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) { \
if (p->type == A_REG) \
R(p->reg) = r; \
@ -52,54 +17,26 @@ bool eval_cond(uint cond)
void exec_instr(instr_t *in,
acc_t *p1,
acc_t *p2,
acc_t *p3,
bool lock,
bool rep)
acc_t *p3)
{
uint out;
ulong r1 = 0, r2 = 0, r3 = 0;
ulong r1 = 0, r2 = 0;
// Global instruction counter
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)
dump_instr(in, p1, p2, p3, lock, rep);
dump_instr(in, p1, p2, p3);
do_rep:
out = in->func(p1, p2, p3, &r1, &r2, &r3);
out = in->func(p1, p2, p3, &r1, &r2);
if (out)
{
OUTPUT(p1, r1);
if (out >= 2) OUTPUT(p2, r2);
if (out >= 3) OUTPUT(p3, r3);
if (__builtin_expect(out == 2, 0))
OUTPUT(p2, r2);
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() \
ulong real = addr2real(addr + R(CR2))
ulong real = addr2real(addr + R(CR1))
//----------------------------------------------------------------------------//

View File

@ -5,9 +5,6 @@
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 },
{ "rsi", GPR }, { "rdi", GPR }, { "ax0", GPR }, { "ax1", 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 },
{ "r16", GPR }, { "r17", GPR }, { "r18", GPR }, { "r19", GPR },
{ "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, "");
@ -26,8 +26,8 @@ void dumpregs()
TRACE("Current RFRAME index: #%lu", rfs_current_idx);
TRACE("\n\nEnviron #1:");
TRACE("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", ctx->cur_pc, R(RIP), R(RFX));
TRACE("\ncr0=0x%-16lX cr1=0x%-16lX cr2=0x%-16lX", R(CR0), R(CR1), R(CR2));
TRACE("\nrpc=0x%-16lX rip=0x%-16lX", ctx->cur_pc, R(RIP));
TRACE("\ncr0=0x%-16lX cr1=0x%-16lX", R(CR0), R(CR1));
TRACE("\n\nEnviron #2:");
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
{
RZX, CR0, CR1, CR2, RFX, RIP, RBP, RSP,
RAX, RBX, RCX, RDX, RSI, RDI, AX0, AX1,
AX2, AX3, AX4, AX5, R12, R13, R14, R15,
R16, R17, R18, R19, R20, GRP, TRP, SRP,
TMP, RAD, CR0, CR1, RIP, RBP, RSP, RZX,
NREGS
};

View File

@ -18,9 +18,9 @@ int create_symtab(const char *name)
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)
{
@ -38,7 +38,6 @@ int create_symtab(const char *name)
}
fclose(tab);
return 0;
}

View File

@ -1,7 +1,7 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#define SYMLEN_MAX 32
#define SYMLEN_MAX 46
#define SYMTAB_LEN 4096
typedef struct sym_t sym_t;
@ -9,7 +9,7 @@ typedef struct sym_t sym_t;
struct sym_t
{
ulong addr;
char name[SYMLEN_MAX];
char name[SYMLEN_MAX+1];
};
extern sym_t symtab[SYMTAB_LEN];