mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
INSTRS
This commit is contained in:
parent
710d2ca3f9
commit
b6c4f3b8d3
@ -103,6 +103,8 @@ struct ctx_t
|
||||
FILE *disf;
|
||||
};
|
||||
|
||||
#define R(X) ctx->r[X].val
|
||||
|
||||
static inline ushort bswap16(ushort u)
|
||||
{ return ((u<<8) | (u>>8)); }
|
||||
|
||||
|
11
pc/decd.c
11
pc/decd.c
@ -93,7 +93,7 @@ void disasm(ctx_t *ctx)
|
||||
acc_t p1 = { 0 }, p2 = { 0 };
|
||||
|
||||
uint rep = 0;
|
||||
ulong rip = ctx->r[RIP].val;
|
||||
ulong orig_rip = rip;
|
||||
ushort c = ctx->get(ctx);
|
||||
|
||||
if (ISPREF(c)) {
|
||||
@ -118,17 +118,16 @@ void disasm(ctx_t *ctx)
|
||||
}
|
||||
|
||||
#ifdef _NEED_DISASM
|
||||
dumpinstr(ctx, rip, rep, c, &p1, &p2);
|
||||
dumpinstr(ctx, orig_rip, rep, c, &p1, &p2);
|
||||
#else
|
||||
|
||||
do_rep:
|
||||
dumpinstr(ctx, rip, rep, c, &p1, &p2);
|
||||
dumpinstr(ctx, orig_rip, rep, c, &p1, &p2);
|
||||
i->func(ctx, &p1, &p2);
|
||||
|
||||
|
||||
if (rep && ctx->r[RCX].val > 0) {
|
||||
log("rcx::%lu\n", ctx->r[RCX].val);
|
||||
ctx->r[RCX].val--;
|
||||
if (rep && rcx > 0) {
|
||||
rcx--;
|
||||
goto do_rep;
|
||||
}
|
||||
|
||||
|
@ -44,13 +44,13 @@ void d_log(ctx_t *ctx, char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void dumpinstr(ctx_t *ctx, ulong rip, uint rep,
|
||||
void dumpinstr(ctx_t *ctx, ulong _rip, uint rep,
|
||||
ushort c, acc_t *p1, acc_t *p2)
|
||||
{
|
||||
acc_t *p = 0;
|
||||
instr_t *i = &ctx->i[c];
|
||||
|
||||
d_log(ctx, "0x%08lX: %s%s", rip,
|
||||
d_log(ctx, "0x%08lX: %s%s", _rip,
|
||||
(rep ? "rep " : ""),
|
||||
i->name);
|
||||
|
||||
|
400
pc/instrs/INSTRS
400
pc/instrs/INSTRS
@ -8,361 +8,137 @@ nop
|
||||
# Logical instructions
|
||||
#
|
||||
|
||||
not r
|
||||
not m
|
||||
cnotz r
|
||||
cnotz m
|
||||
cnotnz r
|
||||
cnotnz m
|
||||
not rm
|
||||
and rm rim
|
||||
or rm rim
|
||||
xor rm rim
|
||||
shl rm rim
|
||||
shr rm rim
|
||||
|
||||
and r r
|
||||
and r i
|
||||
and r m
|
||||
and m r
|
||||
and m i
|
||||
and m m
|
||||
cnotz rm
|
||||
candz rm rim
|
||||
corz rm rim
|
||||
cxorz rm rim
|
||||
cshlz rm rim
|
||||
cshrz rm rim
|
||||
|
||||
candz r r
|
||||
candz r i
|
||||
candz r m
|
||||
candz m r
|
||||
candz m i
|
||||
candz m m
|
||||
|
||||
candnz r r
|
||||
candnz r i
|
||||
candnz r m
|
||||
candnz m r
|
||||
candnz m i
|
||||
candnz m m
|
||||
|
||||
or r r
|
||||
or r i
|
||||
or r m
|
||||
or m r
|
||||
or m i
|
||||
or m m
|
||||
|
||||
corz r r
|
||||
corz r i
|
||||
corz r m
|
||||
corz m r
|
||||
corz m i
|
||||
corz m m
|
||||
|
||||
cornz r r
|
||||
cornz r i
|
||||
cornz r m
|
||||
cornz m r
|
||||
cornz m i
|
||||
cornz m m
|
||||
|
||||
xor r r
|
||||
xor r i
|
||||
xor r m
|
||||
xor m r
|
||||
xor m i
|
||||
xor m m
|
||||
|
||||
cxorz r r
|
||||
cxorz r i
|
||||
cxorz r m
|
||||
cxorz m r
|
||||
cxorz m i
|
||||
cxorz m m
|
||||
|
||||
cxornz r r
|
||||
cxornz r i
|
||||
cxornz r m
|
||||
cxornz m r
|
||||
cxornz m i
|
||||
cxornz m m
|
||||
|
||||
# shift left logical
|
||||
shl r r
|
||||
shl r i
|
||||
shl r m
|
||||
shl m r
|
||||
shl m i
|
||||
shl m m
|
||||
|
||||
cshlz r r
|
||||
cshlz r i
|
||||
cshlz r m
|
||||
cshlz m r
|
||||
cshlz m i
|
||||
cshlz m m
|
||||
|
||||
cshlnz r r
|
||||
cshlnz r i
|
||||
cshlnz r m
|
||||
cshlnz m r
|
||||
cshlnz m i
|
||||
cshlnz m m
|
||||
|
||||
# shift right logical
|
||||
shr r r
|
||||
shr r i
|
||||
shr r m
|
||||
shr m r
|
||||
shr m i
|
||||
shr m m
|
||||
|
||||
cshrz r r
|
||||
cshrz r i
|
||||
cshrz r m
|
||||
cshrz m r
|
||||
cshrz m i
|
||||
cshrz m m
|
||||
|
||||
cshrnz r r
|
||||
cshrnz r i
|
||||
cshrnz r m
|
||||
cshrnz m r
|
||||
cshrnz m i
|
||||
cshrnz m m
|
||||
cnotnz rm
|
||||
candnz rm rim
|
||||
cornz rm rim
|
||||
cxornz rm rim
|
||||
cshlnz rm rim
|
||||
cshrnz rm rim
|
||||
|
||||
#
|
||||
# Unsigned arithmetic instructions
|
||||
#
|
||||
|
||||
add r r
|
||||
add r i
|
||||
add r m
|
||||
add m r
|
||||
add m i
|
||||
add m m
|
||||
|
||||
caddz r r
|
||||
caddz r i
|
||||
caddz r m
|
||||
caddz m r
|
||||
caddz m i
|
||||
caddz m m
|
||||
|
||||
caddnz r r
|
||||
caddnz r i
|
||||
caddnz r m
|
||||
caddnz m r
|
||||
caddnz m i
|
||||
caddnz m m
|
||||
|
||||
sub r r
|
||||
sub r i
|
||||
sub r m
|
||||
sub m r
|
||||
sub m i
|
||||
sub m m
|
||||
|
||||
csubz r r
|
||||
csubz r i
|
||||
csubz r m
|
||||
csubz m r
|
||||
csubz m i
|
||||
csubz m m
|
||||
|
||||
csubnz r r
|
||||
csubnz r i
|
||||
csubnz r m
|
||||
csubnz m r
|
||||
csubnz m i
|
||||
csubnz m m
|
||||
|
||||
# mul:
|
||||
# rdx = hi(rax * $0)
|
||||
# rax = lo(rax * $0)
|
||||
mul r
|
||||
mul i
|
||||
cmulz r
|
||||
cmulz i
|
||||
cmulnz r
|
||||
cmulnz i
|
||||
|
||||
# div:
|
||||
# rdx = rax % $0
|
||||
# rax = rax / $0
|
||||
div r
|
||||
div i
|
||||
cdivz r
|
||||
cdivz i
|
||||
cdivnz r
|
||||
cdivnz i
|
||||
|
||||
inc r
|
||||
inc m
|
||||
cincz r
|
||||
cincz m
|
||||
cincnz r
|
||||
cincnz m
|
||||
sgn rm rim
|
||||
add rm rim
|
||||
sub rm rim
|
||||
mul rim
|
||||
div rim
|
||||
inc rm
|
||||
dec rm
|
||||
|
||||
dec r
|
||||
dec m
|
||||
cdecz r
|
||||
cdecz m
|
||||
cdecnz r
|
||||
cdecnz m
|
||||
csgnz rm rim
|
||||
caddz rm rim
|
||||
csubz rm rim
|
||||
cmulz rim
|
||||
cdivz rim
|
||||
cincz rm
|
||||
cdecz rm
|
||||
|
||||
sgn r r
|
||||
sgn r i
|
||||
sgn r m
|
||||
sgn m r
|
||||
sgn m i
|
||||
sgn m m
|
||||
|
||||
csgnz r r
|
||||
csgnz r i
|
||||
csgnz r m
|
||||
csgnz m r
|
||||
csgnz m i
|
||||
csgnz m m
|
||||
|
||||
csgnnz r r
|
||||
csgnnz r i
|
||||
csgnnz r m
|
||||
csgnnz m r
|
||||
csgnnz m i
|
||||
csgnnz m m
|
||||
csgnnz rm rim
|
||||
caddnz rm rim
|
||||
csubnz rm rim
|
||||
cmulnz rim
|
||||
cdivnz rim
|
||||
cincnz rm
|
||||
cdecnz rm
|
||||
|
||||
#
|
||||
# Comparison instruction
|
||||
#
|
||||
|
||||
# Affects ZF and CF
|
||||
cmp r r
|
||||
cmp r i
|
||||
cmp r m
|
||||
cmp i r
|
||||
cmp i i
|
||||
cmp i m
|
||||
cmp m r
|
||||
cmp m i
|
||||
cmp m m
|
||||
cmp rim rim
|
||||
cmpb rim rim
|
||||
cmpw rim rim
|
||||
cmpl rim rim
|
||||
cmpt rim rim
|
||||
|
||||
# Only affects ZF
|
||||
test r r
|
||||
test r i
|
||||
test r m
|
||||
test i r
|
||||
test i i
|
||||
test i m
|
||||
test m r
|
||||
test m i
|
||||
test m m
|
||||
test rim rim
|
||||
testb rim rim
|
||||
testw rim rim
|
||||
testl rim rim
|
||||
testt rim rim
|
||||
|
||||
#
|
||||
# Jump instructions
|
||||
#
|
||||
|
||||
jmp r
|
||||
jmp i
|
||||
jmp ri
|
||||
|
||||
cjmpz r
|
||||
cjmpz i
|
||||
cjmpnz r
|
||||
cjmpnz i
|
||||
cjmpz ri
|
||||
cjmpnz ri
|
||||
|
||||
cjmpa r
|
||||
cjmpa i
|
||||
cjmpae r
|
||||
cjmpae i
|
||||
cjmpa ri
|
||||
cjmpae ri
|
||||
|
||||
cjmpb r
|
||||
cjmpb i
|
||||
cjmpbe r
|
||||
cjmpbe i
|
||||
cjmpb ri
|
||||
cjmpbe ri
|
||||
|
||||
jcxz r
|
||||
jcxz i
|
||||
jcxnz r
|
||||
jcxnz i
|
||||
jcxz ri
|
||||
jcxnz ri
|
||||
|
||||
loop r
|
||||
loop i
|
||||
cloopz r
|
||||
cloopz i
|
||||
cloopnz r
|
||||
cloopnz i
|
||||
loop ri
|
||||
cloopz ri
|
||||
cloopnz ri
|
||||
|
||||
#
|
||||
# Movement instructions
|
||||
#
|
||||
|
||||
mov r r
|
||||
mov r i
|
||||
mov r m
|
||||
mov m r
|
||||
mov m i
|
||||
mov m m
|
||||
cmovz r r
|
||||
cmovz r i
|
||||
cmovz r m
|
||||
cmovz m r
|
||||
cmovz m i
|
||||
cmovz m m
|
||||
cmovnz r r
|
||||
cmovnz r i
|
||||
cmovnz r m
|
||||
cmovnz m r
|
||||
cmovnz m i
|
||||
cmovnz m m
|
||||
lea rm m
|
||||
mov rm rim
|
||||
xchg rm rim
|
||||
cmpxchg rm rim
|
||||
|
||||
xchg r r
|
||||
xchg r i
|
||||
xchg r m
|
||||
xchg m r
|
||||
xchg m i
|
||||
xchg m m
|
||||
cxchgz r r
|
||||
cxchgz r i
|
||||
cxchgz r m
|
||||
cxchgz m r
|
||||
cxchgz m i
|
||||
cxchgz m m
|
||||
cxchgnz r r
|
||||
cxchgnz r i
|
||||
cxchgnz r m
|
||||
cxchgnz m r
|
||||
cxchgnz m i
|
||||
cxchgnz m m
|
||||
cleaz rm m
|
||||
cmovz rm rim
|
||||
cxchgz rm rim
|
||||
ccmpxchgz rm rim
|
||||
|
||||
lea r m
|
||||
lea m m
|
||||
cleaz r m
|
||||
cleaz m m
|
||||
cleanz r m
|
||||
cleanz m m
|
||||
cleanz rm m
|
||||
cmovnz rm rim
|
||||
cxchgnz rm rim
|
||||
ccmpxchgnz rm rim
|
||||
|
||||
#
|
||||
# Stack manipulation instructions
|
||||
#
|
||||
|
||||
push i
|
||||
push r
|
||||
push m
|
||||
cpushz i
|
||||
cpushz r
|
||||
cpushz m
|
||||
cpushnz i
|
||||
cpushnz r
|
||||
cpushnz m
|
||||
|
||||
pop r
|
||||
pop m
|
||||
cpopz r
|
||||
cpopz m
|
||||
cpopnz r
|
||||
cpopnz m
|
||||
|
||||
call r
|
||||
call i
|
||||
call m
|
||||
ccallz r
|
||||
ccallz i
|
||||
ccallz m
|
||||
ccallnz r
|
||||
ccallnz i
|
||||
ccallnz m
|
||||
|
||||
push rim
|
||||
call rim
|
||||
pop rm
|
||||
ret
|
||||
|
||||
cpushz rim
|
||||
ccallz rim
|
||||
cpopz rm
|
||||
cretz
|
||||
|
||||
cpushnz rim
|
||||
ccallnz rim
|
||||
cpopnz rm
|
||||
cretnz
|
||||
|
||||
# push rbp
|
||||
@ -391,9 +167,7 @@ sti
|
||||
#
|
||||
|
||||
# Prints a character on the screen
|
||||
prn r
|
||||
prn i
|
||||
prn m
|
||||
prn rim
|
||||
|
||||
#
|
||||
# Debugging instructions
|
||||
|
@ -3,6 +3,8 @@
|
||||
# The OS/K Team licenses this file to you under the MIT license.
|
||||
# See the LICENSE file in the project root for more information.
|
||||
|
||||
from tempfile import TemporaryFile
|
||||
|
||||
fi = open("INSTRS")
|
||||
hd = open("arch_i.h", "w")
|
||||
ls = open("instrs.lst", "w")
|
||||
@ -15,6 +17,8 @@ hd.write("#ifdef _NEED_ARCH_I\n")
|
||||
hd.write("instr_t arch_i[] =\n{\n\n")
|
||||
hd.write("#endif\n")
|
||||
|
||||
fp = TemporaryFile(mode="w+")
|
||||
|
||||
def getflag(s):
|
||||
if s == "r":
|
||||
return "P_REG"
|
||||
@ -27,12 +31,42 @@ def getflag(s):
|
||||
|
||||
return "__ERROR__"
|
||||
|
||||
# "instr ri ri" => "instr r r\ninstr r i\ninstr i r..."
|
||||
# not optimal but will do for now
|
||||
for _, line in enumerate(fi):
|
||||
if line[0] == '#' or line[0] == ' ' or line[0] == '\n':
|
||||
continue
|
||||
|
||||
tok = line.strip().split(' ')
|
||||
|
||||
if len(tok) == 0:
|
||||
continue
|
||||
|
||||
i = tok[0].strip()
|
||||
|
||||
if len(tok) == 1:
|
||||
fp.write("{}\n".format(i))
|
||||
continue
|
||||
|
||||
if len(tok) == 2:
|
||||
p = tok[1].strip()
|
||||
for c in p:
|
||||
fp.write("{} {}\n".format(i, c))
|
||||
continue
|
||||
|
||||
assert(len(tok) == 3)
|
||||
|
||||
p1 = tok[1].strip()
|
||||
p2 = tok[2].strip()
|
||||
|
||||
for c1 in p1:
|
||||
for c2 in p2:
|
||||
fp.write("{} {} {}\n".format(i, c1, c2))
|
||||
|
||||
fp.seek(0)
|
||||
for _, line in enumerate(fp):
|
||||
tok = line.strip().split(' ')
|
||||
|
||||
if len(tok) == 1:
|
||||
name = tok[0]
|
||||
p1 = "NOPRM"
|
||||
|
@ -32,7 +32,7 @@ IMPL_START_1(mul)
|
||||
{
|
||||
// Adapted from www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
|
||||
ulong v2 = v1;
|
||||
v1 = ctx->r[RAX].val;
|
||||
v1 = rax;
|
||||
|
||||
ulong u1 = (v1 & 0xffffffff);
|
||||
ulong u2 = (v2 & 0xffffffff);
|
||||
@ -49,15 +49,15 @@ IMPL_START_1(mul)
|
||||
t = (u1 * v2) + k;
|
||||
k = (t >> 32);
|
||||
|
||||
ctx->r[RDX].val = (v1 * v2) + w1 + k;
|
||||
ctx->r[RAX].val = (t << 32) + w3;
|
||||
rdx = (v1 * v2) + w1 + k;
|
||||
rax = (t << 32) + w3;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(div)
|
||||
{
|
||||
ctx->r[RDX].val = ctx->r[RAX].val % v1;
|
||||
ctx->r[RAX].val = ctx->r[RAX].val / v1;
|
||||
rdx = rax % v1;
|
||||
rax = rax / v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
|
@ -10,30 +10,30 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
|
||||
#define IMPL_START_1(name) \
|
||||
void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
|
||||
{ \
|
||||
ulong v1 = (p1->type == A_REG ? ctx->r[p1->val].val : p1->val); \
|
||||
ulong v1 = (p1->type == A_REG ? R(p1->val) : p1->val); \
|
||||
if (p1->mem) v1 = readmem(ctx, v1 + p1->off, p1->mlen);
|
||||
|
||||
#define IMPL_START_2(name) \
|
||||
void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
|
||||
{ \
|
||||
ulong v1 = (p1->type == A_REG ? ctx->r[p1->val].val : p1->val); \
|
||||
ulong v2 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val); \
|
||||
ulong v1 = (p1->type == A_REG ? R(p1->val) : p1->val); \
|
||||
ulong v2 = (p2->type == A_REG ? R(p2->val) : p2->val); \
|
||||
if (p1->mem) v1 = readmem(ctx, v1 + p1->off, p1->mlen); \
|
||||
if (p2->mem) v2 = readmem(ctx, v2 + p2->off, p2->mlen);
|
||||
|
||||
#define IMPL_START_3(name) \
|
||||
void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
|
||||
{ \
|
||||
ulong v2 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val); \
|
||||
ulong v2 = (p2->type == A_REG ? R(p2->val) : p2->val); \
|
||||
if (p2->mem) v2 = readmem(ctx, v2 + p2->off, p2->mlen);
|
||||
|
||||
#define IMPL_OUT \
|
||||
assert(p1->type == A_REG || p1->mem); \
|
||||
if (p1->mem) { \
|
||||
ulong addr = p1->type == A_REG ? ctx->r[p1->val].val : p1->val; \
|
||||
ulong addr = p1->type == A_REG ? R(p1->val) : p1->val; \
|
||||
writemem(ctx, v1, addr + p1->off, p1->mlen); \
|
||||
} \
|
||||
else ctx->r[p1->val].val = v1; \
|
||||
else R(p1->val) = v1; \
|
||||
}
|
||||
|
||||
#define IMPL_END \
|
||||
@ -46,7 +46,7 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
|
||||
#define IMPL_CxxxZ(name) \
|
||||
IMPL_START_0(c##name##z) \
|
||||
{ \
|
||||
if (ctx->r[FLG].val & ZF) { \
|
||||
if (flg & ZF) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
@ -55,7 +55,7 @@ IMPL_END
|
||||
#define IMPL_CxxxNZ(name) \
|
||||
IMPL_START_0(c##name##nz) \
|
||||
{ \
|
||||
if (!(ctx->r[FLG].val & ZF)) { \
|
||||
if (!(flg & ZF)) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
@ -71,16 +71,16 @@ IMPL_END
|
||||
|
||||
#define CHK_SUPERV() \
|
||||
do { \
|
||||
if ((ctx->r[CR0].val & UF) == 1) { \
|
||||
if ((cr0 & UF) == 1) { \
|
||||
_except(ctx, E_SYS, "Supervisor-only INSTR"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHK_STACK(op) \
|
||||
if (ctx->r[RSP].val % 8 > 0 || ctx->r[RBP].val % 8 > 0) { \
|
||||
if (rsp % 8 > 0 || rbp % 8 > 0) { \
|
||||
_except(ctx, E_STK, "Misaligned stack REGS"); \
|
||||
} \
|
||||
if (ctx->r[RBP].val op ctx->r[RSP].val) { \
|
||||
if (rbp op rsp) { \
|
||||
_except(ctx, E_STK, "RSP above RBP"); \
|
||||
}
|
||||
|
||||
@ -90,13 +90,13 @@ IMPL_END
|
||||
//
|
||||
|
||||
#define PUSH(v) \
|
||||
writemem64(ctx, v, ctx->r[RSP].val); \
|
||||
ctx->r[RSP].val -= 8;
|
||||
writemem64(ctx, v, rsp); \
|
||||
rsp -= 8;
|
||||
|
||||
#define POP(v) \
|
||||
ctx->r[RSP].val += 8; \
|
||||
v = readmem64(ctx, ctx->r[RSP].val);
|
||||
rsp += 8; \
|
||||
v = readmem64(ctx, rsp);
|
||||
|
||||
#define JUMP(v) \
|
||||
ctx->r[RIP].val = v + ctx->r[CR1].val
|
||||
rip = v + cr1
|
||||
|
||||
|
@ -19,8 +19,8 @@ IMPL_END;
|
||||
|
||||
IMPL_START_1(loop)
|
||||
{
|
||||
if (ctx->r[RCX].val > 0) {
|
||||
ctx->r[RCX].val--;
|
||||
if (rcx > 0) {
|
||||
rcx--;
|
||||
JUMP(v1);
|
||||
}
|
||||
}
|
||||
@ -28,42 +28,42 @@ IMPL_END;
|
||||
|
||||
IMPL_START_1(cjmpa)
|
||||
{
|
||||
if (!(ctx->r[FLG].val & ZF) && !(ctx->r[FLG].val & CF))
|
||||
if (!(flg & ZF) && !(flg & CF))
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(cjmpae)
|
||||
{
|
||||
if (!(ctx->r[FLG].val & CF))
|
||||
if (!(flg & CF))
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(cjmpb)
|
||||
{
|
||||
if (!(ctx->r[FLG].val & ZF) && ctx->r[FLG].val & CF)
|
||||
if (!(flg & ZF) && flg & CF)
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(cjmpbe)
|
||||
{
|
||||
if (ctx->r[FLG].val & CF)
|
||||
if (flg & CF)
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jcxz)
|
||||
{
|
||||
if (!ctx->r[RCX].val)
|
||||
if (!rcx)
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jcxnz)
|
||||
{
|
||||
if (ctx->r[RCX].val)
|
||||
if (rcx)
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
@ -11,6 +11,20 @@ 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
|
||||
//
|
||||
@ -19,27 +33,77 @@ IMPL_START_2(test)
|
||||
{
|
||||
ulong v = v1 & v2;
|
||||
|
||||
if (v == 0) ctx->r[FLG].val |= ZF;
|
||||
else ctx->r[FLG].val &= ~ZF;
|
||||
CMP(v, 0);
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (v1 == v2) {
|
||||
ctx->r[FLG].val |= ZF;
|
||||
ctx->r[FLG].val &= ~CF;
|
||||
CMP(v1, v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
else if (v1 < v2) {
|
||||
ctx->r[FLG].val &= ~ZF;
|
||||
ctx->r[FLG].val |= CF;
|
||||
IMPL_START_2(cmpb)
|
||||
{
|
||||
v1 &= 0x00000000000000FF;
|
||||
v2 &= 0x00000000000000FF;
|
||||
CMP(v1, v2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
else {
|
||||
ctx->r[FLG].val &= ~ZF;
|
||||
ctx->r[FLG].val &= ~CF;
|
||||
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;
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
IMPL_COND(mov);
|
||||
IMPL_COND(lea);
|
||||
IMPL_COND(xchg);
|
||||
IMPL_COND(cmpxchg);
|
||||
|
||||
//
|
||||
// Movement instructions
|
||||
@ -28,13 +29,27 @@ IMPL_OUT;
|
||||
|
||||
IMPL_START_1(lea)
|
||||
{
|
||||
v1 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val) + p2->off;
|
||||
v1 = (p2->type == A_REG ? R(p2->val) : p2->val) + p2->off;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(gcs)
|
||||
{
|
||||
v1 = ctx->r[CR1].val;
|
||||
v1 = cr1;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(cmpxchg)
|
||||
{
|
||||
if (rax == v1) {
|
||||
flg |= ZF;
|
||||
v1 = v2;
|
||||
}
|
||||
|
||||
else {
|
||||
flg &= ~ZF;
|
||||
rax = v1;
|
||||
}
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
|
@ -31,7 +31,7 @@ IMPL_OUT;
|
||||
IMPL_START_1(call)
|
||||
{
|
||||
CHK_STACK(<);
|
||||
PUSH(ctx->r[RIP].val);
|
||||
PUSH(rip);
|
||||
JUMP(v1);
|
||||
}
|
||||
IMPL_END;
|
||||
@ -39,7 +39,7 @@ IMPL_END;
|
||||
IMPL_START_0(ret)
|
||||
{
|
||||
CHK_STACK(<=);
|
||||
POP(ctx->r[RIP].val);
|
||||
POP(rip);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
@ -48,8 +48,8 @@ IMPL_START_0(enter)
|
||||
// We don't CHK_STACK(<) here because ENTER
|
||||
// (should) always be preceded by a CALL,
|
||||
// which already checks the stack
|
||||
PUSH(ctx->r[RBP].val);
|
||||
ctx->r[RBP].val = ctx->r[RSP].val;
|
||||
PUSH(rbp);
|
||||
rbp = rsp;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
@ -57,16 +57,14 @@ IMPL_START_0(leave)
|
||||
{
|
||||
// Do NOT check stack here
|
||||
// (it would always fail)
|
||||
POP(ctx->r[RBP].val);
|
||||
POP(rbp);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(pushf)
|
||||
{
|
||||
CHK_STACK(<);
|
||||
|
||||
writemem64(ctx, ctx->r[FLG].val, ctx->r[RSP].val);
|
||||
ctx->r[RSP].val -= 8;
|
||||
PUSH(flg);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
@ -77,8 +75,7 @@ IMPL_START_0(popf)
|
||||
// XXX
|
||||
CHK_SUPERV();
|
||||
|
||||
ctx->r[RSP].val += 8;
|
||||
ctx->r[FLG].val = readmem64(ctx, ctx->r[RSP].val);
|
||||
POP(flg);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
|
@ -11,19 +11,20 @@
|
||||
IMPL_START_0(cli)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
ctx->r[FLG].val &= ~IF;
|
||||
flg &= ~IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(sti)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
ctx->r[FLG].val |= IF;
|
||||
flg |= IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(stop)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
_except(ctx, E_SHT, "STOP INSTR");
|
||||
}
|
||||
IMPL_END;
|
||||
|
14
pc/main.c
14
pc/main.c
@ -9,19 +9,19 @@ static ushort *fwprog;
|
||||
|
||||
ushort bget(ctx_t *ctx)
|
||||
{
|
||||
if (ctx->r[RIP].val % 2) {
|
||||
if (rip % 2) {
|
||||
_except(ctx, E_ALI, "Misaligned RIP register: 0x%016lX",
|
||||
ctx->r[RIP].val);
|
||||
rip);
|
||||
}
|
||||
|
||||
if (addr2real(ctx->r[RIP].val) >= ctx->mz) {
|
||||
if (addr2real(rip) >= ctx->mz) {
|
||||
_except(ctx, E_ACC, "Executing out of memory: 0x%016lX",
|
||||
ctx->r[RIP].val);
|
||||
rip);
|
||||
}
|
||||
|
||||
ushort c = ctx->mp[addr2real(ctx->r[RIP].val)];
|
||||
ushort c = ctx->mp[addr2real(rip)];
|
||||
|
||||
ctx->r[RIP].val += 2;
|
||||
rip += 2;
|
||||
|
||||
return c;
|
||||
}
|
||||
@ -36,7 +36,7 @@ ushort dget(ctx_t *ctx)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ctx->r[RIP].val += 2;
|
||||
rip += 2;
|
||||
return fwprog[i++];
|
||||
}
|
||||
|
||||
|
3
pc/mem.c
3
pc/mem.c
@ -16,7 +16,6 @@ ulong readmem(ctx_t *ctx, ulong addr, uint len)
|
||||
|
||||
void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
||||
{
|
||||
addr += ctx->r[CR2].val;
|
||||
switch (len) {
|
||||
case 1: writemem8(ctx, val, addr); break;
|
||||
case 2: writemem16(ctx, val, addr); break;
|
||||
@ -40,7 +39,7 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
||||
}
|
||||
|
||||
#define GETREAL() \
|
||||
addr += ctx->r[CR2].val; \
|
||||
addr += cr2; \
|
||||
ulong real = addr2real(addr)
|
||||
|
||||
ulong readmem8(ctx_t *ctx, ulong addr)
|
||||
|
@ -89,9 +89,6 @@ void dumpregs(ctx_t *ctx)
|
||||
(strlen(r->name) == 2 ? "=" : ""), r->val);
|
||||
}
|
||||
log("\nrip=0x%-16lX rbp=0x%-16lX rsp=0x%-16lX flg=0x%-16lX\n",
|
||||
ctx->r[RIP].val,
|
||||
ctx->r[RBP].val,
|
||||
ctx->r[RSP].val,
|
||||
ctx->r[FLG].val);
|
||||
rip, rbp, rsp, flg);
|
||||
}
|
||||
|
||||
|
74
pc/regs.h
74
pc/regs.h
@ -5,56 +5,40 @@ enum
|
||||
{
|
||||
INV,
|
||||
|
||||
RIP,
|
||||
FLG,
|
||||
RIP, FLG, RBP, RSP,
|
||||
#define rip R(RIP)
|
||||
#define flg R(FLG)
|
||||
#define rbp R(RBP)
|
||||
#define rsp R(RSP)
|
||||
|
||||
RBP,
|
||||
RSP,
|
||||
RAX, RBX, RCX, RDX,
|
||||
RSX, RBI, RDI, RSI,
|
||||
#define rax R(RAX)
|
||||
#define rbx R(RBX)
|
||||
#define rcx R(RCX)
|
||||
#define rdx R(RDX)
|
||||
#define rsx R(RSX)
|
||||
#define rbi R(RBI)
|
||||
#define rdi R(RDI)
|
||||
#define rsi R(RSI)
|
||||
|
||||
RAX,
|
||||
RBX,
|
||||
RCX,
|
||||
RDX,
|
||||
RSX,
|
||||
RBI,
|
||||
RDI,
|
||||
RSI,
|
||||
NX0, NX1, NX2, NX3,
|
||||
NX4, NX5, NX6, NX7,
|
||||
|
||||
NX0,
|
||||
NX1,
|
||||
NX2,
|
||||
NX3,
|
||||
NX4,
|
||||
NX5,
|
||||
NX6,
|
||||
NX7,
|
||||
AX0, AX1, AX2, AX3,
|
||||
AX4, AX5, AX6, AX7,
|
||||
|
||||
AX0,
|
||||
AX1,
|
||||
AX2,
|
||||
AX3,
|
||||
AX4,
|
||||
AX5,
|
||||
AX6,
|
||||
AX7,
|
||||
CR0, CR1, CR2, CR3,
|
||||
CR4, CR5, CR6, CR7,
|
||||
#define cr0 R(CR0)
|
||||
#define cr1 R(CR1)
|
||||
#define cr2 R(CR2)
|
||||
#define cr3 R(CR3)
|
||||
|
||||
CR0,
|
||||
CR1,
|
||||
CR2,
|
||||
CR3,
|
||||
CR4,
|
||||
CR5,
|
||||
CR6,
|
||||
CR7,
|
||||
|
||||
SA0,
|
||||
SA1,
|
||||
SA2,
|
||||
SA3,
|
||||
SA4,
|
||||
SA5,
|
||||
SA6,
|
||||
SA7,
|
||||
SA0, SA1,
|
||||
SA2, SA3,
|
||||
SA4, SA5,
|
||||
SA6, SA7,
|
||||
|
||||
NREGS
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user