1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
This commit is contained in:
julianb0 2019-06-06 22:07:34 +02:00
parent a0572e759f
commit 653a6e99c1
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
23 changed files with 307 additions and 275 deletions

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@ print:
.1:
test b[ax0], b[ax0]
cjmpz .2
jmp.z .2
prn b[ax0]
inc ax0

View File

@ -14,5 +14,5 @@ strchrnul:
strchr:
call strchrnul
test b[rax], b[rax]
cmovz rax, 0
mov.z rax, 0
ret

View File

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

View File

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

View File

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

View File

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

@ -0,0 +1,9 @@
TODO
sal, sar
imul, idiv
Flags for shl, shr, mul, div
Useful: https://www.felixcloutier.com/x86

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,6 +12,7 @@
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <limits.h>
#undef dev_t
#define packed __attribute__ ((__packed__))

View File

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

View File

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