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
|
||||
|
||||
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]))
|
||||
sys.exit(1)
|
||||
|
||||
@ -36,7 +36,7 @@ start_addr = int(sys.argv[2], base=0)
|
||||
|
||||
# os.chdir(os.path.dirname(sys.argv[1]))
|
||||
|
||||
def leave():
|
||||
def leave(i):
|
||||
source.close()
|
||||
instrs.close()
|
||||
b_out.close()
|
||||
@ -46,6 +46,7 @@ def leave():
|
||||
main_src.close()
|
||||
lst_regs.close()
|
||||
lst_instrs.close()
|
||||
sys.exit(i)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -71,6 +72,9 @@ ptext = 0
|
||||
# for local labels
|
||||
plastlabel = ''
|
||||
|
||||
# file currently being parsed
|
||||
pcurfile = sys.argv[1]
|
||||
|
||||
# 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
|
||||
def do_includes(fi):
|
||||
global inc_depth
|
||||
|
||||
for _, line in enumerate(fi):
|
||||
line = line.rstrip()
|
||||
tok = line.split(None, 1)
|
||||
@ -135,13 +140,11 @@ def do_includes(fi):
|
||||
if tok[0] == "include":
|
||||
if len(tok) == 1:
|
||||
print("Missing parameter for include directive")
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
if tok[1][0] not in "'\"" or tok[1][-1] != tok[1][0]:
|
||||
print("Invalid format for include directive: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
inc = tok[1][1:-1]
|
||||
|
||||
@ -150,15 +153,14 @@ def do_includes(fi):
|
||||
|
||||
except:
|
||||
print("Couldn't open file: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
inc_depth += 1
|
||||
if inc_depth >= inc_depth_max:
|
||||
print("Maximal include depth reached: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
source.write("$file: {}:\n".format(inc.replace(' ', '')))
|
||||
do_includes(new_fi)
|
||||
|
||||
else:
|
||||
@ -171,16 +173,22 @@ def do_includes(fi):
|
||||
|
||||
def parse():
|
||||
global ptext
|
||||
global pcurfile
|
||||
global plastlabel
|
||||
|
||||
source.seek(0)
|
||||
|
||||
for count, line in enumerate(source):
|
||||
for ln_no, line in enumerate(source):
|
||||
line = line.rstrip()
|
||||
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
||||
# len("$file: ") == 7
|
||||
if len(line) > 7 and line[:7] == "$file: ":
|
||||
pcurfile = line[7:]
|
||||
continue
|
||||
|
||||
quote = False
|
||||
for i in range(len(line)):
|
||||
if line[i] in "'\"":
|
||||
@ -192,15 +200,14 @@ def parse():
|
||||
|
||||
if quote:
|
||||
print("Unterminated string in line: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
||||
if line[0] == ' ' or line[0] == '\t':
|
||||
line = line.lstrip()
|
||||
instrs.write(hex(ptext + start_addr) + ' ')
|
||||
instrs.write(pcurfile + ' ')
|
||||
ptext += parse_instr(line)
|
||||
instrs.write("\n")
|
||||
|
||||
@ -217,8 +224,7 @@ def parse():
|
||||
plabels_text[label] = ptext
|
||||
else:
|
||||
print("Bad label name: {}".format(line[:-1]))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
continue
|
||||
|
||||
# Preprocessor, .data, or invalid
|
||||
@ -246,8 +252,7 @@ def parse_preproc(line):
|
||||
if len(tok) > 1 and tok[1] == ':=':
|
||||
if len(tok) < 3:
|
||||
print("Invalid format: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
s = tok[0]
|
||||
if s in pdefs:
|
||||
@ -263,8 +268,7 @@ def parse_preproc(line):
|
||||
if len(tok) > 1 and tok[1] == '=':
|
||||
if len(tok) < 3:
|
||||
print("Invalid format: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
label = tok[0]
|
||||
if label[0] == '.':
|
||||
@ -292,8 +296,7 @@ def parse_preproc(line):
|
||||
|
||||
if not is_number(s):
|
||||
print("Invalid bss format: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
i = int(s, base=0)
|
||||
|
||||
@ -329,8 +332,7 @@ def parse_preproc(line):
|
||||
|
||||
else:
|
||||
print("Unrecognized escape sequence: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
b_data.write(ord(c).to_bytes(1, byteorder='little', signed=False))
|
||||
real_len += 1
|
||||
@ -351,14 +353,12 @@ def parse_preproc(line):
|
||||
|
||||
else:
|
||||
print("Invalid format: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
return
|
||||
|
||||
print("Unrecognized directive: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -390,8 +390,7 @@ def get_cond_mask(cond, line):
|
||||
|
||||
if cond not in pconds:
|
||||
print("Invalid condition suffix: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
return (mask | pconds[cond])
|
||||
|
||||
@ -507,8 +506,7 @@ def parse_instr(line):
|
||||
|
||||
if len(word) == 0:
|
||||
print("Wrong syntax in line: '{}'".format(line))
|
||||
leave()
|
||||
sys.exit(-1)
|
||||
leave(1)
|
||||
|
||||
# local labels
|
||||
if word[0] == '.':
|
||||
@ -529,8 +527,7 @@ def parse_instr(line):
|
||||
gotPref = True
|
||||
else:
|
||||
print("Bad memory length prefix: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
word = word[1:].strip()
|
||||
assert(word[0] == '[')
|
||||
@ -552,8 +549,7 @@ def parse_instr(line):
|
||||
#
|
||||
if not gotPref:
|
||||
print("Missing access length modifier: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
instr_name += "_m"
|
||||
|
||||
@ -793,8 +789,7 @@ def gentext():
|
||||
if ':' in word:
|
||||
if len(word.split(':')) < 2:
|
||||
print("Stray ':' in line: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
reg2, reg1 = word.split(':', 1)
|
||||
idx1 = pregs[reg1]
|
||||
@ -843,8 +838,7 @@ def gentext():
|
||||
continue
|
||||
|
||||
print("Assembly error, unknown token '{}' in line: {}".format(word, line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
leave(1)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -894,5 +888,5 @@ parse()
|
||||
gentext()
|
||||
genout()
|
||||
gensym()
|
||||
leave()
|
||||
sys.exit(0)
|
||||
leave(0)
|
||||
|
||||
|
@ -27,7 +27,7 @@ ltostr:
|
||||
b.a ax2, 36, .bad
|
||||
|
||||
; deal with zero
|
||||
b.e ax1, 0, .zero
|
||||
b.z ax1, 0, .zero
|
||||
|
||||
; deal with base 10 signedness
|
||||
|
||||
@ -42,7 +42,7 @@ ltostr:
|
||||
|
||||
; main loop
|
||||
.conv:
|
||||
b.e ax1, 0, .fini
|
||||
b.z ax1, 0, .fini
|
||||
|
||||
rem r10, ax1, ax2 ; ax1 % base
|
||||
|
||||
@ -58,7 +58,7 @@ ltostr:
|
||||
mov b[ax0], r10
|
||||
inc ax0
|
||||
|
||||
div ax1, ax2
|
||||
div ax1, ax1, ax2
|
||||
jmp .conv
|
||||
|
||||
; add minus flag, null-terminate and reverse
|
||||
|
@ -137,7 +137,7 @@ strtoq:
|
||||
; too large for base?
|
||||
b.ae r12, ax1, .done
|
||||
|
||||
mul rax, ax1
|
||||
mul rax, rax, ax1
|
||||
add rax, r12
|
||||
jmp .main_loop
|
||||
|
||||
|
@ -54,12 +54,12 @@ GetTimeUTC:
|
||||
|
||||
; minutes
|
||||
div rcx, r11, 60
|
||||
rem rcx, 60
|
||||
rem rcx, rcx, 60
|
||||
mov b[rdx+1], rcx
|
||||
|
||||
; hours
|
||||
div rcx, r11, 3600
|
||||
rem rcx, 24
|
||||
rem rcx, rcx, 24
|
||||
mov b[rdx+2], rcx
|
||||
|
||||
; month days
|
||||
|
@ -1,6 +1,106 @@
|
||||
# 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 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 #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -72,12 +172,10 @@ dec rm
|
||||
#
|
||||
add r rim
|
||||
add r r ri
|
||||
|
||||
add m ri
|
||||
add m r ri
|
||||
|
||||
addf r ri
|
||||
addf r r ri
|
||||
addo r r ri
|
||||
|
||||
#
|
||||
# Atomic exchange and add (XADD)
|
||||
@ -103,15 +201,12 @@ xadd m r
|
||||
sub r rim
|
||||
sub r r ri
|
||||
sub r i r
|
||||
|
||||
sub m ri
|
||||
sub m r ri
|
||||
sub m i r
|
||||
|
||||
subf r ri
|
||||
subf r r ri
|
||||
subf r i r
|
||||
|
||||
subo r r ri
|
||||
subo r i r
|
||||
|
||||
#
|
||||
# Arithmetical ADD/SUB operation, with carry/overflow
|
||||
@ -124,10 +219,10 @@ subf r i r
|
||||
# Preserves ZF and SF
|
||||
# Flags CF and OF are undefined for now
|
||||
#
|
||||
adc r r
|
||||
ado r r
|
||||
sbb r r
|
||||
sbo r r
|
||||
adcx r r ri
|
||||
adox r r ri
|
||||
sbbx r r ri
|
||||
sbox r r ri
|
||||
|
||||
#
|
||||
# Arithmetical unsigned MUL operation
|
||||
@ -137,9 +232,9 @@ sbo r r
|
||||
# Preserves ZF and SF
|
||||
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
|
||||
#
|
||||
mul r ri
|
||||
mul r r ri
|
||||
mulf r r ri
|
||||
mulo r r ri
|
||||
|
||||
# Arithmetical unsigned MUL operation
|
||||
#
|
||||
@ -158,9 +253,7 @@ mulhi r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
div r ri
|
||||
div r r ri
|
||||
div r i r
|
||||
|
||||
#
|
||||
# Arithmetical unsigned modulo operation (REM)
|
||||
@ -169,7 +262,5 @@ div r i r
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
rem 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.
|
||||
|
||||
include "SUPER"
|
||||
include "TRAP"
|
||||
include "ALU"
|
||||
include "MOV"
|
||||
include "MISC"
|
||||
include "LOGIC"
|
||||
include "ARITH"
|
||||
include "JUMPS"
|
||||
include "STACK"
|
||||
include "FLAGS"
|
||||
include "INOUT"
|
||||
include "BITMP"
|
||||
include "DEBUG"
|
||||
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.
|
||||
# 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 #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -79,6 +102,32 @@ cla
|
||||
#
|
||||
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 #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -92,3 +141,34 @@ bswap r r
|
||||
wswap 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.
|
||||
# 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 #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -70,19 +163,9 @@ cmpxchg rm r
|
||||
#
|
||||
# 3-operand rotation (ROTd)
|
||||
#
|
||||
# $3 -> $2 -> $1 -> $3 (KROTL)
|
||||
# $1 -> $2 -> $3 -> $1 (KROTR)
|
||||
# $3 -> $2 -> $1 -> $3 (ROTL)
|
||||
# $1 -> $2 -> $3 -> $1 (ROTR)
|
||||
#
|
||||
rotr 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)
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
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)
|
||||
#
|
||||
# See dv/DEVAPI
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
devctl ri ri
|
||||
|
||||
#
|
||||
@ -46,4 +77,8 @@ devctl ri ri
|
||||
#
|
||||
# See dv/DEVAPI
|
||||
#
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
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.
|
||||
|
||||
#include <pc/arch.h>
|
||||
|
||||
#include <in/flags.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) \
|
||||
DECV(v1, p1);
|
||||
|
||||
#define IMPL_START_1_NOIN(name) \
|
||||
IMPL_START_0(name) \
|
||||
ulong v1;
|
||||
|
||||
#define IMPL_START_2(name) \
|
||||
IMPL_START_1(name) \
|
||||
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() \
|
||||
ulong src1, src2; \
|
||||
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.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include <pc/console.h>
|
||||
#include <in/instrs.h>
|
||||
#include <sys/time.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_START_0(pause)
|
||||
{
|
||||
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_1(time) { v1 = time(NULL); } IMPL_OUT;
|
||||
|
||||
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;
|
||||
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;
|
||||
for (int i = R10; i <= R15; i++) R(i) = 0;
|
||||
}
|
||||
IMPL_END;
|
||||
} IMPL_END;
|
||||
|
||||
IMPL_START_0(cla)
|
||||
{
|
||||
for (int i = AX0; i <= AX7; i++) R(i) = 0;
|
||||
}
|
||||
IMPL_END;
|
||||
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;
|
||||
|
||||
IMPL_START_0(cln)
|
||||
{
|
||||
for (int i = NX0; i <= NX7; i++) R(i) = 0;
|
||||
}
|
||||
IMPL_END;
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
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(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>
|
||||
|
||||
IMPL_START_1(lea)
|
||||
{
|
||||
v1 = p2->addr;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_2_ONLY(mov)
|
||||
{
|
||||
v1 = v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
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_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_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)
|
||||
{
|
||||
ulong tmp = v1;
|
||||
v1 = v2;
|
||||
v2 = v3;
|
||||
v3 = tmp;
|
||||
}
|
||||
IMPL_OUT_3;
|
||||
IMPL_START_1_NOIN(lea) { v1 = p2->addr; } IMPL_OUT;
|
||||
IMPL_START_2_ONLY(mov) { v1 = v2; } IMPL_OUT;
|
||||
|
||||
IMPL_START_3(rotr)
|
||||
{
|
||||
ulong tmp = v3;
|
||||
v3 = v2;
|
||||
v2 = v1;
|
||||
v1 = tmp;
|
||||
}
|
||||
IMPL_OUT_3;
|
||||
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_NOIN(movzx) { DECVZX(v2, p2); v1 = v2; } IMPL_OUT;
|
||||
|
||||
IMPL_START_2(xchg) { ulong t = v1; v1 = v2; v2 = t; } IMPL_OUT_2;
|
||||
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)
|
||||
{
|
||||
if (v2 < 16)
|
||||
v1 = R(AX0 + v2);
|
||||
//
|
||||
// Stack manipulation instructions
|
||||
//
|
||||
|
||||
else
|
||||
_except(ctx, E_ILL, "ldarg: value out of range: %lu", v2);
|
||||
}
|
||||
IMPL_OUT;
|
||||
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;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
@ -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) \
|
||||
if ((rfx & DF) == 0) \
|
||||
R(reg) += len; \
|
||||
else \
|
||||
R(reg) -= len;
|
||||
if (!(rfx & DF)) R(reg) += len; \
|
||||
else R(reg) -= len;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
static void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
DECV(v2, p2);
|
||||
|
||||
writemem(ctx, v2, R(p1->reg), len);
|
||||
|
||||
STR_MOVE(p1->reg, len);
|
||||
}
|
||||
|
||||
IMPL_START_0(stosb)
|
||||
{
|
||||
stos_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
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;
|
||||
IMPL_START_0(stosb) { stos_impl(ctx, p1, p2, 1); } 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)
|
||||
{
|
||||
R(p1->reg) = readmem(ctx, R(p2->reg), len);
|
||||
|
||||
R(RFX) = (R(p1->reg) == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
|
||||
|
||||
STR_MOVE(p2->reg, len);
|
||||
}
|
||||
|
||||
IMPL_START_0(lodsb)
|
||||
{
|
||||
lods_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
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;
|
||||
IMPL_START_0(lodsb) { lods_impl(ctx, p1, p2, 1); } 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)
|
||||
{
|
||||
scas_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
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;
|
||||
IMPL_START_0(scasb) { scas_impl(ctx, p1, p2, 1); } 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);
|
||||
}
|
||||
|
||||
IMPL_START_0(cmpsb)
|
||||
{
|
||||
cmps_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
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;
|
||||
IMPL_START_0(cmpsb) { cmps_impl(ctx, p1, p2, 1); } 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);
|
||||
}
|
||||
|
||||
IMPL_START_0(cmpzsb)
|
||||
{
|
||||
cmpzs_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
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;
|
||||
IMPL_START_0(cmpzsb) { cmpzs_impl(ctx, p1, p2, 1); } 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);
|
||||
}
|
||||
|
||||
IMPL_START_0(movsb)
|
||||
{
|
||||
movs_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
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;
|
||||
IMPL_START_0(movsb) { movs_impl(ctx, p1, p2, 1); } 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 <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)
|
||||
{
|
||||
@ -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;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// code common to devctl and iocall
|
||||
//
|
||||
@ -140,3 +147,5 @@ IMPL_START_2(iocall)
|
||||
}
|
||||
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 disable_stdin_echoing(void);
|
||||
|
||||
extern void do_hlt(ctx_t *ctx);
|
||||
|
||||
#include <pc/mem.h>
|
||||
#include <pc/sym.h>
|
||||
#include <pc/regs.h>
|
||||
|
@ -22,6 +22,7 @@ enum
|
||||
E_ALI, // Alignment error
|
||||
E_BRK, // Ctrl+C or similar
|
||||
E_OVF, // INTO instruction
|
||||
E_DIV, // Division by zero
|
||||
NEXCPTS
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user