This commit is contained in:
julianb0 2019-07-17 20:26:03 +02:00
parent 1cd5286440
commit 1b5b90fa37
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
36 changed files with 729 additions and 1285 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,8 +0,0 @@
# The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information.
#---------------------------------------------------------------------------#
# Bit manipulation instructions #
#---------------------------------------------------------------------------#

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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;
//----------------------------------------------------------------------------//

View File

@ -1,7 +0,0 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <in/instrs.h>
#define _NEED_ARCH_I
#include <in/arch_i.h>

View File

@ -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;
//----------------------------------------------------------------------------//

View File

View File

@ -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;

View File

@ -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;
//----------------------------------------------------------------------------//

View File

@ -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);

View File

@ -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;

View File

@ -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) { \

View File

@ -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;
//----------------------------------------------------------------------------//

View File

@ -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;
//----------------------------------------------------------------------------//

View File

@ -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;
//----------------------------------------------------------------------------//

View File

@ -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;
//----------------------------------------------------------------------------//

View File

@ -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;

View File

@ -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;
//----------------------------------------------------------------------------//

View File

@ -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;
//----------------------------------------------------------------------------//

View File

@ -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;

View File

@ -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>

View File

@ -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
};