This commit is contained in:
julianb0 2019-07-04 20:33:49 +02:00
parent 108faf9269
commit a42786831f
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
38 changed files with 454 additions and 618 deletions

View File

@ -23,6 +23,9 @@ dos: kas dosclean
dosclean:
@rm -f $(KODIR)/*.com $(KODIR)/*.sym
inclean:
@rm -f vm/in/arch_i.h vm/in/instrs.lst vm/ob/in/*.o
clean: dosclean
@cd vm && make clean --no-print-directory -s verbose=no
@rm -f $(KVVM) as/instrs.lst

View File

@ -6,7 +6,9 @@
; int doprnt(PUTC putc, int n, const char *fmt, va_list ap)
;
doprnt:
dump 0
enter 8
mov q[rbp-8], rbx
mov q[rbp-16], nx0
mov q[rbp-24], nx1
@ -118,6 +120,7 @@ doprnt:
.print_itoa_buf:
mov ax0, b[rdi]
test ax0, ax0
add.z rsp, 80
j.z .main_loop
@ -173,6 +176,7 @@ doprnt:
mov rsi, q[rbp-48]
mov nx3, q[rbp-56]
leave
dump 1
ret
;
; prints ax0

View File

@ -13,6 +13,7 @@ putc:
; int printf(const char *fmt, ...)
;
printf:
dump 0
mov ax2, ax0
mov ax0, putc
mov ax1, STRLEN_MAX
@ -23,6 +24,7 @@ printf:
; int nprintf(const char *fmt, int n, ...)
;
nprintf:
dump 0
mov ax2, ax0
mov ax0, putc
lea ax3, b[rsp+8]

View File

@ -21,3 +21,4 @@ LWORD_MAX := 0xFFFFFFFF
QWORD_MAX := 0xFFFFFFFFFFFFFFFF
STRLEN_MAX := 0xFFFFFFFF

View File

@ -23,7 +23,8 @@ strrev:
.2:
; copy, going backward though str
; and forward through buf
mov b[ax0], b[ax1]
mov rax, b[ax1]
mov b[ax0], rax
cmp ax1, rx8
mov.z b[ax0+1], 0
@ -55,7 +56,9 @@ strrev2:
.2:
b.ae ax0, ax1, .3
xchg b[ax0], b[ax1]
mov rax, b[ax1]
xchg rax, b[ax0]
mov b[ax1], rax
inc ax0
dec ax1

View File

@ -1,6 +1,14 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
movsx_test:
mov rcx, 0x1188FF
movsxb rx8, rcx
movsxw rx9, rcx
movsxl r10, rcx
hlt
ret
dir_test:
mov ax0, .buf
mov ax1, 128

View File

@ -35,11 +35,11 @@ CMD.builtins.dir:
scasb.rep.nz r10, '.'
; print file name
ksub rcx, r10, r11
sub rcx, r10, r11
prns.rep r11
; calculate where to put extension
ksub r11, r10, .buf
sub r11, r10, .buf
dec r11
.ext_pad:

View File

@ -12,13 +12,13 @@ dv_src = $(shell ls dv/*.c)
in_src = $(shell ls in/*.c)
pc_src = $(shell ls pc/*.c)
obj = $(patsubst %.c,$(OBJDIR)/%.o,$(dv_src))
obj = $(patsubst %.c,$(OBJDIR)/%.o,$(pc_src))
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(dv_src))
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(in_src))
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(pc_src))
dep = $(patsubst %.c,$(OBJDIR)/%.d,$(dv_src))
dep = $(patsubst %.c,$(OBJDIR)/%.d,$(pc_src))
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(dv_src))
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(in_src))
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(pc_src))
# Color codes
CL='\033[0;32m'

View File

@ -146,7 +146,7 @@ long cpudev_switchframe(ctx_t *ctx, dev_t *dev)
rfs_current_idx = ax0;
ctx->rf = rfs[ax0];
rx2 = 0;
fc2 = 0;
return 0;
}

View File

@ -14,7 +14,8 @@
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
cmp rim rim
cmp r ri
cmp m ri
#
# Arithmetical SGN operation
@ -28,58 +29,55 @@ cmp rim rim
# FI
#
# Treats $1 and $2 as signed values
# Sets ZF and SF according to the result
#
sgn rm rim
sgnf rm rim
# Preserves all flags
#
sgn r r
#
# Arithmetical NEG operation
#
# $1 = NOT($2) + 1
#
# Sets CF if $2 == 0; clears it otherwise
# Sets OF if $2 == $LONG_MIN; clears it otherwise
# Sets ZF and SF according to the result
# Preserves all flags
#
neg rm rim
negf rm rim
neg r r
#
# Arithmetical INC operation
#
# $1 = $1 + 1
#
# Preserves CF
# Sets OF if $1 == $LONG_MAX, clears it otherwise
# Sets ZF and SF according to the result
# Preserves all flags
#
inc rm
incf rm
#
# Arithmetical DEC operation
#
# $1 = $1 - 1
#
# Preserves CF
# Sets OF if $1 == $LONG_MIN, clears it otherwise
# Sets ZF and SF according to the result
# Preserves all flags
#
dec rm
decf rm
#
# Arithmetical ADD operation
#
# $1 = $1 + $2
# $dest1 = $src1 + $src2
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
add rm rim
addf rm rim
add r rim
add r r ri
add m ri
add m r ri
addf r ri
addf r r ri
#
# Atomic exchange and add (XADD)
@ -90,74 +88,76 @@ addf rm rim
#
# Preserves all flags
#
xadd rm rm
#
# Arithmetical ADD operation, with carry
#
# $1 = $1 + $2 + CF
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
adc rm rim
adcf rm rim
xadd r rm
xadd m r
#
# Arithmetical SUB operation
#
# $1 = $1 - $2
# $dest = $src1 - $src2
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
sub rm rim
subf rm rim
sub r rim
sub r r ri
sub m ri
sub m r ri
subf r ri
subf r r ri
#
# Arithmetical ADD/SUB operation, with carry/overflow
#
# $dest = $src1 + $src2 + CF (ADC)
# $dest = $src1 + $src2 + OF (ADO)
# $dest = $src1 - $src2 - CF (SBB)
# $dest = $src1 - $src2 - OF (SBO)
#
# Preserves ZF and SF
# Flags CF and OF are undefined for now
#
adc r r
ado r r
sbb r r
sbo r r
#
# Arithmetical unsigned MUL operation
#
# $1 = LO($1 * $2)
# $dest = LO($src1 * $src2)
#
# Sets CF and OF if HI($1 * $2) > 0, clears them otherwise
# Preserves ZF and SF
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
#
mul rm rim
mulf rm rim
mul r ri
mul r r ri
mulf r r ri
# Arithmetical unsigned MUL operation
#
# Arithmetical unsigned 128-bit MUL operation
#
# $1 = HI($2 * $3)
# $2 = LO($2 * $3)
# $dest1 = HI($dest2 * $src)
# $dest2 = LO($dest2 * $src)
#
# Sets CF and OF if HI($2 * $3) > 0, clears them otherwise
# Preserves ZF and SF
#
mulx rm rm rim
mulfx rm rm rim
mulhi r r ri
#
# Arithmetical unsigned DIV operation
#
# $1 = $1 DIV $2
# $dest1 = $1 DIV $2
#
# Preserves all flags
#
div rm rim
div r ri
div r r ri
#
# Arithmetical unsigned combined DIV and MOD operations
#
# $1 = ($2 MOD $3)
# $2 = ($2 DIV $3)
#
# Preserves all flags
#
divx rm rm rim
#
# Arithmetical unsigned modulo operation (REM)
#
@ -165,5 +165,6 @@ divx rm rm rim
#
# Preserves all flags
#
rem rm rim
rem r ri
rem r r ri

View File

@ -22,5 +22,15 @@ break
# (enable step-by-step execution)
# FI
#
step rim
step ri
#
# Enable/disable instruction dumping (DUMP)
#
# IF $1 == 0 THEN
# (disable instruction dumping)
# ELSE
# (enable instruction dumping)
# FI
#
dump ri

View File

@ -30,5 +30,5 @@ prns r
#
# Scan a character from standard input (SCAN)
#
scan rm
scan r

View File

@ -14,5 +14,4 @@ include "INOUT"
include "BITMP"
include "DEBUG"
include "STRING"
include "TERNARY"

View File

@ -39,5 +39,5 @@ loop ri
#
# Suffixing B with the REP suffix results in undefined behavior
#
b rim rim ri
b rm ri ri

View File

@ -13,7 +13,7 @@
# Clears OF and CF
# Sets ZF and SF according to the result
#
test rim rim
test r ri
#
# Bitwise NOT operation
@ -22,50 +22,82 @@ test rim rim
#
# Preserves all flags
#
not rm rim
not r r
#
# Bitwise OR operation
#
# $1 = $1 OR $2
# $dest = $src1 OR $src2
#
# Clears OF and CF
# Sets ZF and SF according to the result
#
or rm rim
orf rm rim
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
#
# $1 = $1 AND $2
# $dest = $src1 AND $src2
#
# Clears OF and CF
# Sets ZF and SF according to the result
#
and rm rim
andf rm rim
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
#
# $1 = $1 XOR $2
# $dest = $src1 XOR $src2
#
# Clears OF and CF
# Sets ZF and SF according to the result
#
xor rm rim
xorf rm rim
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 rm rim
shr rm rim
shlf rm rim
shrf rm rim
shl r rim
shl m ri
sal rm rim
sar rm rim
salf rm rim
sarf rm rim
shr r rim
shr m ri
sal r rim
sal m ri
sar r rim
sar m ri

View File

@ -34,12 +34,12 @@ xpause
#
# Get timestamp in seconds
#
time rm
time r
#
# Get timestamp in µseconds
#
utime rm
utime r
#
# CPU Identification Number
@ -77,7 +77,7 @@ cla
#
# Change endianness
#
bswap rm rim
wswap rm rim
dswap rm rim
bswap r r
wswap r r
dswap r r

View File

@ -17,21 +17,31 @@
#
# Preserves all flags
#
lea rm m
lea r m
#
# Movement (MOV) instruction
# Movement with sign-extension (MOV) instruction
#
# $1 = $2
#
mov rm rim
mov r rim
mov m ri
#
# Movement with sign-extension (MOVSXx) instruction
#
# $1 = SignExtend($2 & (2^(8 * sizeof(x)) - 1)
#
movsxb r r
movsxw r r
movsxl r r
#
# Movement with zero-extension (MOVZX) instruction
#
# $1 = ZeroExtend($2)
#
movzx rm m
movzx r m
#
# Exchange (XCHG) instruction
@ -40,7 +50,7 @@ movzx rm m
# $1 = $2
# $2 = $_
#
xchg rm rim
xchg r rm
#
# Compare-and-exchange (CMPXCHG) instruction
@ -55,7 +65,16 @@ xchg rm rim
#
# Preserves CF, OF and SF
#
cmpxchg rm rim
cmpxchg rm r
#
# 3-operand rotation (ROTd)
#
# $3 -> $2 -> $1 -> $3 (KROTL)
# $1 -> $2 -> $3 -> $1 (KROTR)
#
rotr rm r r
rotl rm r r
#
# Load argument #N (LDARG)
@ -69,7 +88,7 @@ cmpxchg rm rim
# Throws:
# #ILL if $2 ≥ 16
#
ldarg rm rim
ldarg r ri
#
# Get code/data offset (GCO/GCD)
@ -77,6 +96,6 @@ ldarg rm rim
# $1 = CR1 (GCO)
# $1 = CR2 (GCD)
#
gco rm
gcd rm
gco r
gcd r

View File

@ -11,7 +11,7 @@
# PUSH(RIP)
# JMP(RIP)
#
call rim
call ri
#
# Return to caller (RET)
@ -43,7 +43,7 @@ leave
# RSP = RSP - 8
# *RSP = $1
#
push rim
push ri
#
# POP value from stack
@ -51,5 +51,5 @@ push rim
# $1 = *RSP
# RSP = RSP + 8
#
pop rm
pop r

View File

@ -19,10 +19,10 @@
# When one parameter is given, %str = RDI and $val = $1
# When two parameters are given, %str = $1 and $val = $2
#
stosb r rim
stosw r rim
stosl r rim
stosq r rim
stosb r ri
stosw r ri
stosl r ri
stosq r ri
#
# Load value from string (LODSx)
@ -64,10 +64,10 @@ lodsq r r
# - Does not move past the value when found
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
#
scasb r rim
scasw r rim
scasl r rim
scasq r rim
scasb r ri
scasw r ri
scasl r ri
scasq r ri
#
# Compare bytes in strings (CMPSx)

View File

@ -39,11 +39,11 @@ hlt
#
# See dv/DEVAPI
#
devctl rim rim
devctl ri ri
#
# Call a device-defined function slot of device (IOCALL)
#
# See dv/DEVAPI
#
iocall rim rim
iocall ri ri

View File

@ -1,44 +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.
#---------------------------------------------------------------------------#
# 3-operand instructions #
#---------------------------------------------------------------------------#
#
# 3-operand rotation (KROTd)
#
# $3 -> $2 -> $1 -> $3 (KROTL)
# $1 -> $2 -> $3 -> $1 (KROTR)
#
krotr rm rm rm
krotl rm rm rm
#
# 2-sources logical & arithmetical operations
#
# Preserves all flags
#
kor rm rim rim
kand rm rim rim
kxor rm rim rim
knor rm rim rim
korn rm rim rim
knand rm rim rim
kandn rm rim rim
kxnor rm rim rim
kxorn rm rim rim
kshl rm rim rim
kshr rm rim rim
ksal rm rim rim
ksar rm rim rim
kadd rm rim rim
kadc rm rim rim
kado rm rim rim
ksub rm rim rim
ksbb rm rim rim
ksbo rm rim rim
kmul rm rim rim
kdiv rm rim rim
krem rm rim rim

View File

@ -12,7 +12,7 @@
# #ILL if $1 > 255
# #($1+256) otherwise
#
trap rim
trap ri
#
# Return from exception/interrupt (IRET)

View File

@ -12,36 +12,12 @@ IMPL_START_2(sgn)
}
IMPL_OUT;
IMPL_START_2(sgnf)
{
v1 = (long)v2 < 0 ? (ulong)-1L : 1;
}
IMPL_OUT_ZSF;
IMPL_START_2(neg)
{
v1 = ~v2 + 1;
}
IMPL_OUT;
IMPL_START_2(negf)
{
if (v2 == 0) {
flg |= CF;
flg &= ~OF;
}
else {
flg &= ~CF;
if (v2 == LONG_MIN) flg |= OF;
else flg &= ~OF;
}
v1 = ~v2 + 1;
}
IMPL_OUT_ZSF;
//----------------------------------------------------------------------------//
IMPL_START_1(inc)
@ -50,35 +26,18 @@ IMPL_START_1(inc)
}
IMPL_OUT;
IMPL_START_1(incf)
{
if (v1 == LONG_MAX) flg |= OF;
else flg &= ~OF;
v1++;
}
IMPL_OUT_ZSF;
IMPL_START_1(dec)
{
v1--;
}
IMPL_OUT;
IMPL_START_1(decf)
{
if (v1 == LONG_MIN) flg |= OF;
else flg &= ~OF;
v1--;
}
IMPL_OUT_ZSF;
//----------------------------------------------------------------------------//
IMPL_START_2(add)
{
v1 += v2;
ALU_GET_SRCS();
v1 = src1 + src2;
}
IMPL_OUT;
@ -92,37 +51,9 @@ IMPL_OUT_2;
IMPL_START_2(addf)
{
if (v1 + v2 < v1) flg |= OF;
else flg &= ~OF;
if ( ((v2 > 0) && (v1 > LONG_MAX - v2))
|| ((v2 < 0) && (v1 < LONG_MIN - v2)) )
flg |= CF;
else flg &= ~CF;
v1 += v2;
}
IMPL_OUT_ZSF;
IMPL_START_2(adc)
{
v1 += v2 + !!(flg&CF);
}
IMPL_OUT;
IMPL_START_2(adcf)
{
if (v1 + v2 + !!(flg&CF) < v1) flg |= OF;
else flg &= ~OF;
v1 += !!(flg&CF);
if ( ((v2 > 0) && (v1 > LONG_MAX - v2))
|| ((v2 < 0) && (v1 < LONG_MIN - v2)) )
flg |= CF;
else flg &= ~CF;
v1 += v2;
ALU_GET_SRCS();
COMPARE(src1, ~src2+1);
v1 = src1 + src2;
}
IMPL_OUT_ZSF;
@ -130,14 +61,16 @@ IMPL_OUT_ZSF;
IMPL_START_2(sub)
{
v1 -= v2;
ALU_GET_SRCS();
v1 = src1 - src2;
}
IMPL_OUT;
IMPL_START_2(subf)
{
COMPARE(v1, v2);
v1 -= v2;
ALU_GET_SRCS();
COMPARE(src1, src2);
v1 = src1 - src2;
}
IMPL_OUT;
@ -152,6 +85,36 @@ IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_2(adc)
{
ALU_GET_SRCS();
v1 = src1 + src2 + !!(flg&CF);
}
IMPL_OUT;
IMPL_START_2(ado)
{
ALU_GET_SRCS();
v1 = src1 + src2 + !!(flg&OF);
}
IMPL_OUT;
IMPL_START_2(sbb)
{
ALU_GET_SRCS();
v1 = src1 - src2 - !!(flg&CF);
}
IMPL_OUT;
IMPL_START_2(sbo)
{
ALU_GET_SRCS();
v1 = src1 - src2 - !!(flg&OF);
}
IMPL_OUT;
//----------------------------------------------------------------------------//
//
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
//
@ -172,24 +135,30 @@ static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
t = (u1 * v) + k;
k = (t >> 32);
*hi = (u * v) + w1 + k;
*lo = (t << 32) + w3;
if (hi) *hi = (u * v) + w1 + k;
if (lo) *lo = (t << 32) + w3;
}
IMPL_START_2(mul)
{
ulong hi;
multiply(v1, v2, &hi, &v1);
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)
{
ulong hi;
ALU_GET_SRCS();
multiply(src1, src2, &v2, &v1);
multiply(v1, v2, &hi, &v1);
if (hi > 0) {
if (v2 > 0) {
flg |= CF;
flg |= OF;
}
@ -201,48 +170,21 @@ IMPL_START_2(mulf)
}
IMPL_OUT;
IMPL_START_3(mulx)
{
multiply(v2, v3, &v1, &v2);
}
IMPL_OUT_2;
IMPL_START_3(mulfx)
{
multiply(v2, v3, &v1, &v2);
if (v1 > 0) {
flg |= CF;
flg |= OF;
}
else {
flg &= ~CF;
flg &= ~OF;
}
}
IMPL_OUT_2;
//----------------------------------------------------------------------------//
IMPL_START_2(div)
{
v1 /= v2;
ALU_GET_SRCS();
v1 = src1 / src2;
}
IMPL_OUT;
IMPL_START_2(rem)
{
v1 %= v2;
ALU_GET_SRCS();
v1 = src1 % src2;
}
IMPL_OUT;
IMPL_START_3(divx)
{
v1 = v2 % v3;
v2 = v2 / v3;
}
IMPL_OUT_2;
//----------------------------------------------------------------------------//

View File

@ -19,6 +19,18 @@ IMPL_START_1(step)
}
IMPL_END;
IMPL_START_1(dump)
{
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;
}
IMPL_END;
IMPL_START_0(err)
{
}

View File

@ -22,11 +22,15 @@
SET_PF(v)
#define COMPARE(v1, v2) \
if (v1 < v2) flg |= CF; \
ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \
long _s1 = (long)v1, _s2 = (long)v2; \
\
if (_u1 < _u2) flg |= CF; \
else flg &= ~CF; \
if ( ((v2 < 0) && (v1 > LONG_MAX + v2)) \
|| ((v2 > 0) && (v1 < LONG_MIN + v2)) ) \
\
if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \
|| ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \
flg |= OF; \
else flg &= ~OF; \
SET_ZSF(v1 - v2);
SET_ZSF(_u1 - _u2);

View File

@ -48,6 +48,13 @@ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
DECV(v1, p1); \
DECV(v2, p2);
#define IMPL_START_2_ONLY(name) \
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
ulong *r1, ulong *r2, ulong *r3) \
{ \
ulong v1; (void)v1; \
DECV(v2, p2);
#define IMPL_START_3(name) \
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
ulong *r1, ulong *r2, ulong *r3) \
@ -56,15 +63,21 @@ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
DECV(v2, p2); \
DECV(v3, p3);
#define IMPL_OUT_ZSF \
SET_ZSF(v1); \
IMPL_OUT
//----------------------------------------------------------------------------//
#define IMPL_END \
return 0; \
}
#define IMPL_OUT \
*r1 = v1; \
return 1; \
}
#define IMPL_OUT_ZSF \
SET_ZSF(v1); \
IMPL_OUT
#define IMPL_OUT_2 \
*r1 = v1; \
*r2 = v2; \
@ -78,9 +91,17 @@ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
return 3; \
}
#define IMPL_END \
return 0; \
}
//----------------------------------------------------------------------------//
#define ALU_GET_SRCS() \
ulong src1, src2; \
if (p3) { \
src1 = v2; \
GETV(src2, p3); \
} else { \
src1 = v1; \
src2 = v2; \
}
//----------------------------------------------------------------------------//

View File

@ -11,131 +11,65 @@ IMPL_START_2(not)
}
IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_2(test)
{
flg &= ~OF;
flg &= ~CF;
flg &= ~(CF|OF);
SET_ZSF(v1 & v2);
}
IMPL_END;
IMPL_START_2(and)
{
v1 &= v2;
}
IMPL_OUT;
IMPL_START_2(andf)
{
flg &= ~OF;
flg &= ~CF;
v1 &= v2;
}
IMPL_OUT_ZSF;
//----------------------------------------------------------------------------//
IMPL_START_2(or)
{
v1 |= v2;
}
#define LOGIC_IMPL(name, op) \
IMPL_START_2(name) \
{ \
ALU_GET_SRCS(); \
v1 = op; \
} \
IMPL_OUT;
IMPL_START_2(orf)
{
flg &= ~OF;
flg &= ~CF;
v1 |= v2;
}
IMPL_OUT_ZSF;
LOGIC_IMPL(and, src1 & src2);
LOGIC_IMPL(andn, src1 & ~src2);
LOGIC_IMPL(nand, ~(src1 & src2));
IMPL_START_2(xor)
{
v1 ^= v2;
}
IMPL_OUT;
LOGIC_IMPL(or, src1 | src2);
LOGIC_IMPL(orn, src1 | ~src2);
LOGIC_IMPL(nor, ~(src1 | src2));
IMPL_START_2(xorf)
{
flg &= ~OF;
flg &= ~CF;
v1 ^= v2;
}
IMPL_OUT_ZSF;
LOGIC_IMPL(xor, src1 ^ src2);
LOGIC_IMPL(xorn, src1 ^ ~src2);
LOGIC_IMPL(xnor, ~(src1 ^ src2));
//----------------------------------------------------------------------------//
IMPL_START_2(shl)
{
v1 <<= v2;
}
IMPL_OUT;
IMPL_START_2(shlf)
{
v1 <<= v2;
}
IMPL_OUT_ZSF;
IMPL_START_2(shr)
{
v1 >>= v2;
}
IMPL_OUT;
IMPL_START_2(shrf)
{
v1 >>= v2;
}
IMPL_OUT_ZSF;
LOGIC_IMPL(shl, src1 << src2);
LOGIC_IMPL(shr, src1 >> src2);
//--------------------------------------------------------------------------
IMPL_START_2(sal)
{
long w1 = v1;
long w2 = v2;
ALU_GET_SRCS();
long w1 = src1;
long w2 = src2;
w1 <<= w2;
v1 = (ulong) w1;
v1 = (ulong)w1;
}
IMPL_OUT;
IMPL_START_2(salf)
{
long w1 = v1;
long w2 = v2;
w1 <<= w2;
v1 = (ulong) w1;
}
IMPL_OUT_ZSF;
IMPL_START_2(sar)
{
long w1 = v1;
long w2 = v2;
ALU_GET_SRCS();
long w1 = src1;
long w2 = src2;
w1 >>= w2;
v1 = (ulong) w1;
v1 = (ulong)w1;
}
IMPL_OUT;
IMPL_START_2(sarf)
{
long w1 = v1;
long w2 = v2;
w1 >>= w2;
v1 = (ulong) w1;
}
IMPL_OUT_ZSF;
//----------------------------------------------------------------------------//

View File

@ -11,12 +11,34 @@ IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_2(mov)
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);
@ -51,13 +73,33 @@ IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_2(ldarg)
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_ONLY(ldarg)
{
if (v2 < 32)
v1 = R(AX0 + v2);
else
_except(ctx, E_ILL, "ldarg: value out of range: %lu", v1);
_except(ctx, E_ILL, "ldarg: value out of range: %lu", v2);
}
IMPL_OUT;

View File

@ -1,82 +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_3(krotl)
{
ulong tmp = v1;
v1 = v2;
v2 = v3;
v3 = tmp;
}
IMPL_OUT_3;
IMPL_START_3(krotr)
{
ulong tmp = v3;
v3 = v2;
v2 = v1;
v1 = tmp;
}
IMPL_OUT_3;
//----------------------------------------------------------------------------//
#define K_IMPL_ALU(name, expr) \
IMPL_START_3(k##name) \
{ \
v1 = (expr); \
} \
IMPL_OUT
K_IMPL_ALU(or, v2 | v3);
K_IMPL_ALU(and, v2 & v3);
K_IMPL_ALU(xor, v2 ^ v3);
K_IMPL_ALU(nor, ~(v2 | v3));
K_IMPL_ALU(orn, v2 | ~v3);
K_IMPL_ALU(nand, ~(v2 & v3));
K_IMPL_ALU(andn, v2 & ~v3);
K_IMPL_ALU(xnor, ~(v2 ^ v3));
K_IMPL_ALU(xorn, v2 ^ ~v3);
K_IMPL_ALU(shl, v2 << v3);
K_IMPL_ALU(shr, v2 >> v3);
K_IMPL_ALU(add, v2 + v3);
K_IMPL_ALU(adc, v2 + v3 + !!(flg&CF));
K_IMPL_ALU(ado, v2 + v3 + !!(flg&OF));
K_IMPL_ALU(sub, v2 - v3);
K_IMPL_ALU(sbb, v2 - v3 - !!(flg&CF));
K_IMPL_ALU(sbo, v2 - v3 - !!(flg&OF));
K_IMPL_ALU(mul, v2 * v3);
K_IMPL_ALU(div, v2 / v3);
K_IMPL_ALU(rem, v2 % v3);
//----------------------------------------------------------------------------//
IMPL_START_3(ksal)
{
long w2 = v2;
long w3 = v3;
w2 <<= w3;
v1 = (ulong)w2;
}
IMPL_OUT;
IMPL_START_3(ksar)
{
long w2 = v2;
long w3 = v3;
w2 >>= w3;
v1 = (ulong)w2;
}
IMPL_OUT;
//----------------------------------------------------------------------------//

View File

@ -55,6 +55,9 @@ struct ctx_t
// Instruction table
instr_t *i;
// Instruction currently executing
instr_t *cur_in;
// Memory and memory size
ushort *mp;
ulong mz;
@ -73,6 +76,9 @@ struct ctx_t
// Last COND field
uint cond;
// Dumpinstr switch
bool dumpsw;
};
#define R(X) ctx->rf[X]

View File

@ -187,6 +187,7 @@ void decode(ctx_t *ctx)
}
in = &ctx->i[w1];
ctx->cur_in = in;
if (!nomore)
{

View File

@ -157,3 +157,4 @@ err:
devdetach(ctx, dev);
return -1;
}

View File

@ -10,6 +10,7 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
va_list ap;
ulong handler;
uint code = _code;
uint effcode;
ulong orig_frame;
@ -40,18 +41,23 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
//
if (idt[code] == 0)
{
if (code < 512 && code != E_DBF)
handler = idt[0];
if (code == E_DBF)
effcode = E_DBF;
if (code < 512)
effcode = 0;
else if (code < 768)
handler = idt[512];
effcode = 512;
else
handler = idt[768];
effcode = 768;
}
else
handler = idt[code];
effcode = code;
handler = idt[effcode];
// Found nothing?
if (handler == 0)
@ -68,7 +74,7 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
if (code < 512)
_except(ctx, E_DBF, "Double Fault; previously handling: #%u", code);
// XXX Queue TRAPs and INTs
// Todo: queue INTs
else
goto actually_die;
}
@ -81,14 +87,16 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
ctx->rf = rfs[handler];
rfs_current_idx = handler;
rx2 = 0;
fc2 = 0;
rax = code;
R(CR6) = rip;
R(CR7) = orig_frame;
idt_handling[code]++;
idt_handling[effcode]++;
longjmp(exc_jmp_buf, code);
__builtin_unreachable();
}
actually_die:

View File

@ -60,8 +60,8 @@ void exec_instr(ctx_t *ctx,
ctx->ninstrs++;
// Current frame instruction counter
rx2++; // since last frame change
rx1++; // since startup
fc2++; // since last frame change
fc1++; // since startup
//
// For REPs we evaluate the condition AFTER running the instruction,
@ -71,9 +71,8 @@ void exec_instr(ctx_t *ctx,
if (!rep && !eval_cond(ctx, ctx->cond))
return;
#ifndef NDEBUG
dump_instr(ctx, in, p1, p2, p3, lock, rep);
#endif
if (ctx->dumpsw)
dump_instr(ctx, in, p1, p2, p3, lock, rep);
do_rep:
@ -138,9 +137,10 @@ do_rep:
ctx->ninstrs++;
#ifndef NDEBUG
#if 0
// Show that we're REP'ing
dump_instr(ctx, in, p1, p2, p3, lock, rep);
if (ctx->dumpsw)
dump_instr(ctx, in, p1, p2, p3, lock, rep);
#endif
goto do_rep;

View File

@ -79,6 +79,7 @@ int main(int argc, char **argv)
main_ctx.r = arch_r;
main_ctx.i = arch_i;
main_ctx.dumpsw = 1;
//
// srand

View File

@ -5,137 +5,41 @@
reg_t arch_r[] =
{
{ "inv", RES },
{ "flg", GPR },
{ "rip", GPR },
{ "rpc", GPR },
{ "px0", RES },
{ "px1", RES },
{ "fc1", RES },
{ "fc2", RES },
{ "sa0", SYS },
{ "sa1", SYS },
{ "sa2", SYS },
{ "sa3", SYS },
{ "sa4", SYS },
{ "sa5", SYS },
{ "sa6", SYS },
{ "sa7", SYS },
{ "dr0", SYS },
{ "dr1", SYS },
{ "dr2", SYS },
{ "dr3", SYS },
{ "dr4", SYS },
{ "dr5", SYS },
{ "dr6", SYS },
{ "dr7", SYS },
{ "cr0", CTL },
{ "cr1", CTL },
{ "cr2", CTL },
{ "cr3", CTL },
{ "cr4", CTL },
{ "cr5", CTL },
{ "cr6", CTL },
{ "cr7", CTL },
{ "inv", RES }, { "flg", GPR }, { "rip", GPR }, { "rpc", GPR },
{ "px0", RES }, { "px1", RES }, { "fc1", RES }, { "fc2", RES },
{ "sa0", SYS }, { "sa1", SYS }, { "sa2", SYS }, { "sa3", SYS },
{ "sa4", SYS }, { "sa5", SYS }, { "sa6", SYS }, { "sa7", SYS },
{ "dr0", SYS }, { "dr1", SYS }, { "dr2", SYS }, { "dr3", SYS },
{ "dr4", SYS }, { "dr5", SYS }, { "dr6", SYS }, { "dr7", SYS },
{ "cr0", CTL }, { "cr1", CTL }, { "cr2", CTL }, { "cr3", CTL },
{ "cr4", CTL }, { "cr5", CTL }, { "cr6", CTL }, { "cr7", CTL },
{ "rax", GPR },
{ "rbx", GPR },
{ "rcx", GPR },
{ "rdx", GPR },
{ "rsi", GPR },
{ "rdi", GPR },
{ "rbp", GPR },
{ "rsp", GPR },
{ "rx8", GPR },
{ "rx9", GPR },
{ "r10", GPR },
{ "r11", GPR },
{ "r12", GPR },
{ "r13", GPR },
{ "r14", GPR },
{ "r15", GPR },
{ "r16", GPR },
{ "r17", GPR },
{ "r18", GPR },
{ "r19", GPR },
{ "r20", GPR },
{ "r21", GPR },
{ "r22", GPR },
{ "r23", GPR },
{ "r24", GPR },
{ "r25", GPR },
{ "r26", GPR },
{ "r27", GPR },
{ "r28", GPR },
{ "r29", GPR },
{ "r30", GPR },
{ "r31", GPR },
{ "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR },
{ "rsi", GPR }, { "rdi", GPR }, { "rbp", GPR }, { "rsp", GPR },
{ "rx8", GPR }, { "rx9", GPR }, { "r10", GPR }, { "r11", GPR },
{ "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR },
{ "r16", GPR }, { "r17", GPR }, { "r18", GPR }, { "r19", GPR },
{ "r20", GPR }, { "r21", GPR }, { "r22", GPR }, { "r23", GPR },
{ "r24", GPR }, { "r25", GPR }, { "r26", GPR }, { "r27", GPR },
{ "r28", GPR }, { "r29", GPR }, { "r30", GPR }, { "r31", GPR },
{ "ax0", GPR },
{ "ax1", GPR },
{ "ax2", GPR },
{ "ax3", GPR },
{ "ax4", GPR },
{ "ax5", GPR },
{ "ax6", GPR },
{ "ax7", GPR },
{ "ax8", GPR },
{ "ax9", GPR },
{ "a10", GPR },
{ "a11", GPR },
{ "a12", GPR },
{ "a13", GPR },
{ "a14", GPR },
{ "a15", GPR },
{ "a16", GPR },
{ "a17", GPR },
{ "a18", GPR },
{ "a19", GPR },
{ "a20", GPR },
{ "a21", GPR },
{ "a22", GPR },
{ "a23", GPR },
{ "a24", GPR },
{ "a25", GPR },
{ "a26", GPR },
{ "a27", GPR },
{ "a28", GPR },
{ "a29", GPR },
{ "a30", GPR },
{ "a31", GPR },
{ "ax0", GPR }, { "ax1", GPR }, { "ax2", GPR }, { "ax3", GPR },
{ "ax4", GPR }, { "ax5", GPR }, { "ax6", GPR }, { "ax7", GPR },
{ "ax8", GPR }, { "ax9", GPR }, { "a10", GPR }, { "a11", GPR },
{ "a12", GPR }, { "a13", GPR }, { "a14", GPR }, { "a15", GPR },
{ "a16", GPR }, { "a17", GPR }, { "a18", GPR }, { "a19", GPR },
{ "a20", GPR }, { "a21", GPR }, { "a22", GPR }, { "a23", GPR },
{ "a24", GPR }, { "a25", GPR }, { "a26", GPR }, { "a27", GPR },
{ "a28", GPR }, { "a29", GPR }, { "a30", GPR }, { "a31", GPR },
{ "nx0", GPR },
{ "nx1", GPR },
{ "nx2", GPR },
{ "nx3", GPR },
{ "nx4", GPR },
{ "nx5", GPR },
{ "nx6", GPR },
{ "nx7", GPR },
{ "nx8", GPR },
{ "nx9", GPR },
{ "n10", GPR },
{ "n11", GPR },
{ "n12", GPR },
{ "n13", GPR },
{ "n14", GPR },
{ "n15", GPR },
{ "n16", GPR },
{ "n17", GPR },
{ "n18", GPR },
{ "n19", GPR },
{ "n20", GPR },
{ "n21", GPR },
{ "n22", GPR },
{ "n23", GPR },
{ "n24", GPR },
{ "n25", GPR },
{ "n26", GPR },
{ "n27", GPR },
{ "n28", GPR },
{ "n29", GPR },
{ "n30", GPR },
{ "n31", GPR },
{ "nx0", GPR }, { "nx1", GPR }, { "nx2", GPR }, { "nx3", GPR },
{ "nx4", GPR }, { "nx5", GPR }, { "nx6", GPR }, { "nx7", GPR },
{ "nx8", GPR }, { "nx9", GPR }, { "n10", GPR }, { "n11", GPR },
{ "n12", GPR }, { "n13", GPR }, { "n14", GPR }, { "n15", GPR },
{ "n16", GPR }, { "n17", GPR }, { "n18", GPR }, { "n19", GPR },
{ "n20", GPR }, { "n21", GPR }, { "n22", GPR }, { "n23", GPR },
{ "n24", GPR }, { "n25", GPR }, { "n26", GPR }, { "n27", GPR },
{ "n28", GPR }, { "n29", GPR }, { "n30", GPR }, { "n31", GPR },
};
static_assert(NREGS <= 256, "");
@ -172,10 +76,11 @@ void dumpregs(ctx_t *ctx)
trace("\n\nrip=0x%-16lX rpc=0x%-16lX rsp=0x%-16lX rbp=0x%-16lX",
rip, rpc, rsp, rbp);
trace("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu flg=0x%-16lX",
rx0, rx1, rx2, flg);
trace("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu flg=0x%-16lX\n",
fc0, fc1, fc2, flg);
trace("\n\nCF=%x OF=%x\n"
/*
trace("\nCF=%x OF=%x\n"
"ZF=%x SF=%x\n"
"PF=%x DF=%x\n"
"IF=%x UF=%x\n",
@ -183,6 +88,7 @@ void dumpregs(ctx_t *ctx)
!!(flg&ZF), !!(flg&SF),
!!(flg&PF), !!(flg&DF),
!!(cr0&IF), !!(cr0&UF));
*/
assert(inv == 0);
}

View File

@ -62,14 +62,14 @@ enum
NREGS
};
#define rx0 ctx->ninstrs
#define fc0 ctx->ninstrs
#define inv R(INV)
#define rip R(RIP)
#define rpc R(RPC)
#define flg R(FLG)
#define rx1 R(FC1)
#define rx2 R(FC2)
#define fc1 R(FC1)
#define fc2 R(FC2)
#define cr0 R(CR0)
#define cr1 R(CR1)
#define cr2 R(CR2)

View File

@ -12,7 +12,9 @@ void enable_stdin_echoing(void)
}
void disable_stdin_echoing(void)
{return;
{
return;
struct termios t;
tcgetattr(0, &t);
t.c_lflag &= ~ECHO;