mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
flags
This commit is contained in:
parent
a0572e759f
commit
653a6e99c1
@ -330,7 +330,7 @@ def parse_instr(line):
|
||||
instr, params = params.split(' ', 1)
|
||||
size += 2
|
||||
|
||||
instr_name = instr
|
||||
instr_name = instr.replace('.', '$', 1)
|
||||
instr_args = ''
|
||||
|
||||
if params == None or len(params) == 0:
|
||||
|
@ -6,7 +6,6 @@
|
||||
;
|
||||
; Acts as itoa if unsi == 0, as utoa otherwise
|
||||
;
|
||||
|
||||
_itoa:
|
||||
mov rax, ax0
|
||||
xor rdx, rdx
|
||||
@ -14,42 +13,42 @@ _itoa:
|
||||
; make sure base is in [2, 32]
|
||||
|
||||
cmp ax2, 2
|
||||
cjmpb .bad
|
||||
jmp.b .bad
|
||||
|
||||
cmp ax2, 36
|
||||
cjmpa .bad
|
||||
jmp.a .bad
|
||||
|
||||
; deal with zero
|
||||
test ax1, ax1
|
||||
cjmpz .zero
|
||||
jmp.z .zero
|
||||
|
||||
; deal with base 10 signedness
|
||||
|
||||
test ax3, ax3 ; unsigned mode
|
||||
cjmpnz .conv
|
||||
jmp.nz .conv
|
||||
|
||||
cmp ax2, 10 ; base 10
|
||||
cjmpnz .conv
|
||||
jmp.nz .conv
|
||||
|
||||
cmp ax1, -9223372036854775808 ; LONG_MIN
|
||||
cjmpz .min
|
||||
jmp.z .min
|
||||
|
||||
sgn rdx, ax1 ; extract ax1 sign
|
||||
|
||||
cmp rdx, -1 ; negative?
|
||||
cnotz ax1 ; -x = ~x+1
|
||||
cincz ax1 ; need "neg" inst...
|
||||
not.z ax1 ; -x = ~x+1
|
||||
inc.z ax1 ; need "neg" inst...
|
||||
|
||||
; main loop
|
||||
.conv:
|
||||
test ax1, ax1
|
||||
cjmpz .fini
|
||||
jmp.z .fini
|
||||
|
||||
mov rsx, ax1
|
||||
mod rsx, ax2 ; ax1 % base
|
||||
|
||||
cmp rsx, 9 ; rsx > 9 ?
|
||||
cjmpa .nondec
|
||||
jmp.a .nondec
|
||||
|
||||
add rsx, 48 ; '0'
|
||||
jmp .next
|
||||
@ -67,8 +66,8 @@ _itoa:
|
||||
; add minus flag, null-terminate and reverse
|
||||
.fini:
|
||||
cmp rdx, -1
|
||||
cmovz b[ax0], 45 ; '-'
|
||||
cincz ax0
|
||||
mov.z b[ax0], 45 ; '-'
|
||||
inc.z ax0
|
||||
|
||||
mov b[ax0], 0
|
||||
|
||||
|
@ -33,7 +33,7 @@ main:
|
||||
|
||||
.buf = [32]
|
||||
|
||||
test:
|
||||
devtest:
|
||||
enter
|
||||
|
||||
mov ax0, .buf
|
||||
@ -49,7 +49,7 @@ test:
|
||||
|
||||
.buf = [32]
|
||||
|
||||
test1:
|
||||
strtest:
|
||||
enter
|
||||
|
||||
mov ax0, .msg
|
||||
|
@ -14,7 +14,7 @@ print:
|
||||
|
||||
.1:
|
||||
test b[ax0], b[ax0]
|
||||
cjmpz .2
|
||||
jmp.z .2
|
||||
|
||||
prn b[ax0]
|
||||
inc ax0
|
||||
|
@ -14,5 +14,5 @@ strchrnul:
|
||||
strchr:
|
||||
call strchrnul
|
||||
test b[rax], b[rax]
|
||||
cmovz rax, 0
|
||||
mov.z rax, 0
|
||||
ret
|
||||
|
@ -12,10 +12,10 @@
|
||||
|
||||
strcmp:
|
||||
cmp b[ax0], b[ax1]
|
||||
cjmpnz .1
|
||||
jmp.nz .1
|
||||
|
||||
test b[ax0], b[ax0]
|
||||
cjmpz .1
|
||||
jmp.z .1
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
@ -35,10 +35,10 @@ strncmp:
|
||||
|
||||
.1:
|
||||
cmp b[ax0], b[ax1]
|
||||
cjmpnz .1
|
||||
jmp.nz .1
|
||||
|
||||
test b[ax0], b[ax0]
|
||||
cjmpz .1
|
||||
jmp.z .1
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
|
@ -8,7 +8,7 @@ strcpy:
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
test b[ax1], b[ax1]
|
||||
cretz
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
@ -19,14 +19,14 @@ strcpy:
|
||||
;
|
||||
strncpy:
|
||||
mov rcx, ax2
|
||||
jcxz .2
|
||||
j.cxz .2
|
||||
dec rcx
|
||||
|
||||
.1:
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
test b[ax1], b[ax1]
|
||||
cretz
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
@ -40,14 +40,14 @@ strncpy:
|
||||
;
|
||||
strnzcpy:
|
||||
mov rcx, ax2
|
||||
jcxz .2
|
||||
j.cxz .2
|
||||
dec rcx
|
||||
|
||||
.1:
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
test b[ax1], b[ax1]
|
||||
cretz
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
|
@ -9,7 +9,7 @@ strlen:
|
||||
|
||||
.1:
|
||||
test b[ax0], b[ax0]
|
||||
cretz
|
||||
ret.z
|
||||
|
||||
inc rax
|
||||
inc ax0
|
||||
@ -20,13 +20,14 @@ strlen:
|
||||
;
|
||||
strnlen:
|
||||
xor rax, rax
|
||||
|
||||
mov rcx, ax1
|
||||
jcxz .2
|
||||
j.cxz .2
|
||||
dec rcx
|
||||
|
||||
.1:
|
||||
test b[ax0], b[ax0]
|
||||
cretz
|
||||
ret.z
|
||||
|
||||
inc rax
|
||||
inc ax0
|
||||
|
@ -8,8 +8,8 @@
|
||||
;
|
||||
strrev:
|
||||
test b[ax1], b[ax1]
|
||||
cmovz b[ax0], 0
|
||||
cretz
|
||||
mov.z b[ax0], 0
|
||||
ret.z
|
||||
|
||||
; save str's location
|
||||
mov rdx, ax1
|
||||
@ -18,8 +18,8 @@ strrev:
|
||||
; the null terminator
|
||||
.1:
|
||||
test b[ax1+1], b[ax1+1]
|
||||
cincnz ax1
|
||||
cjmpnz .1
|
||||
inc.nz ax1
|
||||
jmp.nz .1
|
||||
|
||||
.2:
|
||||
; copy, going backward though str
|
||||
@ -27,8 +27,8 @@ strrev:
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
cmp ax1, rdx
|
||||
cmovz b[ax0+1], 0
|
||||
cretz
|
||||
mov.z b[ax0+1], 0
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
dec ax1
|
||||
@ -42,7 +42,7 @@ strrev:
|
||||
;
|
||||
strrev2:
|
||||
test b[ax0], b[ax0]
|
||||
cretz
|
||||
ret.z
|
||||
|
||||
mov ax1, ax0
|
||||
|
||||
@ -50,13 +50,13 @@ strrev2:
|
||||
; the null terminator
|
||||
.1:
|
||||
test b[ax1+1], b[ax1+1]
|
||||
cincnz ax1
|
||||
cjmpnz .1
|
||||
inc.nz ax1
|
||||
jmp.nz .1
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.2:
|
||||
cmp ax0, ax1
|
||||
cjmpae .3
|
||||
jmp.ae .3
|
||||
|
||||
xchg b[ax0], b[ax1]
|
||||
|
||||
|
9
vm/TODO
Normal file
9
vm/TODO
Normal file
@ -0,0 +1,9 @@
|
||||
TODO
|
||||
|
||||
sal, sar
|
||||
imul, idiv
|
||||
|
||||
Flags for shl, shr, mul, div
|
||||
|
||||
Useful: https://www.felixcloutier.com/x86
|
||||
|
38
vm/in/INSTRS
38
vm/in/INSTRS
@ -9,8 +9,8 @@ nop
|
||||
#
|
||||
|
||||
!not rm
|
||||
!and rm rim
|
||||
!or rm rim
|
||||
!and rm rim
|
||||
!xor rm rim
|
||||
!shl rm rim
|
||||
!shr rm rim
|
||||
@ -19,6 +19,7 @@ nop
|
||||
# Unsigned arithmetic instructions
|
||||
#
|
||||
|
||||
!neg rm
|
||||
!inc rm
|
||||
!dec rm
|
||||
!add rm rim
|
||||
@ -30,37 +31,34 @@ nop
|
||||
|
||||
# rdx = hi(rax * $0)
|
||||
# rax = lo(rax * $0)
|
||||
!mul2 rim
|
||||
mul2 rim
|
||||
|
||||
# rdx = rax % $0
|
||||
# rax = rax / $0
|
||||
!div2 rim
|
||||
div2 rim
|
||||
|
||||
#
|
||||
# Comparison instruction
|
||||
#
|
||||
|
||||
cmp rim rim
|
||||
cmpb rim rim
|
||||
cmpw rim rim
|
||||
cmpl rim rim
|
||||
cmpt rim rim
|
||||
#cmpb rim rim
|
||||
#cmpw rim rim
|
||||
#cmpl rim rim
|
||||
#cmpt rim rim
|
||||
|
||||
test rim rim
|
||||
testb rim rim
|
||||
testw rim rim
|
||||
testl rim rim
|
||||
testt rim rim
|
||||
#testb rim rim
|
||||
#testw rim rim
|
||||
#testl rim rim
|
||||
#testt rim rim
|
||||
|
||||
#
|
||||
# Jump instructions
|
||||
#
|
||||
|
||||
!j ri
|
||||
!jmp ri
|
||||
|
||||
jcxz ri
|
||||
jcxnz ri
|
||||
|
||||
!loop ri
|
||||
|
||||
#
|
||||
@ -70,12 +68,12 @@ jcxnz ri
|
||||
!lea rm m
|
||||
!mov rm rim
|
||||
!xchg rm rim
|
||||
!cmpxchg rm rim
|
||||
cmpxchg rm rim
|
||||
|
||||
!movb rm rim
|
||||
!movw rm rim
|
||||
!movl rm rim
|
||||
!movt rm rim
|
||||
movb rm rim
|
||||
movw rm rim
|
||||
movl rm rim
|
||||
movt rm rim
|
||||
|
||||
#
|
||||
# Stack manipulation instructions
|
||||
|
@ -35,12 +35,32 @@ def doprnt(i, p1, p2, cond):
|
||||
doprnt_2(i, p1, p2)
|
||||
|
||||
if cond:
|
||||
doprnt_2('c' + i + 'z', p1, p2)
|
||||
doprnt_2('c' + i + 'a', p1, p2)
|
||||
doprnt_2('c' + i + 'b', p1, p2)
|
||||
doprnt_2('c' + i + 'nz', p1, p2)
|
||||
doprnt_2('c' + i + 'ae', p1, p2)
|
||||
doprnt_2('c' + i + 'be', p1, p2)
|
||||
doprnt_2(i + '$cxz', p1, p2)
|
||||
doprnt_2(i + '$cxnz', p1, p2)
|
||||
|
||||
doprnt_2(i + '$c', p1, p2)
|
||||
doprnt_2(i + '$o', p1, p2)
|
||||
doprnt_2(i + '$z', p1, p2)
|
||||
doprnt_2(i + '$s', p1, p2)
|
||||
doprnt_2(i + '$p', p1, p2)
|
||||
doprnt_2(i + '$e', p1, p2)
|
||||
doprnt_2(i + '$eq', p1, p2)
|
||||
|
||||
doprnt_2(i + '$a', p1, p2)
|
||||
doprnt_2(i + '$ae', p1, p2)
|
||||
doprnt_2(i + '$b', p1, p2)
|
||||
doprnt_2(i + '$be', p1, p2)
|
||||
doprnt_2(i + '$l', p1, p2)
|
||||
doprnt_2(i + '$le', p1, p2)
|
||||
doprnt_2(i + '$g', p1, p2)
|
||||
doprnt_2(i + '$ge', p1, p2)
|
||||
|
||||
doprnt_2(i + '$nc', p1, p2)
|
||||
doprnt_2(i + '$no', p1, p2)
|
||||
doprnt_2(i + '$nz', p1, p2)
|
||||
doprnt_2(i + '$ns', p1, p2)
|
||||
doprnt_2(i + '$np', p1, p2)
|
||||
doprnt_2(i + '$ne', p1, p2)
|
||||
|
||||
def doprnt_2(i, p1, p2):
|
||||
for c1 in p1:
|
||||
|
108
vm/in/arith.c
108
vm/in/arith.c
@ -14,21 +14,74 @@ IMPL_COND(mod);
|
||||
IMPL_COND(mul2);
|
||||
IMPL_COND(div2);
|
||||
|
||||
//
|
||||
// Unsigned arithmetic instructions
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_1(inc)
|
||||
{
|
||||
if (v1 == LONG_MAX) flg |= OF;
|
||||
else flg &= ~OF;
|
||||
|
||||
v1++;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_1(dec)
|
||||
{
|
||||
if (v1 == LONG_MIN) flg |= OF;
|
||||
else flg &= ~OF;
|
||||
|
||||
v1--;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(add)
|
||||
{
|
||||
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;
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(sub)
|
||||
{
|
||||
if (v1 < v2) flg |= CF;
|
||||
else flg &= ~CF;
|
||||
|
||||
if ( ((v2 < 0) && (v1 > LONG_MAX + v2))
|
||||
|| ((v2 > 0) && (v1 < LONG_MIN + v2)) )
|
||||
flg |= OF;
|
||||
else flg &= ~OF;
|
||||
|
||||
v1 -= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
//
|
||||
// i_sub but discards result
|
||||
//
|
||||
IMPL_START_2(cmp)
|
||||
{
|
||||
if (v1 < v2) flg |= CF;
|
||||
else flg &= ~CF;
|
||||
|
||||
if ( ((v2 < 0) && (v1 > LONG_MAX + v2))
|
||||
|| ((v2 > 0) && (v1 < LONG_MIN + v2)) )
|
||||
flg |= OF;
|
||||
else flg &= ~OF;
|
||||
|
||||
SET_ZSF(v1 - v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(mul)
|
||||
{
|
||||
@ -62,6 +115,8 @@ IMPL_START_1(mul2)
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(div)
|
||||
{
|
||||
v1 /= v2;
|
||||
@ -81,21 +136,36 @@ IMPL_START_1(div2)
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(inc)
|
||||
{
|
||||
v1++;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(dec)
|
||||
{
|
||||
v1--;
|
||||
}
|
||||
IMPL_OUT;
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(sgn)
|
||||
{
|
||||
v1 = (v2 ? ((long)v2 > 0 ? 1 : (ulong)-1L) : 0);
|
||||
}
|
||||
IMPL_OUT;
|
||||
if (v2 == 0) v1 = 0;
|
||||
|
||||
else if ((long)v2 > 0) {
|
||||
flg &= ~CF;
|
||||
v1 = 1;
|
||||
}
|
||||
|
||||
else {
|
||||
flg |= CF;
|
||||
v1 = (ulong)-1L;
|
||||
}
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_1(neg)
|
||||
{
|
||||
if (v1 == 0) flg |= CF;
|
||||
|
||||
else {
|
||||
flg &= ~CF;
|
||||
|
||||
if (v1 == LONG_MIN) flg |= OF;
|
||||
else flg &= ~OF;
|
||||
}
|
||||
|
||||
v1 = ~v1 + 1;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
|
47
vm/in/cond.h
Normal file
47
vm/in/cond.h
Normal file
@ -0,0 +1,47 @@
|
||||
// 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 _IMPL_IF_COND(name, suf, cond) \
|
||||
IMPL_START_0(name##$##suf) \
|
||||
{ \
|
||||
if (cond) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
IMPL_END \
|
||||
|
||||
#define IMPL_COND(name) \
|
||||
\
|
||||
_IMPL_IF_COND(name, cxz, rcx == 0); \
|
||||
_IMPL_IF_COND(name, cxnz, rcx != 0); \
|
||||
\
|
||||
_IMPL_IF_COND(name, c, flg&CF); \
|
||||
_IMPL_IF_COND(name, o, flg&OF); \
|
||||
\
|
||||
_IMPL_IF_COND(name, nc, !(flg&CF)); \
|
||||
_IMPL_IF_COND(name, no, !(flg&OF)); \
|
||||
\
|
||||
_IMPL_IF_COND(name, z, flg&ZF); \
|
||||
_IMPL_IF_COND(name, s, flg&SF); \
|
||||
_IMPL_IF_COND(name, p, flg&PF); \
|
||||
\
|
||||
_IMPL_IF_COND(name, nz, !(flg&ZF)); \
|
||||
_IMPL_IF_COND(name, ns, !(flg&SF)); \
|
||||
_IMPL_IF_COND(name, np, !(flg&PF)); \
|
||||
\
|
||||
_IMPL_IF_COND(name, e, flg&ZF); \
|
||||
_IMPL_IF_COND(name, eq, flg&ZF); \
|
||||
_IMPL_IF_COND(name, ne, !(flg&ZF)); \
|
||||
\
|
||||
_IMPL_IF_COND(name, b, flg&CF); \
|
||||
_IMPL_IF_COND(name, be, flg&ZF || flg&CF); \
|
||||
\
|
||||
_IMPL_IF_COND(name, a, !(flg&CF || flg&ZF)); \
|
||||
_IMPL_IF_COND(name, ae, !(flg&CF)); \
|
||||
\
|
||||
_IMPL_IF_COND(name, l, !!(flg&SF) != !!(flg&OF)); \
|
||||
_IMPL_IF_COND(name, le, flg&ZF || (!!(flg&SF) != !!(flg&OF))); \
|
||||
\
|
||||
_IMPL_IF_COND(name, g, !(flg&ZF) && (!!(flg&SF) == !!(flg&OF))); \
|
||||
_IMPL_IF_COND(name, ge, !!(flg&SF) == !!(flg&OF)); \
|
||||
|
@ -20,3 +20,8 @@ IMPL_START_1(step)
|
||||
ctx->step = !!v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(err)
|
||||
{
|
||||
}
|
||||
IMPL_END;
|
||||
|
21
vm/in/flags.h
Normal file
21
vm/in/flags.h
Normal file
@ -0,0 +1,21 @@
|
||||
// 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 SET_ZF(v) \
|
||||
flg = ((v) == 0 ? (flg|ZF) : (flg&~ZF))
|
||||
|
||||
#define SET_SF(v) \
|
||||
flg = ((long)(v) < 0 ? (flg|SF) : (flg&~SF))
|
||||
|
||||
#define SET_PF(v) \
|
||||
flg = (__builtin_parity(v) == 1 ? (flg|PF) : (flg&~PF))
|
||||
|
||||
#define SET_ZSF(v) \
|
||||
SET_ZF(v); \
|
||||
SET_SF(v)
|
||||
|
||||
#define _SET_ZSPF(v) \
|
||||
SET_ZF(v); \
|
||||
SET_SF(v); \
|
||||
SET_PF(v)
|
||||
|
@ -2,6 +2,9 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include <pc/arch.h>
|
||||
|
||||
#include <in/cond.h>
|
||||
#include <in/flags.h>
|
||||
#include <in/arch_i.h>
|
||||
|
||||
#define DECV(p, v) \
|
||||
@ -30,6 +33,10 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
|
||||
{ \
|
||||
DECV(p2, v2);
|
||||
|
||||
#define IMPL_OUT_ZSF \
|
||||
SET_ZSF(v1); \
|
||||
IMPL_OUT
|
||||
|
||||
#define IMPL_OUT \
|
||||
assert(p1->type == A_REG || p1->mem); \
|
||||
if (p1->mem) { \
|
||||
@ -58,72 +65,6 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
|
||||
#define IMPL_END \
|
||||
}
|
||||
|
||||
//
|
||||
// c...z instructions easy implementation
|
||||
//
|
||||
|
||||
#define IMPL_CxxxZ(name) \
|
||||
IMPL_START_0(c##name##z) \
|
||||
{ \
|
||||
if (flg & ZF) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
IMPL_END
|
||||
|
||||
#define IMPL_CxxxNZ(name) \
|
||||
IMPL_START_0(c##name##nz) \
|
||||
{ \
|
||||
if (!(flg & ZF)) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
IMPL_END
|
||||
|
||||
#define IMPL_CxxxA(name) \
|
||||
IMPL_START_0(c##name##a) \
|
||||
{ \
|
||||
if (!(flg & ZF) && !(flg & CF)) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
IMPL_END
|
||||
|
||||
#define IMPL_CxxxAE(name) \
|
||||
IMPL_START_0(c##name##ae) \
|
||||
{ \
|
||||
if (!(flg & CF)) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
IMPL_END
|
||||
|
||||
#define IMPL_CxxxB(name) \
|
||||
IMPL_START_0(c##name##b) \
|
||||
{ \
|
||||
if (!(flg & ZF) && (flg & CF)) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
IMPL_END
|
||||
|
||||
#define IMPL_CxxxBE(name) \
|
||||
IMPL_START_0(c##name##be) \
|
||||
{ \
|
||||
if (flg & CF) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
IMPL_END
|
||||
|
||||
#define IMPL_COND(name) \
|
||||
IMPL_CxxxZ(name); \
|
||||
IMPL_CxxxA(name); \
|
||||
IMPL_CxxxB(name); \
|
||||
IMPL_CxxxNZ(name); \
|
||||
IMPL_CxxxAE(name); \
|
||||
IMPL_CxxxBE(name)
|
||||
|
||||
//
|
||||
// Consistency checks
|
||||
//
|
||||
@ -143,7 +84,6 @@ IMPL_END
|
||||
_except(ctx, E_STK, "RSP above RBP"); \
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Common operations
|
||||
//
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <in/instrs.h>
|
||||
|
||||
IMPL_COND(j);
|
||||
IMPL_COND(jmp);
|
||||
IMPL_COND(loop);
|
||||
|
||||
@ -10,6 +11,12 @@ IMPL_COND(loop);
|
||||
// Jump instructions
|
||||
//
|
||||
|
||||
IMPL_START_1(j)
|
||||
{
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jmp)
|
||||
{
|
||||
JUMP(v1);
|
||||
@ -25,17 +32,3 @@ IMPL_START_1(loop)
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jcxz)
|
||||
{
|
||||
if (!rcx)
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jcxnz)
|
||||
{
|
||||
if (rcx)
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
|
115
vm/in/logic.c
115
vm/in/logic.c
@ -10,135 +10,52 @@ IMPL_COND(xor);
|
||||
IMPL_COND(shl);
|
||||
IMPL_COND(shr);
|
||||
|
||||
#define CMP(v1, v2) \
|
||||
if (v1 == v2) { \
|
||||
flg |= ZF; \
|
||||
flg &= ~CF; \
|
||||
} \
|
||||
else if (v1 < v2) { \
|
||||
flg &= ~ZF; \
|
||||
flg |= CF; \
|
||||
} \
|
||||
else { \
|
||||
flg &= ~ZF; \
|
||||
flg &= ~CF; \
|
||||
}
|
||||
|
||||
//
|
||||
// Comparison instructions
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(test)
|
||||
{
|
||||
ulong v = v1 & v2;
|
||||
|
||||
CMP(v, 0);
|
||||
flg &= ~OF;
|
||||
flg &= ~CF;
|
||||
SET_ZSF(v1 & v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(testb)
|
||||
{
|
||||
ulong v = v1 & v2 & 0x00000000000000FF;
|
||||
|
||||
CMP(v, 0);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(testw)
|
||||
{
|
||||
ulong v = v1 & v2 & 0x000000000000FFFF;
|
||||
|
||||
CMP(v, 0);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(testl)
|
||||
{
|
||||
ulong v = v1 & v2 & 0x00000000FFFFFFFF;
|
||||
|
||||
CMP(v, 0);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(testt)
|
||||
{
|
||||
ulong v = v1 & v2 & 0x0000FFFFFFFFFFFF;
|
||||
|
||||
CMP(v, 0);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(cmp)
|
||||
{
|
||||
CMP(v1, v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(cmpb)
|
||||
{
|
||||
v1 &= 0x00000000000000FF;
|
||||
v2 &= 0x00000000000000FF;
|
||||
CMP(v1, v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(cmpw)
|
||||
{
|
||||
v1 &= 0x000000000000FFFF;
|
||||
v2 &= 0x000000000000FFFF;
|
||||
CMP(v1, v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(cmpl)
|
||||
{
|
||||
v1 &= 0x00000000FFFFFFFF;
|
||||
v2 &= 0x00000000FFFFFFFF;
|
||||
CMP(v1, v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(cmpt)
|
||||
{
|
||||
v1 &= 0x0000FFFFFFFFFFFF;
|
||||
v2 &= 0x0000FFFFFFFFFFFF;
|
||||
CMP(v1, v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//
|
||||
// Logical instructions
|
||||
//
|
||||
|
||||
IMPL_START_2(and)
|
||||
{
|
||||
flg &= ~OF;
|
||||
flg &= ~CF;
|
||||
v1 &= v2;
|
||||
|
||||
}
|
||||
IMPL_OUT;
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(or)
|
||||
{
|
||||
flg &= ~OF;
|
||||
flg &= ~CF;
|
||||
v1 |= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(xor)
|
||||
{
|
||||
flg &= ~OF;
|
||||
flg &= ~CF;
|
||||
v1 ^= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(shl)
|
||||
{
|
||||
v1 <<= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(shr)
|
||||
{
|
||||
v1 >>= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_1(not)
|
||||
{
|
||||
|
@ -46,7 +46,7 @@
|
||||
<pattern-item _name="Instructions" style="def:keyword" case-sensitive="FALSE"
|
||||
match-empty-string-at-beginning = "TRUE"
|
||||
match-empty-string-at-end = "TRUE">
|
||||
<regex>^\s+[a-zA-Z_]{2,}</regex>
|
||||
<regex>^\s+[a-zA-Z0-9_.$%]{2,}</regex>
|
||||
</pattern-item>
|
||||
|
||||
<keyword-list _name="Registers K" style="def:type"
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
|
||||
#undef dev_t
|
||||
#define packed __attribute__ ((__packed__))
|
||||
|
17
vm/pc/regs.c
17
vm/pc/regs.c
@ -76,8 +76,6 @@ void dumpregs(ctx_t *ctx)
|
||||
int i;
|
||||
reg_t *r;
|
||||
|
||||
assert(ctx->r[INV].val == 0);
|
||||
|
||||
log("\nRegisters:");
|
||||
|
||||
for (i = RAX; i < CR4; i++) {
|
||||
@ -88,7 +86,18 @@ void dumpregs(ctx_t *ctx)
|
||||
log("%s%s=0x%-16lX ", r->name,
|
||||
(strlen(r->name) == 2 ? "=" : ""), r->val);
|
||||
}
|
||||
log("\nrip=0x%-16lX rbp=0x%-16lX rsp=0x%-16lX flg=0x%-16lX\n",
|
||||
rip, rbp, rsp, flg);
|
||||
log("\nrip=0x%-16lX rbp=0x%-16lX rsp=0x%-16lX inv=0x%-16lX\n",
|
||||
rip, rbp, rsp, inv);
|
||||
|
||||
log("\nFlags: 0x%-16lX\n", flg);
|
||||
|
||||
log("CF=%-4x OF=%-4x\n"
|
||||
"ZF=%-4x SF=%-4x\n"
|
||||
"PF=%-4x DF=%-4x\n"
|
||||
"IF=%-4x UF=%-4x\n",
|
||||
!!(flg&CF), !!(flg&OF),
|
||||
!!(flg&ZF), !!(flg&SF),
|
||||
!!(flg&PF), !!(flg&DF),
|
||||
!!(flg&IF), !!(cr0&UF));
|
||||
}
|
||||
|
||||
|
12
vm/pc/regs.h
12
vm/pc/regs.h
@ -4,6 +4,7 @@
|
||||
enum
|
||||
{
|
||||
INV,
|
||||
#define inv R(INV)
|
||||
|
||||
RIP, FLG, RBP, RSP,
|
||||
#define rip R(RIP)
|
||||
@ -83,12 +84,13 @@ enum
|
||||
enum
|
||||
{
|
||||
CF = 1 << 0, // Carry flag
|
||||
PF = 1 << 1, // Parity flag
|
||||
AC = 1 << 2, // Auxiliary flag
|
||||
ZF = 1 << 3, // Zero flag
|
||||
OV = 1 << 4, // Overflow flag
|
||||
OF = 1 << 1, // Overflow flag
|
||||
|
||||
ZF = 1 << 2, // Zero flag
|
||||
SF = 1 << 3, // Sign flag
|
||||
|
||||
PF = 1 << 4, // Parity flag
|
||||
DF = 1 << 5, // Direction flag
|
||||
SF = 1 << 6, // Sign flag
|
||||
|
||||
UF = 1 << 16, // User-mode flag
|
||||
IF = 1 << 17, // Interrupts enable flag
|
||||
|
Loading…
Reference in New Issue
Block a user