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-07-01 21:46:36 +02:00
parent b4f36ab137
commit 6f59eebedb
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
18 changed files with 284 additions and 145 deletions

View File

@ -308,14 +308,12 @@ def parse_preproc(line):
sys.exit(1) sys.exit(1)
written = b_data.write(ord(c).to_bytes(1, byteorder='little', signed=False)) written = b_data.write(ord(c).to_bytes(1, byteorder='little', signed=False))
assert(written == 1)
real_len += 1 real_len += 1
pdata += 1 pdata += 1
# align # align
for i in range(8 - len(s) % 8): for i in range(8 - len(s) % 8):
written = b_data.write(int(0).to_bytes(1, byteorder='little', signed=False)) written = b_data.write(int(0).to_bytes(1, byteorder='little', signed=False))
assert(written == 1)
pdata += 1 pdata += 1
pdefs[label + "_len"] = str(real_len) pdefs[label + "_len"] = str(real_len)
@ -364,7 +362,7 @@ def get_cond_mask(cond, line):
leave() leave()
sys.exit(1) sys.exit(1)
return (mask | pconds[cond]) << 10 return (mask | pconds[cond])
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@ -419,9 +417,11 @@ def parse_instr(line):
size = 4 size = 4
# Word 2 (rep|cond|ft1|ft2) # Word 2 (rep|ft3|ft2|ft1)
w2 = 0 w2 = 0
cond = None
if len(instr) > 2 and '.' in instr: if len(instr) > 2 and '.' in instr:
instr, suf = instr.split('.', 1) instr, suf = instr.split('.', 1)
@ -440,20 +440,26 @@ def parse_instr(line):
w2 |= 0x8000 # REP w2 |= 0x8000 # REP
if len(suf) > 0: if len(suf) > 0:
w2 |= get_cond_mask(suf, line) instrs.write("%%cond ")
cond = "%%imm16 {}".format(get_cond_mask(suf, line))
instr_name = instr instr_name = instr
instr_args = '' instr_args = ''
if params == None or len(params) == 0: if params == None or len(params) == 0:
instrs.write("{} ".format(instr_name)) instrs.write("{} ".format(instr_name))
if cond != None:
size += 2
instrs.write("{} ".format(cond))
instrs.write("%%imm16 {}".format(w2)) instrs.write("%%imm16 {}".format(w2))
return size return size
tok = params.split(',') tok = params.split(',')
# FT1 and FT2 # FTn
fts = '' fts = ''
# #
@ -680,29 +686,43 @@ def parse_instr(line):
fellthrough = False fellthrough = False
# #
# Compute FT1 and FT2 # Compute FTn
# #
if ' ' in fts: l = len(fts.split())
assert(len(fts.split()) == 2)
if l == 3:
ft1, ft2, ft3 = fts.split()
w2 |= get_fts_mask(ft3, line) << 10
w2 |= get_fts_mask(ft2, line) << 5
w2 |= get_fts_mask(ft1, line)
elif l == 2:
ft1, ft2 = fts.split() ft1, ft2 = fts.split()
w2 |= get_fts_mask(ft1, line) << 5 w2 |= get_fts_mask(ft2, line) << 5
w2 |= get_fts_mask(ft2, line) w2 |= get_fts_mask(ft1, line)
else: else:
assert(len(fts) > 0) assert(l == 1)
w2 |= get_fts_mask(fts, line) << 5 w2 |= get_fts_mask(fts, line)
if cond == None:
instrs.write("{} %%imm16 {}{}".format(instr_name, w2, instr_args)) instrs.write("{} %%imm16 {}{}".format(instr_name, w2, instr_args))
else:
size += 2
instrs.write("{} {} %%imm16 {}{}".format(instr_name, cond, w2, instr_args))
return size return size
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
special_syms = { special_syms = {
"%%cond",
"%%imm16", "%%imm16",
"%%imm32", "%%imm32",
"%%imm64", "%%imm64",
"%%signed" "%%signed",
} }
def gentext(): def gentext():
@ -712,6 +732,8 @@ def gentext():
instrs.seek(0) instrs.seek(0)
cond_mask = 0
for _, line in enumerate(instrs): for _, line in enumerate(instrs):
tok = line.strip().split() tok = line.strip().split()
@ -742,7 +764,8 @@ def gentext():
continue continue
if word in pinstrs: if word in pinstrs:
idx = pinstrs.index(word) idx = pinstrs.index(word) | cond_mask
cond_mask = 0
b_text.write(idx.to_bytes(2, byteorder='little', signed=False)) b_text.write(idx.to_bytes(2, byteorder='little', signed=False))
continue continue
@ -763,13 +786,13 @@ def gentext():
lastimm = 4 lastimm = 4
elif word == "%%imm64": elif word == "%%imm64":
lastimm = 8 lastimm = 8
elif word == "%%cond":
cond_mask = (1 << 13)
elif word == "%%signed": elif word == "%%signed":
lastimm = 2 lastimm = 2
isSigned = True isSigned = True
else: else:
isSigned = False isSigned = False
continue continue
if is_number(word): if is_number(word):

6
ka/ABI
View File

@ -46,7 +46,7 @@ Between the 'enter' and the 'leave', the stack looks like this:
| . | rsp+8 | | . | rsp+8 |
| . | rsp+0 / | . | rsp+0 /
|---------------| |---------------|
. (undefined) . . (red zone) .
. . . .
. . . .
@ -131,9 +131,7 @@ The following registers can only be used by the supervisor:
- Debugging registers for the supervisor: - Debugging registers for the supervisor:
dr0-dr7 dr0-dr7
The following registers cannot be referenced by machine code at all; they must The following registers cannot be referenced by machine code at all:
be manipulated through specific instructions, and manipulating their values
allow for controlling the machine in various ways:
px0-px1, fc0-fc2, cr0-cr7 px0-px1, fc0-fc2, cr0-cr7
#------------------------------------------------------------------------------# #------------------------------------------------------------------------------#

View File

@ -42,8 +42,8 @@ CMD.builtins.dir:
j.b .print_file_name j.b .print_file_name
; calculate where to put extension ; calculate where to put extension
lea r11, b[r10 - 1] ksub r11, r10, .buf
sub r11, .buf dec r11
.ext_pad: .ext_pad:
; print at least 11 non-space characters before extension ; print at least 11 non-space characters before extension

View File

@ -27,19 +27,3 @@ cmc
clc clc
stc stc
#
# Load FLG register (LODF)
#
# $1 = FLG
#
lodf rm
#
# Store FLG register - lower byte only (STOFB)
#
# FLG[7:0] = $1[7:0]
#
# Note: FLG's lower byte contains CF, OF, ZF, SF, PF and DF
#
stofb rm

View File

@ -13,4 +13,5 @@ include "FLAGS"
include "INOUT" include "INOUT"
include "DEBUG" include "DEBUG"
include "STRING" include "STRING"
include "KINSTRS"

View File

@ -6,7 +6,7 @@
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# #
# Absolute jump (JMP) instruction # Jump (JMP) instruction
# #
# RIP = $1 # RIP = $1
# #
@ -14,7 +14,7 @@ j ri
jmp ri jmp ri
# #
# RCX-dependent absolute jump (LOOP) instruction # RCX-dependent jump (LOOP) instruction
# #
# IF (RCX > 0) THEN # IF (RCX > 0) THEN
# RCX = RCX - 1 # RCX = RCX - 1

34
vm/in/KINSTRS Normal file
View File

@ -0,0 +1,34 @@
# 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 #
#---------------------------------------------------------------------------#
#
# 2-sources logical & arithmetical operations
#
# Preserves CF and OF
# Sets ZF and SF according to the result
#
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
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

@ -17,10 +17,11 @@ def getflag(s):
return "__FLAG_ERROR__" return "__FLAG_ERROR__"
def doprnt(fp, i, p1, p2): def doprnt(fp, i, p1, p2, p3):
for c1 in p1: for c1 in p1:
for c2 in p2: for c2 in p2:
fp.write("{} {} {}".format(i, c1, c2).strip()) for c3 in p3:
fp.write("{} {} {} {}".format(i, c1, c2, c3).strip())
fp.write('\n') fp.write('\n')
def parse_1(fi, fp): def parse_1(fi, fp):
@ -40,28 +41,34 @@ def parse_1(fi, fp):
parse_1(fi2, fp) parse_1(fi2, fp)
continue continue
tok = line.split(' ') tok = line.split()
if len(tok) == 0: if len(tok) == 0:
continue continue
i = tok[0].strip() i = tok[0]
if len(tok) == 1: if len(tok) == 1:
doprnt(fp, i, ' ', ' ') doprnt(fp, i, ' ', ' ', ' ')
continue continue
if len(tok) == 2: if len(tok) == 2:
p = tok[1].strip() p = tok[1]
doprnt(fp, i, p, ' ') doprnt(fp, i, p, ' ', ' ')
continue continue
assert(len(tok) == 3) if len(tok) == 3:
p1 = tok[1]
p2 = tok[2]
doprnt(fp, i, p1, p2, ' ')
continue
p1 = tok[1].strip() assert(len(tok) == 4)
p2 = tok[2].strip() p1 = tok[1]
p2 = tok[2]
p3 = tok[3]
doprnt(fp, i, p1, p2) doprnt(fp, i, p1, p2, p3)
fi.close() fi.close()
@ -84,30 +91,40 @@ def parse_2(fp):
name = tok[0] name = tok[0]
p1 = "NOPRM" p1 = "NOPRM"
p2 = "NOPRM" p2 = "NOPRM"
p3 = "NOPRM"
elif len(tok) == 2: elif len(tok) == 2:
name = "{}_{}".format(tok[0], tok[1].strip()) name = "{}_{}".format(tok[0], tok[1])
p1 = getflag(tok[1]) p1 = getflag(tok[1])
p2 = "NOPRM" p2 = "NOPRM"
p3 = "NOPRM"
elif len(tok) == 3: elif len(tok) == 3:
name = "{}_{}_{}".format(tok[0], tok[1], tok[2].strip()) name = "{}_{}_{}".format(tok[0], tok[1], tok[2])
p1 = getflag(tok[1]) p1 = getflag(tok[1])
p2 = getflag(tok[2]) p2 = getflag(tok[2])
p3 = "NOPRM"
elif len(tok) == 4:
name = "{}_{}_{}_{}".format(tok[0], tok[1], tok[2], tok[3])
p1 = getflag(tok[1])
p2 = getflag(tok[2])
p3 = getflag(tok[3])
else: else:
name = "__TOK_ERROR__" name = "__TOK_ERROR__"
p1 = "__TOK_ERROR__" p1 = "__TOK_ERROR__"
p2 = "__TOK_ERROR__" p2 = "__TOK_ERROR__"
p3 = "__TOK_ERROR__"
ls.write("{}{}\n".format(deprecated, name)) ls.write("{}{}\n".format(deprecated, name))
hd.write("#ifdef _NEED_ARCH_I\n") hd.write("#ifdef _NEED_ARCH_I\n")
hd.write('{{ "{}{}", "{}{}", {}, {}, i_{} }},\n'\ hd.write('{{ "{}{}", "{}{}", {}, {}, {}, i_{} }},\n'\
.format(deprecated, tok[0], deprecated, name, p1, p2, tok[0])) .format(deprecated, tok[0], deprecated, name, p1, p2, p3, tok[0]))
hd.write("#else\n") hd.write("#else\n")
hd.write("#define I_{} {}\n".format(name.upper(), count)) hd.write("#define I_{} {}\n".format(name.upper(), count))
hd.write("extern bool i_{}(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);\n" hd.write("extern bool i_{}(ctx_t *, acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n"
.format(tok[0])) .format(tok[0]))
hd.write("#endif\n\n") hd.write("#endif\n\n")

View File

@ -55,17 +55,3 @@ IMPL_END;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_1(lodf)
{
v1 = flg;
}
IMPL_OUT;
IMPL_START_1(stofb)
{
flg = (flg & ~0xFF) | (v1 & 0xFF);
}
IMPL_END;
//----------------------------------------------------------------------------//

View File

@ -31,20 +31,31 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#define IMPL_START_0(name) \ #define IMPL_START_0(name) \
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
ulong *r1, ulong *r2, ulong *r3) \
{ {
#define IMPL_START_1(name) \ #define IMPL_START_1(name) \
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
ulong *r1, ulong *r2, ulong *r3) \
{ \ { \
DECV(v1, p1); DECV(v1, p1);
#define IMPL_START_2(name) \ #define IMPL_START_2(name) \
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
ulong *r1, ulong *r2, ulong *r3) \
{ \ { \
DECV(v1, p1); \ DECV(v1, p1); \
DECV(v2, p2); 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) \
{ \
DECV(v1, p1); \
DECV(v2, p2); \
DECV(v3, p3);
#define IMPL_OUT_ZSF \ #define IMPL_OUT_ZSF \
SET_ZSF(v1); \ SET_ZSF(v1); \
IMPL_OUT IMPL_OUT
@ -60,6 +71,13 @@ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \
return 2; \ return 2; \
} }
#define IMPL_OUT_3 \
*r1 = v1; \
*r2 = v2; \
*r3 = v3; \
return 3; \
}
#define IMPL_END \ #define IMPL_END \
return 0; \ return 0; \
} }

40
vm/in/kinstrs.c Normal file
View File

@ -0,0 +1,40 @@
// 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 K_IMPL_ALU(name, expr) \
IMPL_START_3(k##name) \
{ \
v1 = expr; \
} \
IMPL_OUT_ZSF
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);
//----------------------------------------------------------------------------//

View File

@ -5,14 +5,15 @@ Instruction encoding:
15 0 15 0 15 0 15 0
xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
││└───────────┘ │└───┘└───┘└───┘ ││└───────────┘ │└───┘└───┘└───┘
││ INSTR. │ CND FT1 FT2 │││ INSTR. │ FT3 FT2 FT1
││ ││
LM R LMC R
M No more words M No more words
L LOCK prefix C COND suffix
R REP prefix L LOCK suffix
R REP suffix
FT1 First operand format FT1 First operand format
FT2 Second operand format FT2 Second operand format

View File

@ -7,7 +7,7 @@
// Read the "DECD" file before reading this code // Read the "DECD" file before reading this code
// //
static void check_param_type(ctx_t *ctx, instr_t *in, uint prm, uchar fmt) static void check_param_type(ctx_t *ctx, instr_t *in, uint prm, uchar fmt, int which)
{ {
bool ok; bool ok;
@ -22,8 +22,8 @@ static void check_param_type(ctx_t *ctx, instr_t *in, uint prm, uchar fmt)
if (!ok) if (!ok)
_except(ctx, E_ILL, _except(ctx, E_ILL,
"FT1 or FT2 not matching %s's expected parameter types: " "FT%d not matching %s's expected parameter types: "
"fmt=0x%x prm=0x%x", in->full, fmt, prm); "fmt=0x%x prm=0x%x", which, in->full, fmt, prm);
} }
// //
@ -146,27 +146,21 @@ void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
void decode(ctx_t *ctx) void decode(ctx_t *ctx)
{ {
char *illmsg;
instr_t *in; instr_t *in;
acc_t p1 = { 0 }; acc_t p1 = { 0 };
acc_t p2 = { 0 }; acc_t p2 = { 0 };
acc_t p3 = { 0 };
bool rep = 0; bool rep = 0;
uint cond = 0; uint cond = 0;
bool lock, nomore; bool lock, nomore;
ushort w1, w2; ushort w1, w2;
uchar f1 = 0, f2 = 0; uchar f1 = 0, f2 = 0, f3 = 0;
rpc = rip; rpc = rip;
/*
sym_t *sym = find_sym_by_addr(pc);
if (sym)
trace("0x%lX: %s:\n", pc, sym->name);
*/
// //
// Process the first word of the instruction // Process the first word of the instruction
// //
@ -174,10 +168,15 @@ void decode(ctx_t *ctx)
// Extract first word flags // Extract first word flags
lock = !!(w1 & PREF_LOCK); lock = !!(w1 & SUFF_LOCK);
nomore = !!(w1 & PREF_NOMORE); nomore = !!(w1 & SUFF_NOMORE);
w1 &= ~(PREF_LOCK|PREF_NOMORE); if (w1 & SUFF_COND)
{
cond = ctx->get(ctx);
}
w1 &= ~(SUFF_LOCK|SUFF_NOMORE|SUFF_COND);
// Find instruction // Find instruction
@ -197,12 +196,12 @@ void decode(ctx_t *ctx)
w2 = ctx->get(ctx); w2 = ctx->get(ctx);
// REP and COND // REP and COND
rep = !!(w2 & PREF_REP); rep = !!(w2 & SUFF_REP);
cond = (w2 & BITS_COND) >> COND_SHIFT;
// F1 and F2 // Fn
f1 = (w2 >> F1_SHIFT) & Fx_MASK; f3 = (w2 >> F3_SHIFT) & Fx_MASK;
f2 = w2 & Fx_MASK; f2 = (w2 >> F2_SHIFT) & Fx_MASK;
f1 = w2 & Fx_MASK;
} }
// //
@ -211,17 +210,18 @@ void decode(ctx_t *ctx)
if (in->prm1 == NOPRM) if (in->prm1 == NOPRM)
{ {
if (f1 || f2) if (f1 || f2 || f3)
{ {
illmsg = "FT1 and/or FT2 filled for 0-param INSTR"; _except(ctx, E_ILL,
goto ill; "FTn (%u,%u,%u) filled for 0-param INSTR '%s'",
f1, f2, f3, in->full);
} }
exec_instr(ctx, in, NULL, NULL, lock, rep, cond); exec_instr(ctx, in, NULL, NULL, NULL, lock, rep, cond);
return; return;
} }
check_param_type(ctx, in, in->prm1, f1); check_param_type(ctx, in, in->prm1, f1, 1);
extract_param(ctx, &p1, f1); extract_param(ctx, &p1, f1);
// //
@ -230,23 +230,40 @@ void decode(ctx_t *ctx)
if (in->prm2 == NOPRM) if (in->prm2 == NOPRM)
{ {
if (f2) if (f2 || f3)
{ {
illmsg = "FT2 filled for 1-param INSTR"; _except(ctx, E_ILL,
goto ill; "FT3/FT2 (%u,%u,%u) filled for 1-param INSTR '%s'",
f1, f2, f3, in->full);
} }
exec_instr(ctx, in, &p1, NULL, lock, rep, cond); exec_instr(ctx, in, &p1, NULL, NULL, lock, rep, cond);
return; return;
} }
check_param_type(ctx, in, in->prm2, f2); check_param_type(ctx, in, in->prm2, f2, 2);
extract_param(ctx, &p2, f2); extract_param(ctx, &p2, f2);
exec_instr(ctx, in, &p1, &p2, lock, rep, cond); //
return; // Deal with operand 3
//
ill: if (in->prm3 == NOPRM)
_except(ctx, E_ILL, illmsg); {
if (f3)
{
_except(ctx, E_ILL,
"FT3 (%u,%u,%u) filled for 2-param INSTR '%s'",
f1, f2, f3, in->full);
}
exec_instr(ctx, in, &p1, &p2, NULL, lock, rep, cond);
return;
}
check_param_type(ctx, in, in->prm3, f3, 3);
extract_param(ctx, &p3, f3);
exec_instr(ctx, in, &p1, &p2, &p3, lock, rep, cond);
} }

View File

@ -13,18 +13,14 @@ enum
enum enum
{ {
PREF_LOCK = (1 << 15), SUFF_LOCK = (1 << 15),
PREF_NOMORE = (1 << 14), SUFF_NOMORE = (1 << 14),
SUFF_COND = (1 << 13),
PREF_REP = (1 << 15), SUFF_REP = (1 << 15),
BITS_COND = (1 << 14) | (1 << 13) | (1 << 12)
| (1 << 11) | (1 << 10),
COND_SHIFT = 10,
Fx_MASK = 0x1F, Fx_MASK = 0x1F,
F1_SHIFT = 5, F3_SHIFT = 10,
F2_SHIFT = 5,
}; };
enum enum
@ -79,14 +75,17 @@ struct instr_t
uint prm1; uint prm1;
uint prm2; uint prm2;
uint prm3;
bool (*func)(ctx_t *, acc_t *, acc_t *, ulong *, ulong *); bool (*func)(ctx_t *, acc_t *, acc_t *, acc_t *,
ulong *, ulong *, ulong *);
}; };
void exec_instr(ctx_t *ctx, void exec_instr(ctx_t *ctx,
instr_t *in, instr_t *in,
acc_t *p1, acc_t *p1,
acc_t *p2, acc_t *p2,
acc_t *p3,
bool lock, bool lock,
bool rep, bool rep,
uint cond); uint cond);
@ -99,6 +98,7 @@ void dump_instr(ctx_t *ctx,
instr_t *in, instr_t *in,
acc_t *p1, acc_t *p1,
acc_t *p2, acc_t *p2,
acc_t *p3,
bool lock, bool lock,
bool rep, bool rep,
uint cond); uint cond);

View File

@ -23,6 +23,7 @@ void dump_instr(ctx_t *ctx,
instr_t *in, instr_t *in,
acc_t *p1, acc_t *p1,
acc_t *p2, acc_t *p2,
acc_t *p3,
bool lock, bool lock,
bool rep, bool rep,
uint cond) uint cond)
@ -62,12 +63,16 @@ void dump_instr(ctx_t *ctx,
trace("\t"); trace("\t");
if (p1) if (p1)
{
dump_acc(ctx, p1); dump_acc(ctx, p1);
if (p2) { if (p2) {
trace(", "); trace(", ");
dump_acc(ctx, p2); dump_acc(ctx, p2);
} }
if (p3) {
trace(", ");
dump_acc(ctx, p3);
} }
trace("\n"); trace("\n");

View File

@ -48,12 +48,13 @@ void exec_instr(ctx_t *ctx,
instr_t *in, instr_t *in,
acc_t *p1, acc_t *p1,
acc_t *p2, acc_t *p2,
acc_t *p3,
bool lock, bool lock,
bool rep, bool rep,
uint cond) uint cond)
{ {
bool out; bool out;
ulong r1 = 0, r2 = 0; ulong r1 = 0, r2 = 0, r3 = 0;
// Global instruction counter // Global instruction counter
ctx->ninstrs++; ctx->ninstrs++;
@ -75,14 +76,13 @@ void exec_instr(ctx_t *ctx,
return; return;
} }
#ifndef NDEBUG #ifndef NDEBUG
dump_instr(ctx, in, p1, p2, lock, rep, cond); dump_instr(ctx, in, p1, p2, p3, lock, rep, cond);
#endif #endif
do_rep: do_rep:
out = in->func(ctx, p1, p2, &r1, &r2); out = in->func(ctx, p1, p2, p3, &r1, &r2, &r3);
if (out) if (out)
{ {
@ -99,7 +99,7 @@ do_rep:
} }
} }
if (out == 2) if (out >= 2)
{ {
if (p2->type == A_REG) if (p2->type == A_REG)
R(p2->reg) = r2; R(p2->reg) = r2;
@ -114,6 +114,21 @@ do_rep:
} }
} }
if (out >= 3)
{
if (p3->type == A_REG)
R(p3->reg) = r3;
else if (p3->type == A_IMM64)
_except(ctx, E_ACC, "Trying to output to an IMM64");
else
{
assert(ACC_IS_MEM(p3));
writemem(ctx, r3, p3->addr, p3->mlen);
}
}
if (rep) if (rep)
{ {
// RCX remains untouched when condition fails // RCX remains untouched when condition fails
@ -130,7 +145,7 @@ do_rep:
#ifndef NDEBUG #ifndef NDEBUG
// Show that we're REP'ing // Show that we're REP'ing
dump_instr(ctx, in, p1, p2, lock, rep, cond); dump_instr(ctx, in, p1, p2, p3, lock, rep, cond);
#endif #endif
goto do_rep; goto do_rep;

View File

@ -6,11 +6,11 @@
reg_t arch_r[] = reg_t arch_r[] =
{ {
{ "inv", RES }, { "inv", RES },
{ "flg", RES }, { "flg", GPR },
{ "rip", GPR }, { "rip", GPR },
{ "rpc", GPR }, { "rpc", GPR },
{ "px0", CTL }, { "px0", RES },
{ "px1", CTL }, { "px1", RES },
{ "fc1", RES }, { "fc1", RES },
{ "fc2", RES }, { "fc2", RES },
{ "sa0", SYS }, { "sa0", SYS },

View File

@ -37,8 +37,6 @@ struct reg_t
ulong flags; ulong flags;
}; };
#define rx0 ctx->ninstrs
enum enum
{ {
INV, FLG, RIP, RPC, PX0, PX1, FC1, FC2, INV, FLG, RIP, RPC, PX0, PX1, FC1, FC2,
@ -64,6 +62,8 @@ enum
NREGS NREGS
}; };
#define rx0 ctx->ninstrs
#define inv R(INV) #define inv R(INV)
#define rip R(RIP) #define rip R(RIP)
#define rpc R(RPC) #define rpc R(RPC)