mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
instrs
This commit is contained in:
parent
1cd5286440
commit
1b5b90fa37
78
as/k-as.py
78
as/k-as.py
@ -16,7 +16,7 @@ from collections import OrderedDict
|
|||||||
WANT_DISASM = False
|
WANT_DISASM = False
|
||||||
|
|
||||||
if len(sys.argv) != 5:
|
if len(sys.argv) != 5:
|
||||||
print("Usage: {} (output file) (memory entry point) (source file) (symbols file)"
|
print("Usage: {} (source file) (memory entry point) (output file) (symbols file)"
|
||||||
.format(sys.argv[0]))
|
.format(sys.argv[0]))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ start_addr = int(sys.argv[2], base=0)
|
|||||||
|
|
||||||
# os.chdir(os.path.dirname(sys.argv[1]))
|
# os.chdir(os.path.dirname(sys.argv[1]))
|
||||||
|
|
||||||
def leave():
|
def leave(i):
|
||||||
source.close()
|
source.close()
|
||||||
instrs.close()
|
instrs.close()
|
||||||
b_out.close()
|
b_out.close()
|
||||||
@ -46,6 +46,7 @@ def leave():
|
|||||||
main_src.close()
|
main_src.close()
|
||||||
lst_regs.close()
|
lst_regs.close()
|
||||||
lst_instrs.close()
|
lst_instrs.close()
|
||||||
|
sys.exit(i)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -71,6 +72,9 @@ ptext = 0
|
|||||||
# for local labels
|
# for local labels
|
||||||
plastlabel = ''
|
plastlabel = ''
|
||||||
|
|
||||||
|
# file currently being parsed
|
||||||
|
pcurfile = sys.argv[1]
|
||||||
|
|
||||||
# after parse() is done, pdata and ptext are never modified
|
# after parse() is done, pdata and ptext are never modified
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@ -125,6 +129,7 @@ inc_depth_max = 16
|
|||||||
# Quickly goes through source file and resolves "include" directives ONLY
|
# Quickly goes through source file and resolves "include" directives ONLY
|
||||||
def do_includes(fi):
|
def do_includes(fi):
|
||||||
global inc_depth
|
global inc_depth
|
||||||
|
|
||||||
for _, line in enumerate(fi):
|
for _, line in enumerate(fi):
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
tok = line.split(None, 1)
|
tok = line.split(None, 1)
|
||||||
@ -135,13 +140,11 @@ def do_includes(fi):
|
|||||||
if tok[0] == "include":
|
if tok[0] == "include":
|
||||||
if len(tok) == 1:
|
if len(tok) == 1:
|
||||||
print("Missing parameter for include directive")
|
print("Missing parameter for include directive")
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if tok[1][0] not in "'\"" or tok[1][-1] != tok[1][0]:
|
if tok[1][0] not in "'\"" or tok[1][-1] != tok[1][0]:
|
||||||
print("Invalid format for include directive: {}".format(line))
|
print("Invalid format for include directive: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
inc = tok[1][1:-1]
|
inc = tok[1][1:-1]
|
||||||
|
|
||||||
@ -150,15 +153,14 @@ def do_includes(fi):
|
|||||||
|
|
||||||
except:
|
except:
|
||||||
print("Couldn't open file: {}".format(line))
|
print("Couldn't open file: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
inc_depth += 1
|
inc_depth += 1
|
||||||
if inc_depth >= inc_depth_max:
|
if inc_depth >= inc_depth_max:
|
||||||
print("Maximal include depth reached: {}".format(line))
|
print("Maximal include depth reached: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
source.write("$file: {}:\n".format(inc.replace(' ', '')))
|
||||||
do_includes(new_fi)
|
do_includes(new_fi)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -171,16 +173,22 @@ def do_includes(fi):
|
|||||||
|
|
||||||
def parse():
|
def parse():
|
||||||
global ptext
|
global ptext
|
||||||
|
global pcurfile
|
||||||
global plastlabel
|
global plastlabel
|
||||||
|
|
||||||
source.seek(0)
|
source.seek(0)
|
||||||
|
|
||||||
for count, line in enumerate(source):
|
for ln_no, line in enumerate(source):
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
|
|
||||||
if len(line) == 0:
|
if len(line) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# len("$file: ") == 7
|
||||||
|
if len(line) > 7 and line[:7] == "$file: ":
|
||||||
|
pcurfile = line[7:]
|
||||||
|
continue
|
||||||
|
|
||||||
quote = False
|
quote = False
|
||||||
for i in range(len(line)):
|
for i in range(len(line)):
|
||||||
if line[i] in "'\"":
|
if line[i] in "'\"":
|
||||||
@ -192,15 +200,14 @@ def parse():
|
|||||||
|
|
||||||
if quote:
|
if quote:
|
||||||
print("Unterminated string in line: {}".format(line))
|
print("Unterminated string in line: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if len(line) == 0:
|
if len(line) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if line[0] == ' ' or line[0] == '\t':
|
if line[0] == ' ' or line[0] == '\t':
|
||||||
line = line.lstrip()
|
line = line.lstrip()
|
||||||
instrs.write(hex(ptext + start_addr) + ' ')
|
instrs.write(pcurfile + ' ')
|
||||||
ptext += parse_instr(line)
|
ptext += parse_instr(line)
|
||||||
instrs.write("\n")
|
instrs.write("\n")
|
||||||
|
|
||||||
@ -217,8 +224,7 @@ def parse():
|
|||||||
plabels_text[label] = ptext
|
plabels_text[label] = ptext
|
||||||
else:
|
else:
|
||||||
print("Bad label name: {}".format(line[:-1]))
|
print("Bad label name: {}".format(line[:-1]))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Preprocessor, .data, or invalid
|
# Preprocessor, .data, or invalid
|
||||||
@ -246,8 +252,7 @@ def parse_preproc(line):
|
|||||||
if len(tok) > 1 and tok[1] == ':=':
|
if len(tok) > 1 and tok[1] == ':=':
|
||||||
if len(tok) < 3:
|
if len(tok) < 3:
|
||||||
print("Invalid format: {}".format(line))
|
print("Invalid format: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
s = tok[0]
|
s = tok[0]
|
||||||
if s in pdefs:
|
if s in pdefs:
|
||||||
@ -263,8 +268,7 @@ def parse_preproc(line):
|
|||||||
if len(tok) > 1 and tok[1] == '=':
|
if len(tok) > 1 and tok[1] == '=':
|
||||||
if len(tok) < 3:
|
if len(tok) < 3:
|
||||||
print("Invalid format: {}".format(line))
|
print("Invalid format: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
label = tok[0]
|
label = tok[0]
|
||||||
if label[0] == '.':
|
if label[0] == '.':
|
||||||
@ -292,8 +296,7 @@ def parse_preproc(line):
|
|||||||
|
|
||||||
if not is_number(s):
|
if not is_number(s):
|
||||||
print("Invalid bss format: {}".format(line))
|
print("Invalid bss format: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
i = int(s, base=0)
|
i = int(s, base=0)
|
||||||
|
|
||||||
@ -329,8 +332,7 @@ def parse_preproc(line):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
print("Unrecognized escape sequence: {}".format(line))
|
print("Unrecognized escape sequence: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
b_data.write(ord(c).to_bytes(1, byteorder='little', signed=False))
|
b_data.write(ord(c).to_bytes(1, byteorder='little', signed=False))
|
||||||
real_len += 1
|
real_len += 1
|
||||||
@ -351,14 +353,12 @@ def parse_preproc(line):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
print("Invalid format: {}".format(line))
|
print("Invalid format: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
print("Unrecognized directive: {}".format(line))
|
print("Unrecognized directive: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -390,8 +390,7 @@ def get_cond_mask(cond, line):
|
|||||||
|
|
||||||
if cond not in pconds:
|
if cond not in pconds:
|
||||||
print("Invalid condition suffix: {}".format(line))
|
print("Invalid condition suffix: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
return (mask | pconds[cond])
|
return (mask | pconds[cond])
|
||||||
|
|
||||||
@ -507,8 +506,7 @@ def parse_instr(line):
|
|||||||
|
|
||||||
if len(word) == 0:
|
if len(word) == 0:
|
||||||
print("Wrong syntax in line: '{}'".format(line))
|
print("Wrong syntax in line: '{}'".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
# local labels
|
# local labels
|
||||||
if word[0] == '.':
|
if word[0] == '.':
|
||||||
@ -529,8 +527,7 @@ def parse_instr(line):
|
|||||||
gotPref = True
|
gotPref = True
|
||||||
else:
|
else:
|
||||||
print("Bad memory length prefix: {}".format(line))
|
print("Bad memory length prefix: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
word = word[1:].strip()
|
word = word[1:].strip()
|
||||||
assert(word[0] == '[')
|
assert(word[0] == '[')
|
||||||
@ -552,8 +549,7 @@ def parse_instr(line):
|
|||||||
#
|
#
|
||||||
if not gotPref:
|
if not gotPref:
|
||||||
print("Missing access length modifier: {}".format(line))
|
print("Missing access length modifier: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
instr_name += "_m"
|
instr_name += "_m"
|
||||||
|
|
||||||
@ -793,8 +789,7 @@ def gentext():
|
|||||||
if ':' in word:
|
if ':' in word:
|
||||||
if len(word.split(':')) < 2:
|
if len(word.split(':')) < 2:
|
||||||
print("Stray ':' in line: {}".format(line))
|
print("Stray ':' in line: {}".format(line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
reg2, reg1 = word.split(':', 1)
|
reg2, reg1 = word.split(':', 1)
|
||||||
idx1 = pregs[reg1]
|
idx1 = pregs[reg1]
|
||||||
@ -843,8 +838,7 @@ def gentext():
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
print("Assembly error, unknown token '{}' in line: {}".format(word, line))
|
print("Assembly error, unknown token '{}' in line: {}".format(word, line))
|
||||||
leave()
|
leave(1)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -894,5 +888,5 @@ parse()
|
|||||||
gentext()
|
gentext()
|
||||||
genout()
|
genout()
|
||||||
gensym()
|
gensym()
|
||||||
leave()
|
leave(0)
|
||||||
sys.exit(0)
|
|
||||||
|
@ -27,7 +27,7 @@ ltostr:
|
|||||||
b.a ax2, 36, .bad
|
b.a ax2, 36, .bad
|
||||||
|
|
||||||
; deal with zero
|
; deal with zero
|
||||||
b.e ax1, 0, .zero
|
b.z ax1, 0, .zero
|
||||||
|
|
||||||
; deal with base 10 signedness
|
; deal with base 10 signedness
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ ltostr:
|
|||||||
|
|
||||||
; main loop
|
; main loop
|
||||||
.conv:
|
.conv:
|
||||||
b.e ax1, 0, .fini
|
b.z ax1, 0, .fini
|
||||||
|
|
||||||
rem r10, ax1, ax2 ; ax1 % base
|
rem r10, ax1, ax2 ; ax1 % base
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ ltostr:
|
|||||||
mov b[ax0], r10
|
mov b[ax0], r10
|
||||||
inc ax0
|
inc ax0
|
||||||
|
|
||||||
div ax1, ax2
|
div ax1, ax1, ax2
|
||||||
jmp .conv
|
jmp .conv
|
||||||
|
|
||||||
; add minus flag, null-terminate and reverse
|
; add minus flag, null-terminate and reverse
|
||||||
|
@ -137,7 +137,7 @@ strtoq:
|
|||||||
; too large for base?
|
; too large for base?
|
||||||
b.ae r12, ax1, .done
|
b.ae r12, ax1, .done
|
||||||
|
|
||||||
mul rax, ax1
|
mul rax, rax, ax1
|
||||||
add rax, r12
|
add rax, r12
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ GetTimeUTC:
|
|||||||
|
|
||||||
; minutes
|
; minutes
|
||||||
div rcx, r11, 60
|
div rcx, r11, 60
|
||||||
rem rcx, 60
|
rem rcx, rcx, 60
|
||||||
mov b[rdx+1], rcx
|
mov b[rdx+1], rcx
|
||||||
|
|
||||||
; hours
|
; hours
|
||||||
div rcx, r11, 3600
|
div rcx, r11, 3600
|
||||||
rem rcx, 24
|
rem rcx, rcx, 24
|
||||||
mov b[rdx+2], rcx
|
mov b[rdx+2], rcx
|
||||||
|
|
||||||
; month days
|
; month days
|
||||||
|
@ -1,6 +1,106 @@
|
|||||||
# 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.
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# Logical instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# TEST Comparison instruction
|
||||||
|
#
|
||||||
|
# $1 AND $2
|
||||||
|
#
|
||||||
|
# Clears OF and CF
|
||||||
|
# Sets ZF and SF according to the result
|
||||||
|
#
|
||||||
|
test r ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bitwise NOT operation
|
||||||
|
#
|
||||||
|
# $1 = NOT($2)
|
||||||
|
#
|
||||||
|
# Preserves all flags
|
||||||
|
#
|
||||||
|
not r r
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bitwise OR operation
|
||||||
|
#
|
||||||
|
# $dest = $src1 OR $src2
|
||||||
|
#
|
||||||
|
# Preserves all flags
|
||||||
|
#
|
||||||
|
or r ri
|
||||||
|
or r r ri
|
||||||
|
or m ri
|
||||||
|
or m r ri
|
||||||
|
|
||||||
|
# $dest = $src1 OR NOT($src2)
|
||||||
|
orn r ri
|
||||||
|
orn r r ri
|
||||||
|
|
||||||
|
# $dest = NOT($src1 OR $src2)
|
||||||
|
nor r r ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bitwise AND operation
|
||||||
|
#
|
||||||
|
# $dest = $src1 AND $src2
|
||||||
|
#
|
||||||
|
# Preserves all flags
|
||||||
|
#
|
||||||
|
and r rim
|
||||||
|
and r r rim
|
||||||
|
and m ri
|
||||||
|
and m r ri
|
||||||
|
|
||||||
|
# $dest = $src1 AND NOT($src2)
|
||||||
|
andn r r ri
|
||||||
|
|
||||||
|
# $dest = NOT($src1 AND $src2)
|
||||||
|
nand r r ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bitwise XOR operation
|
||||||
|
#
|
||||||
|
# $dest = $src1 XOR $src2
|
||||||
|
#
|
||||||
|
# Preserves all flags
|
||||||
|
#
|
||||||
|
xor r rim
|
||||||
|
xor r r rim
|
||||||
|
xor m ri
|
||||||
|
xor m r ri
|
||||||
|
|
||||||
|
# $dest = $src1 XOR NOT($src2)
|
||||||
|
xorn r r ri
|
||||||
|
|
||||||
|
# $dest = NOT($src1 XOR $src2)
|
||||||
|
xnor r r ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Logical left/right shift (SHL/SHR)
|
||||||
|
#
|
||||||
|
# $dest = $src1 << $src2 (SHL)
|
||||||
|
# $dest = $src1 >> $src2 (SHR)
|
||||||
|
#
|
||||||
|
# Preserves all flags
|
||||||
|
#
|
||||||
|
shl r r ri
|
||||||
|
shr r r ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Arithmetical left/right shift (SAL/SAR)
|
||||||
|
#
|
||||||
|
# $dest = $src1 <<< $src2 (SAL)
|
||||||
|
# $dest = $src1 >>> $src2 (SAR)
|
||||||
|
#
|
||||||
|
# Preserves all flags
|
||||||
|
#
|
||||||
|
sal r r ri
|
||||||
|
sar r r ri
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Arithmetic instructions #
|
# Arithmetic instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -72,12 +172,10 @@ dec rm
|
|||||||
#
|
#
|
||||||
add r rim
|
add r rim
|
||||||
add r r ri
|
add r r ri
|
||||||
|
|
||||||
add m ri
|
add m ri
|
||||||
add m r ri
|
|
||||||
|
|
||||||
addf r ri
|
|
||||||
addf r r ri
|
addf r r ri
|
||||||
|
addo r r ri
|
||||||
|
|
||||||
#
|
#
|
||||||
# Atomic exchange and add (XADD)
|
# Atomic exchange and add (XADD)
|
||||||
@ -103,15 +201,12 @@ xadd m r
|
|||||||
sub r rim
|
sub r rim
|
||||||
sub r r ri
|
sub r r ri
|
||||||
sub r i r
|
sub r i r
|
||||||
|
|
||||||
sub m ri
|
sub m ri
|
||||||
sub m r ri
|
|
||||||
sub m i r
|
|
||||||
|
|
||||||
subf r ri
|
|
||||||
subf r r ri
|
subf r r ri
|
||||||
subf r i r
|
subf r i r
|
||||||
|
subo r r ri
|
||||||
|
subo r i r
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical ADD/SUB operation, with carry/overflow
|
# Arithmetical ADD/SUB operation, with carry/overflow
|
||||||
@ -124,10 +219,10 @@ subf r i r
|
|||||||
# Preserves ZF and SF
|
# Preserves ZF and SF
|
||||||
# Flags CF and OF are undefined for now
|
# Flags CF and OF are undefined for now
|
||||||
#
|
#
|
||||||
adc r r
|
adcx r r ri
|
||||||
ado r r
|
adox r r ri
|
||||||
sbb r r
|
sbbx r r ri
|
||||||
sbo r r
|
sbox r r ri
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical unsigned MUL operation
|
# Arithmetical unsigned MUL operation
|
||||||
@ -137,9 +232,9 @@ sbo r r
|
|||||||
# Preserves ZF and SF
|
# Preserves ZF and SF
|
||||||
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
|
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
|
||||||
#
|
#
|
||||||
mul r ri
|
|
||||||
mul r r ri
|
mul r r ri
|
||||||
mulf r r ri
|
mulf r r ri
|
||||||
|
mulo r r ri
|
||||||
|
|
||||||
# Arithmetical unsigned MUL operation
|
# Arithmetical unsigned MUL operation
|
||||||
#
|
#
|
||||||
@ -158,9 +253,7 @@ mulhi r r ri
|
|||||||
#
|
#
|
||||||
# Preserves all flags
|
# Preserves all flags
|
||||||
#
|
#
|
||||||
div r ri
|
|
||||||
div r r ri
|
div r r ri
|
||||||
div r i r
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Arithmetical unsigned modulo operation (REM)
|
# Arithmetical unsigned modulo operation (REM)
|
||||||
@ -169,7 +262,5 @@ div r i r
|
|||||||
#
|
#
|
||||||
# Preserves all flags
|
# Preserves all flags
|
||||||
#
|
#
|
||||||
rem r ri
|
|
||||||
rem r r ri
|
rem r r ri
|
||||||
rem r i r
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# Bit manipulation instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
|
|
25
vm/in/DEBUG
25
vm/in/DEBUG
@ -1,25 +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.
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# Debugging instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Breakpoint instruction (BREAK)
|
|
||||||
#
|
|
||||||
# (cause register dump on standard error)
|
|
||||||
# (wait for user input before proceeeding)
|
|
||||||
#
|
|
||||||
break
|
|
||||||
|
|
||||||
#
|
|
||||||
# Enable/disable instruction dumping (DUMP)
|
|
||||||
#
|
|
||||||
# IF $1 == 0 THEN
|
|
||||||
# (disable instruction dumping)
|
|
||||||
# ELSE
|
|
||||||
# (enable instruction dumping)
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
dump ri
|
|
29
vm/in/FLAGS
29
vm/in/FLAGS
@ -1,29 +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.
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# Flag manipulation instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Clear or set interrupt flag (CLI/STI)
|
|
||||||
#
|
|
||||||
# Throws:
|
|
||||||
# #SYS if not in supervisor mode
|
|
||||||
#
|
|
||||||
cli
|
|
||||||
sti
|
|
||||||
|
|
||||||
#
|
|
||||||
# Clear or set direction flag (CLD/STD)
|
|
||||||
#
|
|
||||||
cld
|
|
||||||
std
|
|
||||||
|
|
||||||
#
|
|
||||||
# Complement, clear or set carry flag (CMC/CLC/STC)
|
|
||||||
#
|
|
||||||
cmc
|
|
||||||
clc
|
|
||||||
stc
|
|
||||||
|
|
34
vm/in/INOUT
34
vm/in/INOUT
@ -1,34 +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.
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# I/O instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Send a character to standard output (PRN)
|
|
||||||
#
|
|
||||||
prn rim
|
|
||||||
|
|
||||||
#
|
|
||||||
# Print a string to standard output (PRN)
|
|
||||||
#
|
|
||||||
# COMPARE([%1], 0)
|
|
||||||
#
|
|
||||||
# IF (ZF == 0) THEN
|
|
||||||
# PRN([%1])
|
|
||||||
# IF (DF == 0) THEN
|
|
||||||
# %1 = %1 + 1
|
|
||||||
# ELSE
|
|
||||||
# %1 = %1 - 1
|
|
||||||
# FI
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
#
|
|
||||||
prns r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Scan a character from standard input (SCAN)
|
|
||||||
#
|
|
||||||
scan r
|
|
||||||
|
|
10
vm/in/INSTRS
10
vm/in/INSTRS
@ -2,16 +2,8 @@
|
|||||||
# See the LICENSE file in the project root for more information.
|
# See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
include "SUPER"
|
include "SUPER"
|
||||||
include "TRAP"
|
include "ALU"
|
||||||
include "MOV"
|
include "MOV"
|
||||||
include "MISC"
|
include "MISC"
|
||||||
include "LOGIC"
|
|
||||||
include "ARITH"
|
|
||||||
include "JUMPS"
|
|
||||||
include "STACK"
|
|
||||||
include "FLAGS"
|
|
||||||
include "INOUT"
|
|
||||||
include "BITMP"
|
|
||||||
include "DEBUG"
|
|
||||||
include "STRING"
|
include "STRING"
|
||||||
|
|
||||||
|
43
vm/in/JUMPS
43
vm/in/JUMPS
@ -1,43 +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.
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# Jump instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Jump (JMP) instruction
|
|
||||||
#
|
|
||||||
# RIP = $1
|
|
||||||
#
|
|
||||||
j ri
|
|
||||||
jmp ri
|
|
||||||
|
|
||||||
#
|
|
||||||
# RCX-dependent jump (LOOP) instruction
|
|
||||||
#
|
|
||||||
# IF (RCX > 0) THEN
|
|
||||||
# RCX = RCX - 1
|
|
||||||
# RIP = $1
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
loop ri
|
|
||||||
|
|
||||||
#
|
|
||||||
# Conditional absolute jumps (B)
|
|
||||||
#
|
|
||||||
# COMPARE($1, $2)
|
|
||||||
#
|
|
||||||
# IF (COND) THEN
|
|
||||||
# RIP = $3
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Sets CF, OF, ZF and SF according to the comparison's results
|
|
||||||
#
|
|
||||||
# This instruction is special in that the COND field specified is not evaluated
|
|
||||||
# before the instruction is executed, but after the comparison it effectuates
|
|
||||||
#
|
|
||||||
# Suffixing B with the REP suffix results in undefined behavior
|
|
||||||
#
|
|
||||||
b rm ri ri
|
|
||||||
|
|
108
vm/in/LOGIC
108
vm/in/LOGIC
@ -1,108 +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.
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# Logical instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
|
||||||
# TEST Comparison instruction
|
|
||||||
#
|
|
||||||
# $1 AND $2
|
|
||||||
#
|
|
||||||
# Clears OF and CF
|
|
||||||
# Sets ZF and SF according to the result
|
|
||||||
#
|
|
||||||
test r ri
|
|
||||||
|
|
||||||
#
|
|
||||||
# Bitwise NOT operation
|
|
||||||
#
|
|
||||||
# $1 = NOT($2)
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
not r r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Bitwise OR operation
|
|
||||||
#
|
|
||||||
# $dest = $src1 OR $src2
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
or r ri
|
|
||||||
or r r ri
|
|
||||||
or m ri
|
|
||||||
or m r ri
|
|
||||||
|
|
||||||
# $dest = $src1 OR NOT($src2)
|
|
||||||
orn r ri
|
|
||||||
orn r r ri
|
|
||||||
|
|
||||||
# $dest = NOT($src1 OR $src2)
|
|
||||||
nor r ri
|
|
||||||
nor r r ri
|
|
||||||
|
|
||||||
#
|
|
||||||
# Bitwise AND operation
|
|
||||||
#
|
|
||||||
# $dest = $src1 AND $src2
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
and r rim
|
|
||||||
and r r rim
|
|
||||||
and m ri
|
|
||||||
and m r ri
|
|
||||||
|
|
||||||
# $dest = $src1 AND NOT($src2)
|
|
||||||
andn r ri
|
|
||||||
andn r r ri
|
|
||||||
|
|
||||||
# $dest = NOT($src1 AND $src2)
|
|
||||||
nand r ri
|
|
||||||
nand r r ri
|
|
||||||
|
|
||||||
#
|
|
||||||
# Bitwise XOR operation
|
|
||||||
#
|
|
||||||
# $dest = $src1 XOR $src2
|
|
||||||
#
|
|
||||||
# Preserves all flags
|
|
||||||
#
|
|
||||||
xor r rim
|
|
||||||
xor r r rim
|
|
||||||
xor m ri
|
|
||||||
xor m r ri
|
|
||||||
|
|
||||||
# $dest = $src1 XOR NOT($src2)
|
|
||||||
xorn r ri
|
|
||||||
xorn r r ri
|
|
||||||
|
|
||||||
# $dest = NOT($src1 XOR $src2)
|
|
||||||
xnor r ri
|
|
||||||
xnor r r ri
|
|
||||||
|
|
||||||
# To document
|
|
||||||
|
|
||||||
shl r ri
|
|
||||||
shl r r ri
|
|
||||||
shl m ri
|
|
||||||
shl m r ri
|
|
||||||
|
|
||||||
shr r ri
|
|
||||||
shr r r ri
|
|
||||||
shr m ri
|
|
||||||
shr m r ri
|
|
||||||
|
|
||||||
sal r ri
|
|
||||||
sal r r ri
|
|
||||||
sal m ri
|
|
||||||
sal m r ri
|
|
||||||
|
|
||||||
sar r ri
|
|
||||||
sar r r ri
|
|
||||||
sar m ri
|
|
||||||
sar m r ri
|
|
||||||
|
|
80
vm/in/MISC
80
vm/in/MISC
@ -1,6 +1,29 @@
|
|||||||
# 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.
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# Debugging instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Breakpoint instruction (BREAK)
|
||||||
|
#
|
||||||
|
# (cause register dump on standard error)
|
||||||
|
# (wait for user input before proceeeding)
|
||||||
|
#
|
||||||
|
break
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable/disable instruction dumping (DUMP)
|
||||||
|
#
|
||||||
|
# IF $1 == 0 THEN
|
||||||
|
# (disable instruction dumping)
|
||||||
|
# ELSE
|
||||||
|
# (enable instruction dumping)
|
||||||
|
# FI
|
||||||
|
#
|
||||||
|
dump ri
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Misc. instructions #
|
# Misc. instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -79,6 +102,32 @@ cla
|
|||||||
#
|
#
|
||||||
cln
|
cln
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# Flag manipulation instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clear or set interrupt flag (CLI/STI)
|
||||||
|
#
|
||||||
|
# Throws:
|
||||||
|
# #SYS if not in supervisor mode
|
||||||
|
#
|
||||||
|
cli
|
||||||
|
sti
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clear or set direction flag (CLD/STD)
|
||||||
|
#
|
||||||
|
cld
|
||||||
|
std
|
||||||
|
|
||||||
|
#
|
||||||
|
# Complement, clear or set carry flag (CMC/CLC/STC)
|
||||||
|
#
|
||||||
|
cmc
|
||||||
|
clc
|
||||||
|
stc
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Byte-wise / bit-wise manipulation instructions #
|
# Byte-wise / bit-wise manipulation instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -92,3 +141,34 @@ bswap r r
|
|||||||
wswap r r
|
wswap r r
|
||||||
dswap r r
|
dswap r r
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# I/O instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Send a character to standard output (PRN)
|
||||||
|
#
|
||||||
|
prn rim
|
||||||
|
|
||||||
|
#
|
||||||
|
# Print a string to standard output (PRN)
|
||||||
|
#
|
||||||
|
# COMPARE([%1], 0)
|
||||||
|
#
|
||||||
|
# IF (ZF == 0) THEN
|
||||||
|
# PRN([%1])
|
||||||
|
# IF (DF == 0) THEN
|
||||||
|
# %1 = %1 + 1
|
||||||
|
# ELSE
|
||||||
|
# %1 = %1 - 1
|
||||||
|
# FI
|
||||||
|
# FI
|
||||||
|
#
|
||||||
|
#
|
||||||
|
prns r
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scan a character from standard input (SCAN)
|
||||||
|
#
|
||||||
|
scan r
|
||||||
|
|
||||||
|
107
vm/in/MOV
107
vm/in/MOV
@ -1,6 +1,99 @@
|
|||||||
# 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.
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# Jump instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Jump (JMP) instruction
|
||||||
|
#
|
||||||
|
# RIP = $1
|
||||||
|
#
|
||||||
|
j ri
|
||||||
|
jmp ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# RCX-dependent jump (LOOP) instruction
|
||||||
|
#
|
||||||
|
# IF (RCX > 0) THEN
|
||||||
|
# RCX = RCX - 1
|
||||||
|
# RIP = $1
|
||||||
|
# FI
|
||||||
|
#
|
||||||
|
loop ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Conditional absolute jumps (B)
|
||||||
|
#
|
||||||
|
# COMPARE($1, $2)
|
||||||
|
#
|
||||||
|
# IF (COND) THEN
|
||||||
|
# RIP = $3
|
||||||
|
# FI
|
||||||
|
#
|
||||||
|
# Sets CF, OF, ZF and SF according to the comparison's results
|
||||||
|
#
|
||||||
|
# This instruction is special in that the COND field specified is not evaluated
|
||||||
|
# before the instruction is executed, but after the comparison it effectuates
|
||||||
|
#
|
||||||
|
# Suffixing B with the REP suffix results in undefined behavior
|
||||||
|
#
|
||||||
|
b rm ri ri
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# Stack manipulation instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Unconditional jump with possible return (CALL)
|
||||||
|
#
|
||||||
|
# PUSH(RIP)
|
||||||
|
# JMP(RIP)
|
||||||
|
#
|
||||||
|
call ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Return to caller (RET)
|
||||||
|
#
|
||||||
|
# POP(RIP)
|
||||||
|
#
|
||||||
|
ret
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make new stack frame (ENTER)
|
||||||
|
#
|
||||||
|
# PUSH(RBP)
|
||||||
|
# RBP = RSP
|
||||||
|
# RSP = RSP - $1
|
||||||
|
#
|
||||||
|
enter i
|
||||||
|
|
||||||
|
#
|
||||||
|
# Leave stack frame (LEAVE)
|
||||||
|
#
|
||||||
|
# RSP = RBP
|
||||||
|
# POP(RBP)
|
||||||
|
#
|
||||||
|
leave
|
||||||
|
|
||||||
|
#
|
||||||
|
# PUSH value onto stack
|
||||||
|
#
|
||||||
|
# RSP = RSP - 8
|
||||||
|
# *RSP = $1
|
||||||
|
#
|
||||||
|
push rim
|
||||||
|
|
||||||
|
#
|
||||||
|
# POP value from stack
|
||||||
|
#
|
||||||
|
# $1 = *RSP
|
||||||
|
# RSP = RSP + 8
|
||||||
|
#
|
||||||
|
pop r
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Movement instructions #
|
# Movement instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -70,19 +163,9 @@ cmpxchg rm r
|
|||||||
#
|
#
|
||||||
# 3-operand rotation (ROTd)
|
# 3-operand rotation (ROTd)
|
||||||
#
|
#
|
||||||
# $3 -> $2 -> $1 -> $3 (KROTL)
|
# $3 -> $2 -> $1 -> $3 (ROTL)
|
||||||
# $1 -> $2 -> $3 -> $1 (KROTR)
|
# $1 -> $2 -> $3 -> $1 (ROTR)
|
||||||
#
|
#
|
||||||
rotr rm r r
|
rotr rm r r
|
||||||
rotl rm r r
|
rotl rm r r
|
||||||
|
|
||||||
#
|
|
||||||
# Load argument #N (LDARG)
|
|
||||||
#
|
|
||||||
# $1 = AX$2
|
|
||||||
#
|
|
||||||
# Throws:
|
|
||||||
# #ILL if $2 ≥ 16
|
|
||||||
#
|
|
||||||
ldarg r r
|
|
||||||
|
|
||||||
|
55
vm/in/STACK
55
vm/in/STACK
@ -1,55 +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.
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# Stack manipulation instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Unconditional jump with possible return (CALL)
|
|
||||||
#
|
|
||||||
# PUSH(RIP)
|
|
||||||
# JMP(RIP)
|
|
||||||
#
|
|
||||||
call ri
|
|
||||||
|
|
||||||
#
|
|
||||||
# Return to caller (RET)
|
|
||||||
#
|
|
||||||
# POP(RIP)
|
|
||||||
#
|
|
||||||
ret
|
|
||||||
|
|
||||||
#
|
|
||||||
# Make new stack frame (ENTER)
|
|
||||||
#
|
|
||||||
# PUSH(RBP)
|
|
||||||
# RBP = RSP
|
|
||||||
# RSP = RSP - $1
|
|
||||||
#
|
|
||||||
enter i
|
|
||||||
|
|
||||||
#
|
|
||||||
# Leave stack frame (LEAVE)
|
|
||||||
#
|
|
||||||
# RSP = RBP
|
|
||||||
# POP(RBP)
|
|
||||||
#
|
|
||||||
leave
|
|
||||||
|
|
||||||
#
|
|
||||||
# PUSH value onto stack
|
|
||||||
#
|
|
||||||
# RSP = RSP - 8
|
|
||||||
# *RSP = $1
|
|
||||||
#
|
|
||||||
push rim
|
|
||||||
|
|
||||||
#
|
|
||||||
# POP value from stack
|
|
||||||
#
|
|
||||||
# $1 = *RSP
|
|
||||||
# RSP = RSP + 8
|
|
||||||
#
|
|
||||||
pop r
|
|
||||||
|
|
35
vm/in/SUPER
35
vm/in/SUPER
@ -32,13 +32,44 @@ stop
|
|||||||
#
|
#
|
||||||
# Halt the processor until next E/I (HLT)
|
# Halt the processor until next E/I (HLT)
|
||||||
#
|
#
|
||||||
|
# Throws:
|
||||||
|
# #SYS if not in supervisor mode
|
||||||
|
#
|
||||||
hlt
|
hlt
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# E/I handling instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Trap into exception handler (TRAP)
|
||||||
|
#
|
||||||
|
# Throw:
|
||||||
|
# #ILL if $1 > 255
|
||||||
|
# #($1+256) otherwise
|
||||||
|
#
|
||||||
|
trap ri
|
||||||
|
|
||||||
|
#
|
||||||
|
# Return from exception/interrupt (IRET)
|
||||||
|
#
|
||||||
|
# Throws:
|
||||||
|
# #SYS if not in supervisor mode
|
||||||
|
#
|
||||||
|
iret
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# Device control instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Call an architecture-reserved function slot of device (DEVCTL)
|
# Call an architecture-reserved function slot of device (DEVCTL)
|
||||||
#
|
#
|
||||||
# See dv/DEVAPI
|
# See dv/DEVAPI
|
||||||
#
|
#
|
||||||
|
# Throws:
|
||||||
|
# #SYS if not in supervisor mode
|
||||||
|
#
|
||||||
devctl ri ri
|
devctl ri ri
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -46,4 +77,8 @@ devctl ri ri
|
|||||||
#
|
#
|
||||||
# See dv/DEVAPI
|
# See dv/DEVAPI
|
||||||
#
|
#
|
||||||
|
# Throws:
|
||||||
|
# #SYS if not in supervisor mode
|
||||||
|
#
|
||||||
iocall ri ri
|
iocall ri ri
|
||||||
|
|
||||||
|
20
vm/in/TRAP
20
vm/in/TRAP
@ -1,20 +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.
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
# E/I handling instructions #
|
|
||||||
#---------------------------------------------------------------------------#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Trap into exception handler (TRAP)
|
|
||||||
#
|
|
||||||
# Throw:
|
|
||||||
# #ILL if $1 > 255
|
|
||||||
# #($1+256) otherwise
|
|
||||||
#
|
|
||||||
trap ri
|
|
||||||
|
|
||||||
#
|
|
||||||
# Return from exception/interrupt (IRET)
|
|
||||||
#
|
|
||||||
iret
|
|
114
vm/in/alu.c
Normal file
114
vm/in/alu.c
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// 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 <in/instrs.h>
|
||||||
|
|
||||||
|
#define _NEED_ARCH_I
|
||||||
|
#include <in/arch_i.h>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_2(not) { v1 = ~v2; } IMPL_OUT;
|
||||||
|
IMPL_START_2(test) { rfx &= ~(CF|OF); SET_ZSF(v1 & v2); } IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_2(or) { ALU_GET_SRCS(); v1 = src1 | src2; } IMPL_OUT;
|
||||||
|
IMPL_START_2(and) { ALU_GET_SRCS(); v1 = src1 & src2; } IMPL_OUT;
|
||||||
|
IMPL_START_2(xor) { ALU_GET_SRCS(); v1 = src1 ^ src2; } IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_3(orn) { v1 = v2 | ~v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(nor) { v1 = ~(v2 | v3); } IMPL_OUT;
|
||||||
|
IMPL_START_3(andn) { v1 = v2 & ~v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(nand) { v1 = ~(v2 & v3); } IMPL_OUT;
|
||||||
|
IMPL_START_3(xorn) { v1 = v2 ^ ~v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(xnor) { v1 = ~(v2 ^ v3); } IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_3(shl) { v1 = v2 << v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(shr) { v1 = v2 >> v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(sal) { v1 = (ulong)((long)v2 << (long)v3); } IMPL_OUT;
|
||||||
|
IMPL_START_3(sar) { v1 = (ulong)((long)v2 >> (long)v3); } IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_2(sgn) { v1 = (!v2 ? 0: ((long)v2 < 0 ? (ulong)-1L : 1)); } IMPL_OUT;
|
||||||
|
IMPL_START_2(neg) { v1 = ~v2 + 1; } IMPL_OUT;
|
||||||
|
IMPL_START_1(inc) { v1++; } IMPL_OUT;
|
||||||
|
IMPL_START_1(dec) { v1--; } IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_2(add) { ALU_GET_SRCS(); v1 = src1 + src2; } IMPL_OUT;
|
||||||
|
IMPL_START_2(xadd) { ulong tmp = v1; v1 += v2; v2 = tmp; } IMPL_OUT_2;
|
||||||
|
IMPL_START_3(addf) { COMPARE(v2, ~v3+1); v1 = v2 + v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(addo) { COMPARE(v2, ~v3+1); v1 = v2 + v3; INTO(); } IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_2(cmp) { COMPARE(v1, v2); } IMPL_END;
|
||||||
|
IMPL_START_2(sub) { ALU_GET_SRCS(); v1 = src1 - src2; } IMPL_OUT;
|
||||||
|
IMPL_START_3(subf){ COMPARE(v2, v3); v1 = v2 - v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(subo){ COMPARE(v2, v3); v1 = v2 - v3; INTO(); } IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_3(adcx) { v1 = v2 + v3 + !!(rfx&CF); } IMPL_OUT;
|
||||||
|
IMPL_START_3(adox) { v1 = v2 + v3 + !!(rfx&OF); } IMPL_OUT;
|
||||||
|
IMPL_START_3(sbbx) { v1 = v2 - v3 - !!(rfx&CF); } IMPL_OUT;
|
||||||
|
IMPL_START_3(sbox) { v1 = v2 - v3 - !!(rfx&OF); } IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_3(rem) { v1 = v2 % v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(div) {
|
||||||
|
if (!v3)
|
||||||
|
_except(ctx, E_DIV, "DIV by 0");
|
||||||
|
v1 = v2 / v3;
|
||||||
|
} IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
|
||||||
|
//
|
||||||
|
static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||||
|
{
|
||||||
|
ulong u1 = (u & 0xffffffff);
|
||||||
|
ulong v1 = (v & 0xffffffff);
|
||||||
|
ulong t = (u1 * v1);
|
||||||
|
ulong w3 = (t & 0xffffffff);
|
||||||
|
ulong k = (t >> 32);
|
||||||
|
|
||||||
|
u >>= 32;
|
||||||
|
t = (u * v1) + k;
|
||||||
|
k = (t & 0xffffffff);
|
||||||
|
ulong w1 = (t >> 32);
|
||||||
|
|
||||||
|
v >>= 32;
|
||||||
|
t = (u1 * v) + k;
|
||||||
|
k = (t >> 32);
|
||||||
|
|
||||||
|
if (hi) *hi = (u * v) + w1 + k;
|
||||||
|
if (lo) *lo = (t << 32) + w3;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT;
|
||||||
|
IMPL_START_3(mulhi) { multiply(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
||||||
|
|
||||||
|
IMPL_START_3(mulf) {
|
||||||
|
ulong tmp;
|
||||||
|
multiply(v2, v3, &tmp, &v1);
|
||||||
|
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
||||||
|
} IMPL_OUT;
|
||||||
|
|
||||||
|
IMPL_START_3(mulo) {
|
||||||
|
ulong tmp;
|
||||||
|
multiply(v2, v3, &tmp, &v1);
|
||||||
|
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
||||||
|
INTO();
|
||||||
|
} IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
#include <in/instrs.h>
|
|
||||||
|
|
||||||
#define _NEED_ARCH_I
|
|
||||||
#include <in/arch_i.h>
|
|
190
vm/in/arith.c
190
vm/in/arith.c
@ -1,190 +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 <in/instrs.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_2(sgn)
|
|
||||||
{
|
|
||||||
v1 = (v2 == 0 ? 0 :
|
|
||||||
((long)v2 < 0 ? (ulong)-1L : 1));
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(neg)
|
|
||||||
{
|
|
||||||
v1 = ~v2 + 1;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_1(inc)
|
|
||||||
{
|
|
||||||
v1++;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_1(dec)
|
|
||||||
{
|
|
||||||
v1--;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_2(add)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
v1 = src1 + src2;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(xadd)
|
|
||||||
{
|
|
||||||
ulong tmp = v1;
|
|
||||||
v1 += v2;
|
|
||||||
v2 = tmp;
|
|
||||||
}
|
|
||||||
IMPL_OUT_2;
|
|
||||||
|
|
||||||
IMPL_START_2(addf)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
COMPARE(src1, ~src2+1);
|
|
||||||
v1 = src1 + src2;
|
|
||||||
}
|
|
||||||
IMPL_OUT_ZSF;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_2(sub)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
v1 = src1 - src2;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(subf)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
COMPARE(src1, src2);
|
|
||||||
v1 = src1 - src2;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//
|
|
||||||
// i_subf but discards result
|
|
||||||
//
|
|
||||||
IMPL_START_2(cmp)
|
|
||||||
{
|
|
||||||
COMPARE(v1, v2);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_2(adc)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
v1 = src1 + src2 + !!(rfx&CF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(ado)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
v1 = src1 + src2 + !!(rfx&OF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(sbb)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
v1 = src1 - src2 - !!(rfx&CF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(sbo)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
v1 = src1 - src2 - !!(rfx&OF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
//
|
|
||||||
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
|
|
||||||
//
|
|
||||||
static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
|
|
||||||
{
|
|
||||||
ulong u1 = (u & 0xffffffff);
|
|
||||||
ulong v1 = (v & 0xffffffff);
|
|
||||||
ulong t = (u1 * v1);
|
|
||||||
ulong w3 = (t & 0xffffffff);
|
|
||||||
ulong k = (t >> 32);
|
|
||||||
|
|
||||||
u >>= 32;
|
|
||||||
t = (u * v1) + k;
|
|
||||||
k = (t & 0xffffffff);
|
|
||||||
ulong w1 = (t >> 32);
|
|
||||||
|
|
||||||
v >>= 32;
|
|
||||||
t = (u1 * v) + k;
|
|
||||||
k = (t >> 32);
|
|
||||||
|
|
||||||
if (hi) *hi = (u * v) + w1 + k;
|
|
||||||
if (lo) *lo = (t << 32) + w3;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPL_START_2(mul)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
multiply(src1, src2, 0, &v1);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(mulhi)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
multiply(src1, src2, &v1, &v2);
|
|
||||||
}
|
|
||||||
IMPL_OUT_2;
|
|
||||||
|
|
||||||
IMPL_START_2(mulf)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
multiply(src1, src2, &v2, &v1);
|
|
||||||
|
|
||||||
if (v2 > 0) {
|
|
||||||
rfx |= CF;
|
|
||||||
rfx |= OF;
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
rfx &= ~CF;
|
|
||||||
rfx &= ~OF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_2(div)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
v1 = src1 / src2;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(rem)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
v1 = src1 % src2;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
@ -1,39 +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 <in/instrs.h>
|
|
||||||
|
|
||||||
extern void do_hlt(ctx_t *ctx);
|
|
||||||
|
|
||||||
IMPL_START_0(break)
|
|
||||||
{
|
|
||||||
trace("\nExecuting BREAK INSTR\n");
|
|
||||||
dumpregs(ctx);
|
|
||||||
|
|
||||||
do_hlt(ctx);
|
|
||||||
|
|
||||||
trace("Resuming execution\n");
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_1(dump)
|
|
||||||
{
|
|
||||||
(void)v1;
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (ctx->dumpsw && !v1)
|
|
||||||
trace("0x%lX:\t...\n", rpc);
|
|
||||||
|
|
||||||
else if (!ctx->dumpsw && v1)
|
|
||||||
dump_instr(ctx, ctx->cur_in, p1, p2, p3, 0, 0);
|
|
||||||
|
|
||||||
ctx->dumpsw = !!v1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(err)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
@ -1,57 +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 <in/instrs.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_0(cli)
|
|
||||||
{
|
|
||||||
CHK_SUPERV();
|
|
||||||
R(CR0) &= ~IF;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(sti)
|
|
||||||
{
|
|
||||||
CHK_SUPERV();
|
|
||||||
R(CR0) |= IF;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_0(cld)
|
|
||||||
{
|
|
||||||
R(RFX) &= ~DF;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(std)
|
|
||||||
{
|
|
||||||
R(RFX) |= DF;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_0(cmc)
|
|
||||||
{
|
|
||||||
R(RFX) = (R(RFX)&CF ? R(RFX)&~CF : R(RFX)|CF);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(clc)
|
|
||||||
{
|
|
||||||
R(RFX) &= ~CF;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(stc)
|
|
||||||
{
|
|
||||||
R(RFX) |= CF;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
@ -1,36 +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.
|
|
||||||
|
|
||||||
#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 SET_ZSPF(v) \
|
|
||||||
SET_ZF(v); \
|
|
||||||
SET_SF(v); \
|
|
||||||
SET_PF(v)
|
|
||||||
|
|
||||||
#define COMPARE(v1, v2) \
|
|
||||||
ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \
|
|
||||||
long _s1 = (long)v1, _s2 = (long)v2; \
|
|
||||||
\
|
|
||||||
if (_u1 < _u2) R(RFX) |= CF; \
|
|
||||||
else R(RFX) &= ~CF; \
|
|
||||||
\
|
|
||||||
if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \
|
|
||||||
|| ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \
|
|
||||||
R(RFX) |= OF; \
|
|
||||||
else R(RFX) &= ~OF; \
|
|
||||||
SET_ZSF(_u1 - _u2);
|
|
||||||
|
|
@ -1,46 +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 <in/instrs.h>
|
|
||||||
#include <pc/console.h>
|
|
||||||
|
|
||||||
IMPL_START_1(prn)
|
|
||||||
{
|
|
||||||
// Magic value? :)
|
|
||||||
if (__builtin_expect(v1 == 0xC15000AF, 0))
|
|
||||||
console_clear(ctx);
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p1->mlen > 1) {
|
|
||||||
trace("prn warning: large access size\n");
|
|
||||||
}
|
|
||||||
console_putc(ctx, (char)v1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IMPL_END
|
|
||||||
|
|
||||||
IMPL_START_0(prns)
|
|
||||||
{
|
|
||||||
uchar ch = readmemzx(ctx, R(p1->reg), 1);
|
|
||||||
|
|
||||||
COMPARE(ch, 0);
|
|
||||||
|
|
||||||
if ((rfx & ZF) == 0)
|
|
||||||
{
|
|
||||||
console_putc(ctx, ch);
|
|
||||||
|
|
||||||
if (rfx & DF)
|
|
||||||
R(p1->reg)--;
|
|
||||||
else
|
|
||||||
R(p1->reg)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IMPL_END
|
|
||||||
|
|
||||||
IMPL_START_1(scan)
|
|
||||||
{
|
|
||||||
v1 = console_scankeybuf(ctx);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
#include <pc/arch.h>
|
#include <pc/arch.h>
|
||||||
|
|
||||||
#include <in/flags.h>
|
|
||||||
#include <in/arch_i.h>
|
#include <in/arch_i.h>
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
@ -37,6 +35,10 @@ uint i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
|
|||||||
IMPL_START_0(name) \
|
IMPL_START_0(name) \
|
||||||
DECV(v1, p1);
|
DECV(v1, p1);
|
||||||
|
|
||||||
|
#define IMPL_START_1_NOIN(name) \
|
||||||
|
IMPL_START_0(name) \
|
||||||
|
ulong v1;
|
||||||
|
|
||||||
#define IMPL_START_2(name) \
|
#define IMPL_START_2(name) \
|
||||||
IMPL_START_1(name) \
|
IMPL_START_1(name) \
|
||||||
DECV(v2, p2);
|
DECV(v2, p2);
|
||||||
@ -80,6 +82,46 @@ IMPL_START_2(name) \
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#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 SET_ZSPF(v) \
|
||||||
|
SET_ZF(v); \
|
||||||
|
SET_SF(v); \
|
||||||
|
SET_PF(v)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define COMPARE(v1, v2) \
|
||||||
|
ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \
|
||||||
|
long _s1 = (long)v1, _s2 = (long)v2; \
|
||||||
|
\
|
||||||
|
if (_u1 < _u2) R(RFX) |= CF; \
|
||||||
|
else R(RFX) &= ~CF; \
|
||||||
|
\
|
||||||
|
if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \
|
||||||
|
|| ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \
|
||||||
|
R(RFX) |= OF; \
|
||||||
|
else R(RFX) &= ~OF; \
|
||||||
|
SET_ZSF(_u1 - _u2);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define INTO() \
|
||||||
|
if (R(RFX) & OF) _except(ctx, E_OVF, "Overflow");
|
||||||
|
|
||||||
#define ALU_GET_SRCS() \
|
#define ALU_GET_SRCS() \
|
||||||
ulong src1, src2; \
|
ulong src1, src2; \
|
||||||
if (p3) { \
|
if (p3) { \
|
||||||
|
@ -1,41 +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 <in/instrs.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_1(j)
|
|
||||||
{
|
|
||||||
R(RIP) = v1;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_1(jmp)
|
|
||||||
{
|
|
||||||
R(RIP) = v1;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_1(loop)
|
|
||||||
{
|
|
||||||
if (R(RCX) > 0) {
|
|
||||||
R(RCX)--;
|
|
||||||
R(RIP) = v1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_3(b)
|
|
||||||
{
|
|
||||||
COMPARE(v1, v2);
|
|
||||||
|
|
||||||
if (eval_cond(ctx, ctx->cond))
|
|
||||||
R(RIP) = v3;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
@ -1,75 +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 <in/instrs.h>
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_2(not)
|
|
||||||
{
|
|
||||||
v1 = ~v2;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(test)
|
|
||||||
{
|
|
||||||
rfx &= ~(CF|OF);
|
|
||||||
SET_ZSF(v1 & v2);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
#define LOGIC_IMPL(name, op) \
|
|
||||||
IMPL_START_2(name) \
|
|
||||||
{ \
|
|
||||||
ALU_GET_SRCS(); \
|
|
||||||
v1 = op; \
|
|
||||||
} \
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
LOGIC_IMPL(and, src1 & src2);
|
|
||||||
LOGIC_IMPL(andn, src1 & ~src2);
|
|
||||||
LOGIC_IMPL(nand, ~(src1 & src2));
|
|
||||||
|
|
||||||
LOGIC_IMPL(or, src1 | src2);
|
|
||||||
LOGIC_IMPL(orn, src1 | ~src2);
|
|
||||||
LOGIC_IMPL(nor, ~(src1 | src2));
|
|
||||||
|
|
||||||
LOGIC_IMPL(xor, src1 ^ src2);
|
|
||||||
LOGIC_IMPL(xorn, src1 ^ ~src2);
|
|
||||||
LOGIC_IMPL(xnor, ~(src1 ^ src2));
|
|
||||||
|
|
||||||
LOGIC_IMPL(shl, src1 << src2);
|
|
||||||
LOGIC_IMPL(shr, src1 >> src2);
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
IMPL_START_2(sal)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
|
|
||||||
long w1 = src1;
|
|
||||||
long w2 = src2;
|
|
||||||
|
|
||||||
w1 <<= w2;
|
|
||||||
|
|
||||||
v1 = (ulong)w1;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(sar)
|
|
||||||
{
|
|
||||||
ALU_GET_SRCS();
|
|
||||||
|
|
||||||
long w1 = src1;
|
|
||||||
long w2 = src2;
|
|
||||||
|
|
||||||
w1 >>= w2;
|
|
||||||
|
|
||||||
v1 = (ulong)w1;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
138
vm/in/misc.c
138
vm/in/misc.c
@ -1,6 +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.
|
||||||
|
|
||||||
|
#include <pc/console.h>
|
||||||
#include <in/instrs.h>
|
#include <in/instrs.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -8,41 +9,45 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_0(nop)
|
IMPL_START_0(nop) {} IMPL_END;
|
||||||
|
IMPL_START_0(cpuid) { rax = rdx = 0; } IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(pause) { usleep(5000); } IMPL_END;
|
||||||
|
IMPL_START_0(xpause) { CHK_SUPERV(); usleep(25000); } IMPL_END;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_0(break)
|
||||||
{
|
{
|
||||||
|
trace("\nExecuting BREAK INSTR\n");
|
||||||
|
dumpregs(ctx);
|
||||||
|
|
||||||
|
do_hlt(ctx);
|
||||||
|
|
||||||
|
trace("Resuming execution\n");
|
||||||
|
}
|
||||||
|
IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_1(dump)
|
||||||
|
{
|
||||||
|
(void)v1;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (ctx->dumpsw && !v1)
|
||||||
|
trace("0x%lX:\t...\n", rpc);
|
||||||
|
|
||||||
|
else if (!ctx->dumpsw && v1)
|
||||||
|
dump_instr(ctx, ctx->cur_in, p1, p2, p3, 0, 0);
|
||||||
|
|
||||||
|
ctx->dumpsw = !!v1;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_0(pause)
|
IMPL_START_1(time) { v1 = time(NULL); } IMPL_OUT;
|
||||||
{
|
|
||||||
usleep(5000);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(xpause)
|
|
||||||
{
|
|
||||||
CHK_SUPERV();
|
|
||||||
usleep(25000);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_0(cpuid)
|
|
||||||
{
|
|
||||||
rax = rdx = 0;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_1(time)
|
|
||||||
{
|
|
||||||
v1 = time(NULL);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_3(ytime)
|
IMPL_START_3(ytime)
|
||||||
{
|
{
|
||||||
@ -68,31 +73,28 @@ IMPL_OUT;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_0(cls)
|
IMPL_START_0(cls) {
|
||||||
{
|
|
||||||
R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
|
R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
|
||||||
for (int i = R10; i <= NX7; i++) R(i) = 0;
|
for (int i = R10; i <= NX7; i++) R(i) = 0;
|
||||||
}
|
} IMPL_END;
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(clr)
|
IMPL_START_0(clr) {
|
||||||
{
|
|
||||||
R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
|
R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
|
||||||
for (int i = R10; i <= R15; i++) R(i) = 0;
|
for (int i = R10; i <= R15; i++) R(i) = 0;
|
||||||
}
|
} IMPL_END;
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cla)
|
IMPL_START_0(cla) { for (int i = AX0; i <= AX7; i++) R(i) = 0; } IMPL_END;
|
||||||
{
|
IMPL_START_0(cln) { for (int i = NX0; i <= NX7; i++) R(i) = 0; } IMPL_END;
|
||||||
for (int i = AX0; i <= AX7; i++) R(i) = 0;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cln)
|
//----------------------------------------------------------------------------//
|
||||||
{
|
|
||||||
for (int i = NX0; i <= NX7; i++) R(i) = 0;
|
IMPL_START_0(cli) { CHK_SUPERV(); R(CR0) &= ~IF; } IMPL_END;
|
||||||
}
|
IMPL_START_0(sti) { CHK_SUPERV(); R(CR0) |= IF; } IMPL_END;
|
||||||
IMPL_END;
|
IMPL_START_0(cld) { R(RFX) &= ~DF; } IMPL_END;
|
||||||
|
IMPL_START_0(clc) { R(RFX) &= ~CF; } IMPL_END;
|
||||||
|
IMPL_START_0(std) { R(RFX) |= DF; } IMPL_END;
|
||||||
|
IMPL_START_0(stc) { R(RFX) |= CF; } IMPL_END;
|
||||||
|
IMPL_START_0(cmc) { R(RFX) = (R(RFX)&CF ? R(RFX)&~CF : R(RFX)|CF); } IMPL_END;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
@ -127,3 +129,45 @@ IMPL_OUT;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_1(prn)
|
||||||
|
{
|
||||||
|
// Magic value? :)
|
||||||
|
if (__builtin_expect(v1 == 0xC15000AF, 0))
|
||||||
|
console_clear(ctx);
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p1->mlen > 1) {
|
||||||
|
trace("prn warning: large access size\n");
|
||||||
|
}
|
||||||
|
console_putc(ctx, (char)v1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IMPL_END
|
||||||
|
|
||||||
|
IMPL_START_0(prns)
|
||||||
|
{
|
||||||
|
uchar ch = readmemzx(ctx, R(p1->reg), 1);
|
||||||
|
|
||||||
|
COMPARE(ch, 0);
|
||||||
|
|
||||||
|
if ((rfx & ZF) == 0)
|
||||||
|
{
|
||||||
|
console_putc(ctx, ch);
|
||||||
|
|
||||||
|
if (rfx & DF)
|
||||||
|
R(p1->reg)--;
|
||||||
|
else
|
||||||
|
R(p1->reg)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IMPL_END
|
||||||
|
|
||||||
|
IMPL_START_1(scan)
|
||||||
|
{
|
||||||
|
v1 = console_scankeybuf(ctx);
|
||||||
|
}
|
||||||
|
IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
151
vm/in/mov.c
151
vm/in/mov.c
@ -3,105 +3,82 @@
|
|||||||
|
|
||||||
#include <in/instrs.h>
|
#include <in/instrs.h>
|
||||||
|
|
||||||
IMPL_START_1(lea)
|
|
||||||
{
|
|
||||||
v1 = p2->addr;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_2_ONLY(mov)
|
IMPL_START_1(j) { R(RIP) = v1; } IMPL_END;
|
||||||
{
|
IMPL_START_1(jmp) { R(RIP) = v1; } IMPL_END;
|
||||||
v1 = v2;
|
IMPL_START_1(loop) {
|
||||||
}
|
if (R(RCX) > 0) {
|
||||||
IMPL_OUT;
|
R(RCX)--;
|
||||||
|
R(RIP) = v1;
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_2_ONLY(movsxb)
|
|
||||||
{
|
|
||||||
v1 = (ulong)(long)(char)(v2 & 0xFF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2_ONLY(movsxw)
|
|
||||||
{
|
|
||||||
v1 = (ulong)(long)(short)(v2 & 0xFFFF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2_ONLY(movsxl)
|
|
||||||
{
|
|
||||||
v1 = (ulong)(long)(int)(v2 & 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_1(movzx)
|
|
||||||
{
|
|
||||||
DECVZX(v2, p2);
|
|
||||||
v1 = v2;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_2(xchg)
|
|
||||||
{
|
|
||||||
ulong t = v1;
|
|
||||||
v1 = v2;
|
|
||||||
v2 = t;
|
|
||||||
}
|
|
||||||
IMPL_OUT_2;
|
|
||||||
|
|
||||||
|
|
||||||
IMPL_START_2(cmpxchg)
|
|
||||||
{
|
|
||||||
if (rax == v1) {
|
|
||||||
rfx |= ZF;
|
|
||||||
v1 = v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
rfx &= ~ZF;
|
|
||||||
rax = v1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IMPL_OUT;
|
IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_3(b) {
|
||||||
|
COMPARE(v1, v2);
|
||||||
|
|
||||||
|
if (eval_cond(ctx, ctx->cond))
|
||||||
|
R(RIP) = v3;
|
||||||
|
}
|
||||||
|
IMPL_END;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_3(rotl)
|
IMPL_START_1_NOIN(lea) { v1 = p2->addr; } IMPL_OUT;
|
||||||
{
|
IMPL_START_2_ONLY(mov) { v1 = v2; } IMPL_OUT;
|
||||||
ulong tmp = v1;
|
|
||||||
v1 = v2;
|
|
||||||
v2 = v3;
|
|
||||||
v3 = tmp;
|
|
||||||
}
|
|
||||||
IMPL_OUT_3;
|
|
||||||
|
|
||||||
IMPL_START_3(rotr)
|
IMPL_START_2_ONLY(movsxb) { v1 = (ulong)(long)(char)(v2 & 0xFF); }IMPL_OUT;
|
||||||
{
|
IMPL_START_2_ONLY(movsxw) { v1 = (ulong)(long)(short)(v2 & 0xFFFF); }IMPL_OUT;
|
||||||
ulong tmp = v3;
|
IMPL_START_2_ONLY(movsxl) { v1 = (ulong)(long)(int)(v2 & 0xFFFFFFFF); }IMPL_OUT;
|
||||||
v3 = v2;
|
|
||||||
v2 = v1;
|
IMPL_START_1_NOIN(movzx) { DECVZX(v2, p2); v1 = v2; } IMPL_OUT;
|
||||||
v1 = tmp;
|
|
||||||
}
|
IMPL_START_2(xchg) { ulong t = v1; v1 = v2; v2 = t; } IMPL_OUT_2;
|
||||||
IMPL_OUT_3;
|
IMPL_START_3(rotl) { ulong tmp = v1; v1 = v2; v2 = v3; v3 = tmp; } IMPL_OUT_3;
|
||||||
|
IMPL_START_3(rotr) { ulong tmp = v3; v3 = v2; v2 = v1; v1 = tmp; } IMPL_OUT_3;
|
||||||
|
|
||||||
|
IMPL_START_2(cmpxchg) {
|
||||||
|
if (R(RAX) == v1) { R(RFX) |= ZF; v1 = v2; }
|
||||||
|
else { R(RFX) &= ~ZF; R(RAX) = v1; }
|
||||||
|
} IMPL_OUT;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_2_ONLY(ldarg)
|
//
|
||||||
{
|
// Stack manipulation instructions
|
||||||
if (v2 < 16)
|
//
|
||||||
v1 = R(AX0 + v2);
|
|
||||||
|
|
||||||
else
|
IMPL_START_1(push) {
|
||||||
_except(ctx, E_ILL, "ldarg: value out of range: %lu", v2);
|
R(RSP) -= 8;
|
||||||
}
|
writemem(ctx, v1, R(RSP), 8);
|
||||||
IMPL_OUT;
|
} IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_1(pop) {
|
||||||
|
v1 = readmem(ctx, R(RSP), 8);
|
||||||
|
R(RSP) += 8;
|
||||||
|
} IMPL_OUT;
|
||||||
|
|
||||||
|
IMPL_START_1(call) {
|
||||||
|
R(RSP) -= 8;
|
||||||
|
writemem(ctx, R(RIP), R(RSP), 8);
|
||||||
|
R(RIP) = v1;
|
||||||
|
} IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(ret) {
|
||||||
|
R(RIP) = readmem(ctx, R(RSP), 8); R(RSP) += 8;
|
||||||
|
} IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(enter) {
|
||||||
|
writemem(ctx, R(RBP), R(RSP) - 8, 8);
|
||||||
|
R(RBP) = R(RSP) - 8;
|
||||||
|
R(RSP) -= (p1->val + 1) * 8;
|
||||||
|
} IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(leave) {
|
||||||
|
R(RSP) = R(RBP) + 8;
|
||||||
|
R(RBP) = readmem(ctx, R(RBP), 8);
|
||||||
|
} IMPL_END;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
@ -1,54 +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 <in/instrs.h>
|
|
||||||
|
|
||||||
//
|
|
||||||
// Stack manipulation instructions
|
|
||||||
//
|
|
||||||
|
|
||||||
IMPL_START_1(push)
|
|
||||||
{
|
|
||||||
R(RSP) -= 8;
|
|
||||||
writemem(ctx, v1, R(RSP), 8);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_1(pop)
|
|
||||||
{
|
|
||||||
v1 = readmem(ctx, R(RSP), 8);
|
|
||||||
R(RSP) += 8;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_1(call)
|
|
||||||
{
|
|
||||||
R(RSP) -= 8;
|
|
||||||
writemem(ctx, R(RIP), R(RSP), 8);
|
|
||||||
|
|
||||||
R(RIP) = v1;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(ret)
|
|
||||||
{
|
|
||||||
R(RIP) = readmem(ctx, R(RSP), 8);
|
|
||||||
R(RSP) += 8;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(enter)
|
|
||||||
{
|
|
||||||
writemem(ctx, R(RBP), R(RSP) - 8, 8);
|
|
||||||
R(RBP) = R(RSP) - 8;
|
|
||||||
R(RSP) -= (p1->val + 1) * 8;
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(leave)
|
|
||||||
{
|
|
||||||
R(RSP) = R(RBP) + 8;
|
|
||||||
R(RBP) = readmem(ctx, R(RBP), 8);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
172
vm/in/string.c
172
vm/in/string.c
@ -6,80 +6,36 @@
|
|||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#define STR_MOVE(reg, len) \
|
#define STR_MOVE(reg, len) \
|
||||||
if ((rfx & DF) == 0) \
|
if (!(rfx & DF)) R(reg) += len; \
|
||||||
R(reg) += len; \
|
else R(reg) -= len;
|
||||||
else \
|
|
||||||
R(reg) -= len;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
static void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
static void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||||
{
|
{
|
||||||
DECV(v2, p2);
|
DECV(v2, p2);
|
||||||
|
|
||||||
writemem(ctx, v2, R(p1->reg), len);
|
writemem(ctx, v2, R(p1->reg), len);
|
||||||
|
|
||||||
STR_MOVE(p1->reg, len);
|
STR_MOVE(p1->reg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_0(stosb)
|
IMPL_START_0(stosb) { stos_impl(ctx, p1, p2, 1); } IMPL_END;
|
||||||
{
|
IMPL_START_0(stosw) { stos_impl(ctx, p1, p2, 2); } IMPL_END;
|
||||||
stos_impl(ctx, p1, p2, 1);
|
IMPL_START_0(stosl) { stos_impl(ctx, p1, p2, 4); } IMPL_END;
|
||||||
}
|
IMPL_START_0(stosq) { stos_impl(ctx, p1, p2, 8); } IMPL_END;
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(stosw)
|
|
||||||
{
|
|
||||||
stos_impl(ctx, p1, p2, 2);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(stosl)
|
|
||||||
{
|
|
||||||
stos_impl(ctx, p1, p2, 4);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(stosq)
|
|
||||||
{
|
|
||||||
stos_impl(ctx, p1, p2, 8);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
static void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
static void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||||
{
|
{
|
||||||
R(p1->reg) = readmem(ctx, R(p2->reg), len);
|
R(p1->reg) = readmem(ctx, R(p2->reg), len);
|
||||||
|
|
||||||
R(RFX) = (R(p1->reg) == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
|
R(RFX) = (R(p1->reg) == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
|
||||||
|
|
||||||
STR_MOVE(p2->reg, len);
|
STR_MOVE(p2->reg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_0(lodsb)
|
IMPL_START_0(lodsb) { lods_impl(ctx, p1, p2, 1); } IMPL_END;
|
||||||
{
|
IMPL_START_0(lodsw) { lods_impl(ctx, p1, p2, 2); } IMPL_END;
|
||||||
lods_impl(ctx, p1, p2, 1);
|
IMPL_START_0(lodsl) { lods_impl(ctx, p1, p2, 4); } IMPL_END;
|
||||||
}
|
IMPL_START_0(lodsq) { lods_impl(ctx, p1, p2, 8); } IMPL_END;
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(lodsw)
|
|
||||||
{
|
|
||||||
lods_impl(ctx, p1, p2, 2);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(lodsl)
|
|
||||||
{
|
|
||||||
lods_impl(ctx, p1, p2, 4);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(lodsq)
|
|
||||||
{
|
|
||||||
lods_impl(ctx, p1, p2, 8);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
@ -99,29 +55,10 @@ static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_0(scasb)
|
IMPL_START_0(scasb) { scas_impl(ctx, p1, p2, 1); } IMPL_END;
|
||||||
{
|
IMPL_START_0(scasw) { scas_impl(ctx, p1, p2, 2); } IMPL_END;
|
||||||
scas_impl(ctx, p1, p2, 1);
|
IMPL_START_0(scasl) { scas_impl(ctx, p1, p2, 4); } IMPL_END;
|
||||||
}
|
IMPL_START_0(scasq) { scas_impl(ctx, p1, p2, 8); } IMPL_END;
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(scasw)
|
|
||||||
{
|
|
||||||
scas_impl(ctx, p1, p2, 2);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(scasl)
|
|
||||||
{
|
|
||||||
scas_impl(ctx, p1, p2, 4);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(scasq)
|
|
||||||
{
|
|
||||||
scas_impl(ctx, p1, p2, 8);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
@ -136,29 +73,10 @@ static void cmps_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
|||||||
STR_MOVE(p2->reg, len);
|
STR_MOVE(p2->reg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_0(cmpsb)
|
IMPL_START_0(cmpsb) { cmps_impl(ctx, p1, p2, 1); } IMPL_END;
|
||||||
{
|
IMPL_START_0(cmpsw) { cmps_impl(ctx, p1, p2, 2); } IMPL_END;
|
||||||
cmps_impl(ctx, p1, p2, 1);
|
IMPL_START_0(cmpsl) { cmps_impl(ctx, p1, p2, 4); } IMPL_END;
|
||||||
}
|
IMPL_START_0(cmpsq) { cmps_impl(ctx, p1, p2, 8); } IMPL_END;
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cmpsw)
|
|
||||||
{
|
|
||||||
cmps_impl(ctx, p1, p2, 2);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cmpsl)
|
|
||||||
{
|
|
||||||
cmps_impl(ctx, p1, p2, 4);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cmpsq)
|
|
||||||
{
|
|
||||||
cmps_impl(ctx, p1, p2, 8);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
@ -176,29 +94,10 @@ static void cmpzs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
|||||||
STR_MOVE(p2->reg, len);
|
STR_MOVE(p2->reg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_0(cmpzsb)
|
IMPL_START_0(cmpzsb) { cmpzs_impl(ctx, p1, p2, 1); } IMPL_END;
|
||||||
{
|
IMPL_START_0(cmpzsw) { cmpzs_impl(ctx, p1, p2, 2); } IMPL_END;
|
||||||
cmpzs_impl(ctx, p1, p2, 1);
|
IMPL_START_0(cmpzsl) { cmpzs_impl(ctx, p1, p2, 4); } IMPL_END;
|
||||||
}
|
IMPL_START_0(cmpzsq) { cmpzs_impl(ctx, p1, p2, 8); } IMPL_END;
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cmpzsw)
|
|
||||||
{
|
|
||||||
cmpzs_impl(ctx, p1, p2, 2);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cmpzsl)
|
|
||||||
{
|
|
||||||
cmpzs_impl(ctx, p1, p2, 4);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(cmpzsq)
|
|
||||||
{
|
|
||||||
cmpzs_impl(ctx, p1, p2, 8);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
@ -213,29 +112,10 @@ static void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
|||||||
STR_MOVE(p2->reg, len);
|
STR_MOVE(p2->reg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_0(movsb)
|
IMPL_START_0(movsb) { movs_impl(ctx, p1, p2, 1); } IMPL_END;
|
||||||
{
|
IMPL_START_0(movsw) { movs_impl(ctx, p1, p2, 2); } IMPL_END;
|
||||||
movs_impl(ctx, p1, p2, 1);
|
IMPL_START_0(movsl) { movs_impl(ctx, p1, p2, 4); } IMPL_END;
|
||||||
}
|
IMPL_START_0(movsq) { movs_impl(ctx, p1, p2, 8); } IMPL_END;
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(movsw)
|
|
||||||
{
|
|
||||||
movs_impl(ctx, p1, p2, 2);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(movsl)
|
|
||||||
{
|
|
||||||
movs_impl(ctx, p1, p2, 4);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(movsq)
|
|
||||||
{
|
|
||||||
movs_impl(ctx, p1, p2, 8);
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
@ -6,19 +6,7 @@
|
|||||||
#include <in/instrs.h>
|
#include <in/instrs.h>
|
||||||
#include <pc/console.h>
|
#include <pc/console.h>
|
||||||
|
|
||||||
IMPL_START_0(stop)
|
//----------------------------------------------------------------------------//
|
||||||
{
|
|
||||||
CHK_SUPERV();
|
|
||||||
_except(ctx, E_SHT, "STOP INSTR");
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(crash)
|
|
||||||
{
|
|
||||||
CHK_SUPERV();
|
|
||||||
_except(ctx, 1023, "CRASH instruction");
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
void do_hlt(ctx_t *ctx)
|
void do_hlt(ctx_t *ctx)
|
||||||
{
|
{
|
||||||
@ -41,14 +29,33 @@ void do_hlt(ctx_t *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_0(hlt)
|
//----------------------------------------------------------------------------//
|
||||||
{
|
|
||||||
CHK_SUPERV();
|
|
||||||
|
|
||||||
do_hlt(ctx);
|
IMPL_START_0(hlt) { CHK_SUPERV(); do_hlt(ctx); } IMPL_END;
|
||||||
|
IMPL_START_0(stop) { CHK_SUPERV(); _except(ctx, E_SHT, "STOP INSTR"); } IMPL_END;
|
||||||
|
IMPL_START_0(crash) { CHK_SUPERV(); _except(ctx, 1023, "CRASH instruction"); } IMPL_END;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_1(trap) {
|
||||||
|
if (v1 > 255) _except(ctx, E_ILL, "TRAP number greater than 255");
|
||||||
|
_except(ctx, v1 + 256, "TRAP instruction");
|
||||||
|
} IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(into) { INTO(); } IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(iret) {
|
||||||
|
trace("\nReturning from exception #%ld\n\n", R(R11));
|
||||||
|
|
||||||
|
// should do more checks
|
||||||
|
R(RIP) = R(R13);
|
||||||
|
rfs_current_idx = R(R12);
|
||||||
|
ctx->rf = rfs[R(R12)];
|
||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
//
|
//
|
||||||
// code common to devctl and iocall
|
// code common to devctl and iocall
|
||||||
//
|
//
|
||||||
@ -140,3 +147,5 @@ IMPL_START_2(iocall)
|
|||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
33
vm/in/trap.c
33
vm/in/trap.c
@ -1,33 +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 <in/instrs.h>
|
|
||||||
|
|
||||||
IMPL_START_1(trap)
|
|
||||||
{
|
|
||||||
if (v1 > 255)
|
|
||||||
_except(ctx, E_ILL, "TRAP number greater than 255");
|
|
||||||
|
|
||||||
_except(ctx, v1 + 256, "TRAP instruction");
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
IMPL_START_0(into)
|
|
||||||
{
|
|
||||||
if (R(RFX) & OF)
|
|
||||||
_except(ctx, E_OVF, "INTO instruction with FLG.OF=1");
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
||||||
// XXX more checks
|
|
||||||
|
|
||||||
IMPL_START_0(iret)
|
|
||||||
{
|
|
||||||
trace("\nReturning from exception #%ld\n\n", R(R11));
|
|
||||||
|
|
||||||
R(RIP) = R(R13);
|
|
||||||
rfs_current_idx = R(R12);
|
|
||||||
ctx->rf = rfs[R(R12)];
|
|
||||||
}
|
|
||||||
IMPL_END;
|
|
||||||
|
|
@ -95,6 +95,8 @@ void decode(ctx_t *ctx);
|
|||||||
void enable_stdin_echoing(void);
|
void enable_stdin_echoing(void);
|
||||||
void disable_stdin_echoing(void);
|
void disable_stdin_echoing(void);
|
||||||
|
|
||||||
|
extern void do_hlt(ctx_t *ctx);
|
||||||
|
|
||||||
#include <pc/mem.h>
|
#include <pc/mem.h>
|
||||||
#include <pc/sym.h>
|
#include <pc/sym.h>
|
||||||
#include <pc/regs.h>
|
#include <pc/regs.h>
|
||||||
|
@ -22,6 +22,7 @@ enum
|
|||||||
E_ALI, // Alignment error
|
E_ALI, // Alignment error
|
||||||
E_BRK, // Ctrl+C or similar
|
E_BRK, // Ctrl+C or similar
|
||||||
E_OVF, // INTO instruction
|
E_OVF, // INTO instruction
|
||||||
|
E_DIV, // Division by zero
|
||||||
NEXCPTS
|
NEXCPTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user