1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
kvisc/.sum
2019-06-15 13:42:30 +02:00

5210 lines
105 KiB
Plaintext

// 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 <pc/dev.h>
long cpudev_testfn(ctx_t *ctx, dev_t *dev)
{
assert(dev == &cpudev);
rax = 4;
rdx = 3;
return 0;
}
long cpudev_poweron(ctx_t *ctx, dev_t *dev)
{
assert(dev == &cpudev);
dev->fslots[0] = cpudev_testfn;
dev->state = DEVGOOD;
return 0;
}
dev_t cpudev =
{
.type = "cpu",
.name = "K-CPU",
.modl = "Prisma 1",
.vend = "The OS/K Team",
.major = KARCH_MAJOR,
.minor = KARCH_MINOR,
.revis = KARCH_REVIS,
.fpwon = cpudev_poweron,
};
// 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 <pc/dev.h>
long memdev_getmemoff(ctx_t *ctx, dev_t *dev)
{
rax = MEMOFF;
return 0;
}
long memdev_getmemsize(ctx_t *ctx, dev_t *dev)
{
rax = ctx->mz;
return 0;
}
long memdev_poweron(ctx_t *ctx, dev_t *dev)
{
dev->fslots[0] = memdev_getmemoff;
dev->fslots[1] = memdev_getmemsize;
dev->state = DEVGOOD;
return 0;
}
dev_t memdev =
{
.type = "ram",
.name = "K-RAM",
.modl = "",
.vend = "The OS/K Team",
.major = KARCH_MAJOR,
.minor = KARCH_MINOR,
.revis = KARCH_REVIS,
.fpwon = memdev_poweron,
};
// 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 <pc/dev.h>
#include <termio.h>
void _except(ctx_t *ctx, int code, char *fmt, ...)
{
va_list ap;
//
// Restore stdin echoing
//
struct termios t;
tcgetattr(0, &t);
t.c_lflag |= ECHO;
tcsetattr(0, TCSANOW, &t);
log("\nException %d - ", code);
va_start(ap, fmt);
vlog(fmt, ap);
va_end(ap);
log("\n");
dumpregs(ctx);
log("\n");
if (ctx->mp)
free(ctx->mp);
//
// Shut down devices
//
if (devfiniall(ctx) < 0)
{
log("Couldn't deinitialize devices\n");
exit(-100 - code);
}
exit(code);
}
// 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 <pc/arch.h>
//----------------------------------------------------------------------------//
#define CHK_ALIGN(type) \
if (addr % alignof(type) > 0) { \
_except(ctx, E_ALI, \
"Non-aligned memory access: 0x%012lX (0x%012lX) by %lu", \
addr, real, alignof(type)); \
}
//----------------------------------------------------------------------------//
static ulong readmem8(ctx_t *ctx, ulong real, ulong addr)
{
if (addr % 2 == 0) return (ulong)ctx->mp[real] & 0xFF;
else return ((ulong)ctx->mp[real] & 0xFF00) >> 8;
}
static ulong readmem16(ctx_t *ctx, ulong real, ulong addr)
{
CHK_ALIGN(ushort);
return (ulong)ctx->mp[real];
}
static ulong readmem32(ctx_t *ctx, ulong real, ulong addr)
{
CHK_ALIGN(uint);
ulong val = ctx->mp[real++];
val = val | ((ulong)ctx->mp[real] << 16);
return val;
}
static ulong readmem64(ctx_t *ctx, ulong real, ulong addr)
{
CHK_ALIGN(ulong);
ulong val = (ulong)ctx->mp[real++];
val = val | ((ulong)ctx->mp[real++] << 16);
val = val | ((ulong)ctx->mp[real++] << 32);
val = val | ((ulong)ctx->mp[real] << 48);
return val;
}
//----------------------------------------------------------------------------//
static void writemem8(ctx_t *ctx, ulong val, ulong real, ulong addr)
{
ushort v = ctx->mp[real];
if (!(addr % 2)) {
ctx->mp[real] = (v & 0xFF00) | (val & 0xFF);
}
else {
ctx->mp[real] = (v & 0xFF) | (((val & 0xFF) << 8));
}
}
static void writemem16(ctx_t *ctx, ulong val, ulong real, ulong addr)
{
CHK_ALIGN(ushort);
ctx->mp[real] = val & 0xFFFF;
}
static void writemem32(ctx_t *ctx, ulong val, ulong real, ulong addr)
{
CHK_ALIGN(uint);
ctx->mp[real++] = val & 0xFFFF;
ctx->mp[real] = (val >> 16) & 0xFFFF;
}
static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
{
CHK_ALIGN(ulong);
ctx->mp[real++] = val;
ctx->mp[real++] = (val >> 16) & 0xFFFF;
ctx->mp[real++] = (val >> 32) & 0xFFFF;
ctx->mp[real] = (val >> 48) & 0xFFFF;
}
//----------------------------------------------------------------------------//
#define CHK_RANGE() \
if (addr < MEMOFF || real >= MEMSIZE) { \
_except(ctx, E_ACC, \
"Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \
}
#define GETREAL() \
addr += cr2; \
ulong real = addr2real(addr)
#define SIGN_EXTEND(val, mask) \
(val & ((mask + 1) >> 1) \
? (val | ~mask) \
: val)
//----------------------------------------------------------------------------//
ulong readmem(ctx_t *ctx, ulong addr, uint len)
{
GETREAL();
CHK_RANGE();
ulong val;
switch (len) {
case 1:
val = readmem8(ctx, real, addr);
val = SIGN_EXTEND(val, 0xFF);
break;
case 2:
val = readmem16(ctx, real, addr);
val = SIGN_EXTEND(val, 0xFFFF);
break;
case 4:
val = readmem32(ctx, real, addr);
val = SIGN_EXTEND(val, 0xFFFFFFFFUL);
break;
case 8:
return readmem64(ctx, real, addr);
default: log("readmem() bad length %d!\n", len); abort();
}
return val;
}
void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
{
GETREAL();
CHK_RANGE();
switch (len) {
case 1: writemem8(ctx, val, real, addr); break;
case 2: writemem16(ctx, val, real, addr); break;
case 4: writemem32(ctx, val, real, addr); break;
case 8: writemem64(ctx, val, real, addr); break;
default: log("writemem() bad length %d!\n", len); abort();
}
}
//----------------------------------------------------------------------------//
//
// The following functions zero-extend rather than sign-extend
//
ulong readmemzx(ctx_t *ctx, ulong addr, uint len)
{
GETREAL();
CHK_RANGE();
switch (len) {
case 1: return readmem8(ctx, real, addr); break;
case 2: return readmem16(ctx, real, addr); break;
case 4: return readmem32(ctx, real, addr); break;
case 8: return readmem64(ctx, real, addr); break;
default: log("readmem() bad length %d!\n", len); abort();
}
}
void writememzx(ctx_t *ctx, ulong val, ulong addr, uint len)
{
GETREAL();
CHK_RANGE();
switch (len) {
case 1: writemem8(ctx, val, real, addr); break;
case 2: writemem16(ctx, val, real, addr); break;
case 4: writemem32(ctx, val, real, addr); break;
case 8: writemem64(ctx, val, real, addr); break;
default: log("writemem() bad length %d!\n", len); abort();
}
}
// 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 <pc/arch.h>
//
// Imperatively read the "DECD" file before reading this code
//
static void check_param_type(ctx_t *ctx, instr_t *in, uint prm, uchar fmt)
{
bool ok;
if (prm == P_REG)
ok = (fmt == A_REG);
else if (prm == P_IMM)
ok = (fmt == A_IMM64);
else /* if (prm == P_MEM) */
ok = ACC_FMT_IS_MEM(fmt);
if (!ok)
_except(ctx, E_ILL,
"FT1 or FT2 not matching %s's expected parameter types: "
"fmt=0x%x prm=0x%x", in->full, fmt, prm);
}
void decode(ctx_t *ctx)
{
char *illmsg;
instr_t *in;
acc_t p1 = { 0 };
acc_t p2 = { 0 };
bool rep = 0;
uint cond = 0;
bool lock, nomore;
ushort w1, w2;
uchar f1 = 0, f2 = 0;
ulong pc = rip;
//
// Process the first word of the instruction
//
w1 = ctx->get(ctx);
// Extract first word flags
lock = !!(w1 & PREF_LOCK);
nomore = !!(w1 & PREF_NOMORE);
w1 &= ~(PREF_LOCK|PREF_NOMORE);
// Find instruction
if (w1 >= NINSTRS)
{
illmsg = "No such INSTR";
goto ill;
}
in = &ctx->i[w1];
if (nomore)
goto skip_w2;
//
// Process second word
//
w2 = ctx->get(ctx);
// REP and COND
rep = !!(w2 & PREF_REP);
cond = (w2 & BITS_COND) >> COND_SHIFT;
// F1 and F2
f1 = (w2 >> F1_SHIFT) & Fx_MASK;
f2 = w2 & Fx_MASK;
skip_w2:
//
// Deal with operand 1
//
if (in->prm1 == NOPRM)
{
if (f1 || f2)
{
illmsg = "FT1 and/or FT2 filled for 0-param INSTR";
goto ill;
}
exec_instr(ctx, in, NULL, NULL, lock, rep, cond, pc);
return;
}
check_param_type(ctx, in, in->prm1, f1);
extract_param(ctx, &p1, f1);
//
// Deal with operand 2
//
if (in->prm2 == NOPRM)
{
if (f2)
{
illmsg = "FT2 filled for 1-param INSTR";
goto ill;
}
exec_instr(ctx, in, &p1, NULL, lock, rep, cond, pc);
return;
}
check_param_type(ctx, in, in->prm2, f2);
extract_param(ctx, &p2, f2);
exec_instr(ctx, in, &p1, &p2, lock, rep, cond, pc);
return;
ill:
_except(ctx, E_ILL, illmsg);
}
//
// Verify that access to a certain register is legal
//
static void checkreg(ctx_t *ctx, uint reg, bool inv_is_ok)
{
if (reg >= NREGS)
_except(ctx, E_ILL, "Inexistent register: %u", reg);
if (reg == INV)
{
if (!inv_is_ok)
_except(ctx, E_ILL, "INV dereference");
else
return;
}
if (ctx->r[reg].flags & (RES | CTL))
//_except(ctx, E_ACC, "Reserved REG: %u", reg);
if (ctx->r[reg].flags & SYS)
if (cr0 & UF)
_except(ctx, E_SYS, "User access to SYS REG: %u", reg);
}
//
// Extract operand according to fmt
//
void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
{
uint mlen, mfmt;
ushort temp;
p->type = fmt;
if (fmt == A_REG)
{
p->reg = ctx->get(ctx);
checkreg(ctx, p->reg, 0);
p->val = R(p->reg);
return;
}
else if (fmt == A_IMM64)
{
p->val = ctx->get(ctx);
p->val |= (ulong)ctx->get(ctx) << 16;
p->val |= (ulong)ctx->get(ctx) << 32;
p->val |= (ulong)ctx->get(ctx) << 48;
return;
}
assert(ACC_FMT_IS_MEM(fmt));
//
// Handle a memory access
//
mlen = fmt & AM_MLEN_MASK;
mfmt = fmt & AM_MFMT_MASK;
p->mlen = (mlen == AM_8ACC ? 1
: (mlen == AM_16ACC ? 2
: (mlen == AM_32ACC ? 4
: (mlen == AM_64ACC ? 8 : 0))));
if (p->mlen == 0)
_except(ctx, E_ILL, "Invalid MLEN for access: %x", fmt);
switch (mfmt)
{
case AM_IMM64:
p->addr = ctx->get(ctx);
p->addr |= (ulong)ctx->get(ctx) << 16;
p->addr |= (ulong)ctx->get(ctx) << 32;
p->addr |= (ulong)ctx->get(ctx) << 48;
break;
case AM_RR:
case AM_RRI:
case AM_RRII:
temp = ctx->get(ctx);
p->reg1 = temp >> 8;
p->reg2 = temp & 0xFF;
checkreg(ctx, p->reg1, 1);
checkreg(ctx, p->reg2, 1);
if (mfmt == AM_RRI)
{
p->imm1 = 1;
p->imm2 = ctx->get(ctx);
}
else if (mfmt == AM_RRII)
{
p->imm1 = ctx->get(ctx);
p->imm2 = ctx->get(ctx);
}
else
{
p->imm1 = 1;
p->imm2 = 0;
}
p->addr = R(p->reg1) + R(p->reg2) * p->imm1
+ (long)(short)p->imm2;
break;
default:
_except(ctx, E_ILL, "Invalid MFMT for access: %x", fmt);
}
}
static bool eval_cond(ctx_t *ctx, uint cond)
{
bool neg = cond & (1 << 4);
bool ok;
cond &= ~(1 << 4);
switch (cond)
{
case CD_NONE: ok = 1; break;
case CD_C: ok = flg&CF; break;
case CD_O: ok = flg&OF; break;
case CD_Z: ok = flg&ZF; break;
case CD_S: ok = flg&SF; break;
case CD_P: ok = flg&PF; break;
case CD_A: ok = !(flg&CF || flg&ZF); break;
case CD_AE: ok = !(flg&CF); break;
case CD_B: ok = flg&CF; break;
case CD_BE: ok = flg&CF || flg&ZF; break;
case CD_G: ok = !(flg&ZF) && (!(flg&SF) == !(flg&OF)); break;
case CD_GE: ok = !(flg&SF) == !(flg&OF); break;
case CD_L: ok = !(flg&SF) != !(flg&OF); break;
case CD_LE: ok = flg&ZF || (!(flg&SF) != !(flg&OF)); break;
case CD_CXZ: ok = !rcx; break;
default:
_except(ctx, E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond));
}
return neg ? !ok : !!ok;
}
//
// Executes an instruction
//
void exec_instr(ctx_t *ctx,
instr_t *in,
acc_t *p1,
acc_t *p2,
bool lock,
bool rep,
uint cond,
ulong pc)
{
bool out;
ulong r1 = 0, r2 = 0;
// Debugging
dump_instr(ctx, in, p1, p2, lock, rep, cond, pc);
//
// For REPs we evaluate the condition AFTER running the instruction,
// in a do ... while(cond) fashion
//
if (!rep && !eval_cond(ctx, cond))
return;
do_rep:
out = in->func(ctx, p1, p2, &r1, &r2);
if (out)
{
if (p1->type == A_REG)
R(p1->reg) = r1;
else if (p1->type == A_IMM64)
_except(ctx, E_ACC, "Trying to output to an IMM64");
else
{
assert(ACC_IS_MEM(p1));
writemem(ctx, r1, p1->addr, p1->mlen);
}
}
if (out == 2)
{
if (p2->type == A_REG)
R(p2->reg) = r2;
else if (p2->type == A_IMM64)
_except(ctx, E_ACC, "Trying to output to an IMM64");
else
{
assert(ACC_IS_MEM(p2));
writemem(ctx, r2, p2->addr, p2->mlen);
}
}
if (rep)
{
// RCX remains untouched when condition fails
if (!eval_cond(ctx, cond))
return;
if (rcx > 0)
rcx--;
if (rcx == 0)
return;
// Show that we're REP'ing
dump_instr(ctx, in, p1, p2, lock, rep, cond, pc);
goto do_rep;
}
}
// 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 <pc/arch.h>
char *cond_suffixes[] =
{
"-",
"c", "o", "z", "s", "p",
"a", "ae", "b", "be",
"g", "ge", "l", "le",
"cxz",
"?"
};
static void dump_acc(ctx_t *ctx, acc_t *p)
{
uint mfmt;
if (p->type == A_REG)
log("%s", ctx->r[p->reg].name);
else if (p->type == A_IMM64)
{
if (p->val < 0xA)
log("%lu", p->val);
else
log("0x%lX", p->val);
}
else
{
log("%c[", getmempref(p->mlen));
mfmt = p->type & AM_MFMT_MASK;
if (mfmt == AM_IMM64)
log("0x%lX]", p->addr);
else if (mfmt == AM_RR)
{
if (p->reg1 && p->reg2)
log("%s+%s]", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
else log("%s]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
}
else if (mfmt == AM_RRI)
{
if (p->reg1 && p->reg2)
log("%s+%s+%hd]", ctx->r[p->reg1].name,
ctx->r[p->reg2].name, p->imm2);
else log("%s+%d]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name, p->imm2);
}
else if (mfmt == AM_RRII)
{
if (p->reg1)
log("%s+%s*%u+%hd]",
ctx->r[p->reg1].name,
ctx->r[p->reg2].name,
p->imm1, p->imm2);
else
log("%s*%u+%hd]",
ctx->r[p->reg2].name,
p->imm1, p->imm2);
}
}
}
void dump_instr(ctx_t *ctx,
instr_t *in,
acc_t *p1,
acc_t *p2,
bool lock,
bool rep,
uint cond,
ulong pc)
{
log("0x%lX: ", pc);
if (lock)
log("lock");
if (rep)
log(" rep");
if (cond)
{
log(".");
if (cond & (1 << 4))
{
cond &= ~(1 << 4);
log("n");
}
assert(cond <= sizeof(cond_suffixes)/sizeof(char *));
log("%s", cond_suffixes[cond]);
}
if (!rep)
log("\t\t");
else
log("\t");
log("%s\t", in->name);
if (p1) {
dump_acc(ctx, p1);
if (p2) {
log(", ");
dump_acc(ctx, p2);
}
}
log("\n");
}
// 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 <pc/arch.h>
reg_t arch_r[NREGS] =
{
// Invalid register
{ "inv", 0, RES },
// Instruction pointer
{ "rip", 0, RES },
// Flags register
{ "flg", 0, RES },
// Stack registers
{ "rbp", 0, GPR },
{ "rsp", 0, GPR },
// Reserved registers
{ "rx0", 0, RES },
{ "rx1", 0, RES },
{ "rx2", 0, RES },
// General-purpose volatile registers
{ "rax", 0, GPR },
{ "rbx", 0, GPR },
{ "rcx", 0, GPR },
{ "rdx", 0, GPR },
{ "rsx", 0, GPR },
{ "rbi", 0, GPR },
{ "rdi", 0, GPR },
{ "rsi", 0, GPR },
// General-purpose non-volatile registers
{ "nx0", 0, GPR },
{ "nx1", 0, GPR },
{ "nx2", 0, GPR },
{ "nx3", 0, GPR },
{ "nx4", 0, GPR },
{ "nx5", 0, GPR },
{ "nx6", 0, GPR },
{ "nx7", 0, GPR },
// Argument registers; volatile
{ "ax0", 0, GPR },
{ "ax1", 0, GPR },
{ "ax2", 0, GPR },
{ "ax3", 0, GPR },
{ "ax4", 0, GPR },
{ "ax5", 0, GPR },
{ "ax6", 0, GPR },
{ "ax7", 0, GPR },
// Leaf function registers; volatile
{ "lx0", 0, GPR },
{ "lx1", 0, GPR },
{ "lx2", 0, GPR },
{ "lx3", 0, GPR },
{ "lx4", 0, GPR },
{ "lx5", 0, GPR },
{ "lx6", 0, GPR },
{ "lx7", 0, GPR },
// Control register
{ "cr0", 0, CTL },
{ "cr1", 0, CTL },
{ "cr2", 0, CTL },
{ "cr3", 0, CTL },
{ "cr4", 0, CTL },
{ "cr5", 0, CTL },
{ "cr6", 0, CTL },
{ "cr7", 0, CTL },
// System-reserved
{ "sa0", 0, SYS },
{ "sa1", 0, SYS },
{ "sa2", 0, SYS },
{ "sa3", 0, SYS },
{ "sa4", 0, SYS },
{ "sa5", 0, SYS },
{ "sa6", 0, SYS },
{ "sa7", 0, SYS },
};
#define DUMPREGS(down, up) \
for (i = down; i <= up; i++) { \
if (i % 4 == 0) \
log("\n"); \
r = &ctx->r[i]; \
log("%s=0x%-16lX ", r->name, r->val); \
} \
void dumpregs(ctx_t *ctx)
{
int i;
reg_t *r;
assert(inv == 0);
DUMPREGS(RAX, RSI);
DUMPREGS(AX0, AX3);
DUMPREGS(LX0, LX3);
log("\n");
DUMPREGS(NX0, NX3);
DUMPREGS(SA0, SA3);
DUMPREGS(CR0, CR3);
log("\n\nrip=0x%-16lX rsp=0x%-16lX rbp=0x%-16lX flg=0x%-16lX\n\n",
rip, rsp, rbp, flg);
log("CF=%x OF=%x\n"
"ZF=%x SF=%x\n"
"PF=%x DF=%x\n"
"IF=%x UF=%x\n",
!!(flg&CF), !!(flg&OF),
!!(flg&ZF), !!(flg&SF),
!!(flg&PF), !!(flg&DF),
!!(flg&IF), !!(cr0&UF));
}
// 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 <pc/arch.h>
void log(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
void vlog(const char *fmt, va_list ap)
{
vfprintf(stderr, fmt, ap);
}
// 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 <pc/dev.h>
//----------------------------------------------------------------------------//
//
// Add new builtin devices here
//
extern dev_t cpudev, memdev;
static dev_t *arch_d[] =
{
&cpudev,
&memdev,
NULL,
};
int devinitall(ctx_t *ctx)
{
size_t it;
for (it = 0; arch_d[it] != NULL; it++) {
// log("Adding device %s\n", arch_d[it]->name);
if (devinit(ctx, arch_d[it]) < 0)
return -1;
}
return 0;
}
int devfiniall(ctx_t *ctx)
{
int failed = 0;
while (ctx->dh)
if (devfini(ctx, ctx->dh) < 0)
failed = -1;
return failed;
}
//----------------------------------------------------------------------------//
dev_t *devalloc(void)
{
return calloc(sizeof(dev_t)/sizeof(ulong), sizeof(ulong));
}
void devfree(dev_t *dev)
{
assert(dev != NULL);
free(dev);
}
//----------------------------------------------------------------------------//
dev_t *devget(ctx_t *ctx, int idx)
{
if (idx < 0)
return NULL;
int i;
dev_t *dev;
for (i = 0, dev = ctx->dh; dev && i != idx; dev = dev->next, i++);
return dev;
}
void devattach(ctx_t *ctx, dev_t *dev)
{
dev_t *it;
assert(dev != NULL);
if (ctx->dh) {
for (it = ctx->dh; it->next != NULL; it = it->next);
it->next = dev;
}
else ctx->dh = dev;
}
int devinit(ctx_t *ctx, dev_t *dev)
{
if (!dev || dev->state != DEVPWOF)
return -1;
if (dev->fpwon)
dev->fpwon(ctx, dev);
else dev->state = DEVGOOD;
if (!(dev->state == DEVPLUG || dev->state == DEVGOOD))
return -1;
dev->id = random();
devattach(ctx, dev);
return 0;
}
//----------------------------------------------------------------------------//
// NEVER detach while some assembly code
// may still be running on the vm!
void devdetach(ctx_t *ctx, dev_t *dev)
{
dev_t *it;
assert(dev != NULL);
if (dev == ctx->dh) {
ctx->dh = dev->next;
}
for (it = ctx->dh; it; it = it->next) {
if (!it)
break;
if (it->next == dev) {
it->next = dev->next;
break;
}
}
}
int devfini(ctx_t *ctx, dev_t *dev)
{
if (dev->state == DEVPWOF || dev->state == DEVFERR) {
goto err;
}
if (dev->fpwoff)
dev->fpwoff(ctx, dev);
else dev->state = DEVPWOF;
if (dev->state != DEVPWOF)
goto err;
devdetach(ctx, dev);
return 0;
err:
devdetach(ctx, dev);
return -1;
}
// 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 <signal.h>
#include <pc/dev.h>
#include <sys/time.h>
#include <termio.h>
#define FWPROGSIZE (1024 * 1024 * 1024)
static ssize_t fwsize;
static ushort *fwprog;
ushort bget(ctx_t *ctx)
{
if (rip % 2) {
_except(ctx, E_ALI, "Misaligned RIP register: 0x%016lX",
rip);
}
if (addr2real(rip) >= ctx->mz) {
_except(ctx, E_ACC, "Executing out of memory: 0x%016lX",
rip);
}
ushort c = ctx->mp[addr2real(rip)];
rip += 2;
return c;
}
ctx_t main_ctx;
void sigint(int _)
{
//
// Enable stdin echoing
//
struct termios t;
tcgetattr(0, &t);
t.c_lflag |= ECHO;
tcsetattr(0, TCSANOW, &t);
//
// Shut down devices
//
devfiniall(&main_ctx);
exit(0);
}
int main(int argc, char **argv)
{
FILE *fwfile;
main_ctx.r = arch_r;
main_ctx.i = arch_i;
//
// srand
//
struct timeval time;
gettimeofday(&time, NULL);
srandom((time.tv_sec * 1000) + (time.tv_usec / 1000));
//
// Disable stdin echoing
//
struct termios t;
tcgetattr(0, &t);
t.c_lflag &= ~ECHO;
tcsetattr(0, TCSANOW, &t);
//
// Signal handling
//
signal(SIGINT, sigint);
//
// Load program
//
if (argc < 2) {
log("Not enough arguments\n");
exit(-3);
}
fwprog = malloc(FWPROGSIZE);
fwfile = fopen(argv[1], "rb");
if (!fwprog) {
log("Couldn't allocate firmware buffer\n");
exit(-1);
}
if (!fwfile) {
log("Couldn't open program file\n");
exit(-2);
}
fwsize = fread(fwprog, 1, FWPROGSIZE, fwfile);
if (fwsize < 2) {
log("Program file too small or empty\n");
exit(-3);
}
main_ctx.mp = malloc(MEMSIZE + 16);
main_ctx.mz = MEMSIZE;
main_ctx.get = bget;
main_ctx.r[RIP].val = MEMOFF;
if (main_ctx.mp == 0) {
log("Couldn't allocate RAM\n");
exit(-1);
}
memcpy(&main_ctx.mp[addr2real(main_ctx.r[RIP].val)], fwprog, fwsize);
main_ctx.dh = 0;
if (devinitall(&main_ctx) < 0) {
log("Couldn't initialize devices\n");
exit(-10);
}
while (1) {
decode(&main_ctx);
if (main_ctx.step)
getchar();
}
}
// 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 <pc/dev.h>
#include <in/instrs.h>
//
// code common to devctl and iocall
//
dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
{
dev_t *dev = devget(ctx, v1);
if (!dev)
rax = -2;
else if (dev->state == DEVPWOF)
rax = -3;
else if (dev->state == DEVFERR)
rax = -4;
else if (dev->state == DEVPLUG)
rax = -5;
else
return dev;
return NULL;
}
void copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str)
{
for (; *str && maxn > 0; str++, addr++, maxn--) {
writemem(ctx, *str, addr, 1);
}
writemem(ctx, 0, addr, 1);
}
IMPL_START_2(devctl)
{
CHK_SUPERV();
dev_t *dev = devctl_common(ctx, v1, v2);
if (dev == NULL)
return 0;
switch (v2) {
case 0:
copystr(ctx, ax0, DEVLEN, dev->type);
break;
case 1:
copystr(ctx, ax0, DEVLEN, dev->name);
break;
case 2:
copystr(ctx, ax0, DEVLEN, dev->modl);
break;
case 3:
copystr(ctx, ax0, DEVLEN, dev->vend);
break;
case 4:
rax = dev->major;
rdx = dev->minor;
break;
case 5:
rax = dev->feats;
rdx = dev->revis;
break;
default:
rax = -6;
break;
}
}
IMPL_END;
IMPL_START_2(iocall)
{
CHK_SUPERV();
long rc;
dev_t *dev = devctl_common(ctx, v1, v2);
if (dev == NULL)
return 0;
if (v2 >= DEVSLOTS)
rax = -6;
else if (dev->fslots[v2] == NULL)
rax = -6;
else {
rc = dev->fslots[v2](ctx, dev);
if (rc < 0) rax = rc;
}
}
IMPL_END;
// 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 _NEED_ARCH_I
#include <in/arch_i.h>
IMPL_START_0(nop)
{
}
IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_1(prn)
{
if (p1->mlen > 1) {
log("prn warning: large access size\n");
}
putchar((int)v1);
}
IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_0(cld)
{
flg &= ~DF;
}
IMPL_END;
IMPL_START_0(std)
{
flg |= DF;
}
IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_0(cmc)
{
flg = (flg&CF ? flg&~CF : flg|CF);
}
IMPL_END;
IMPL_START_0(clc)
{
flg &= ~CF;
}
IMPL_END;
IMPL_START_0(stc)
{
flg |= CF;
}
IMPL_END;
//----------------------------------------------------------------------------//
IMPL_START_0(clr)
{
rax = rbx = rcx = rdx = 0;
rsx = rbi = rdi = rsi = 0;
}
IMPL_END;
IMPL_START_0(cla)
{
ax0 = ax1 = ax2 = ax3 = 0;
ax4 = ax5 = ax6 = ax7 = 0;
}
IMPL_END;
//----------------------------------------------------------------------------//
// 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>
//
// Stack manipulation instructions
//
IMPL_START_1(push)
{
CHK_STACK(<);
PUSH(v1);
}
IMPL_END;
IMPL_START_1(pop)
{
CHK_STACK(<=);
POP(v1);
}
IMPL_OUT;
IMPL_START_1(call)
{
CHK_STACK(<);
PUSH(rip);
JUMP(v1);
}
IMPL_END;
IMPL_START_0(ret)
{
CHK_STACK(<=);
POP(rip);
}
IMPL_END;
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(rbp);
rbp = rsp;
if (p1) {
rsp -= p1->val * 8;
}
}
IMPL_END;
IMPL_START_0(leave)
{
// Do NOT check stack here
// (it would always fail)
rsp = rbp;
POP(rbp);
}
IMPL_END;
IMPL_START_0(pushf)
{
CHK_STACK(<);
PUSH(flg);
}
IMPL_END;
IMPL_START_0(popf)
{
CHK_STACK(<=);
// XXX
CHK_SUPERV();
POP(flg);
}
IMPL_END;
// 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_0(break)
{
log("\nExecuting BREAK INSTR\n");
dumpregs(ctx);
getchar();
log("Resuming execution\n");
}
IMPL_END;
IMPL_START_1(step)
{
ctx->step = !!v1;
}
IMPL_END;
IMPL_START_0(err)
{
}
IMPL_END;
// 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_1(lea)
{
v1 = p2->addr;
}
IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_2(mov)
{
v1 = v2;
}
IMPL_OUT;
IMPL_START_1(movzx)
{
DECVZX(v2, p2);
v1 = v2;
}
IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_2(xchg)
{
ulong t = v1;
v1 = v2;
v2 = t;
}
IMPL_OUT_2;
IMPL_START_2(cmpxchg)
{
if (rax == v1) {
flg |= ZF;
v1 = v2;
}
else {
flg &= ~ZF;
rax = v1;
}
}
IMPL_OUT;
//----------------------------------------------------------------------------//
IMPL_START_1(gco)
{
v1 = cr1;
}
IMPL_OUT;
IMPL_START_1(gcd)
{
v1 = cr2;
}
IMPL_OUT;
// 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>
//
// Supervisor only instructions
//
IMPL_START_0(cli)
{
CHK_SUPERV();
flg &= ~IF;
}
IMPL_END;
IMPL_START_0(sti)
{
CHK_SUPERV();
flg |= IF;
}
IMPL_END;
IMPL_START_0(stop)
{
CHK_SUPERV();
_except(ctx, E_SHT, "STOP INSTR");
}
IMPL_END;
// 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_2(sgn)
{
v1 = (v2 == 0 ? 0 :
((long)v2 < 0 ? (ulong)-1L : 1));
}
IMPL_OUT;
IMPL_START_2(sgnf)
{
v1 = (long)v2 < 0 ? (ulong)-1L : 1;
}
IMPL_OUT_ZSF;
IMPL_START_1(neg)
{
v1 = ~v1 + 1;
}
IMPL_OUT;
IMPL_START_1(negf)
{
if (v1 == 0) flg |= CF;
else {
flg &= ~CF;
if (v1 == LONG_MIN) flg |= OF;
else flg &= ~OF;
}
v1 = ~v1 + 1;
}
IMPL_OUT_ZSF;
//--------------------------------------------------------------------------
IMPL_START_1(inc)
{
v1++;
}
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;
}
IMPL_OUT;
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(sub)
{
v1 -= v2;
}
IMPL_OUT;
IMPL_START_2(subf)
{
COMPARE(v1, v2);
v1 -= v2;
}
IMPL_OUT;
//
// i_subf but discards result
//
IMPL_START_2(cmp)
{
COMPARE(v1, v2);
}
IMPL_END;
//--------------------------------------------------------------------------
//
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
//
static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
{
ulong u1 = (u & 0xffffffff);
ulong v1 = (v & 0xffffffff);
ulong t = (u1 * v1);
ulong w3 = (t & 0xffffffff);
ulong k = (t >> 32);
u >>= 32;
t = (u * v1) + k;
k = (t & 0xffffffff);
ulong w1 = (t >> 32);
v >>= 32;
t = (u1 * v) + k;
k = (t >> 32);
*hi = (u * v) + w1 + k;
*lo = (t << 32) + w3;
}
IMPL_START_2(mul)
{
ulong hi;
multiply(v1, v2, &hi, &v1);
}
IMPL_OUT;
IMPL_START_2(mulf)
{
ulong hi;
multiply(v1, v2, &hi, &v1);
if (hi > 0) {
flg |= CF;
flg |= OF;
}
else {
flg &= ~CF;
flg &= ~OF;
}
}
IMPL_OUT;
IMPL_START_1(mul2)
{
multiply(rax, v1, &rdx, &rax);
}
IMPL_END;
IMPL_START_1(mul2f)
{
multiply(rax, v1, &rdx, &rax);
if (rdx > 0) {
flg |= CF;
flg |= OF;
}
else {
flg &= ~CF;
flg &= ~OF;
}
}
IMPL_END;
//--------------------------------------------------------------------------
IMPL_START_2(div)
{
v1 /= v2;
}
IMPL_OUT;
IMPL_START_2(mod)
{
v1 %= v2;
}
IMPL_OUT;
IMPL_START_1(div2)
{
rdx = rax % v1;
rax = rax / v1;
}
IMPL_END;
// 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>
//
// Jump instructions
//
IMPL_START_1(j)
{
JUMP(v1);
}
IMPL_END;
IMPL_START_1(jmp)
{
JUMP(v1);
}
IMPL_END;
IMPL_START_1(loop)
{
if (rcx > 0) {
rcx--;
JUMP(v1);
}
}
IMPL_END;
// 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 STR_MOVE(reg, len) \
if ((flg & DF) == 0) \
R(reg) += len; \
else \
R(reg) -= len;
//----------------------------------------------------------------------------//
void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
ulong reg, val;
if (p2) {
DECV(v2, p2);
reg = p1->reg;
val = v2;
}
else if (p1) {
DECV(v1, p1);
reg = RDI;
val = v1;
}
else {
reg = RDI;
val = rax;
}
writemem(ctx, val, R(reg), len);
STR_MOVE(reg, len);
}
IMPL_START_0(stosb)
{
stos_impl(ctx, p1, p2, 1);
}
IMPL_END;
IMPL_START_0(stosw)
{
stos_impl(ctx, p1, p2, 2);
}
IMPL_END;
IMPL_START_0(stosl)
{
stos_impl(ctx, p1, p2, 4);
}
IMPL_END;
IMPL_START_0(stosq)
{
stos_impl(ctx, p1, p2, 8);
}
IMPL_END;
//----------------------------------------------------------------------------//
void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
ulong reg1, reg2;
if (p2) {
reg1 = p1->reg;
reg2 = p2->reg;
}
else if (p1) {
reg1 = p1->reg;
reg2 = RSI;
}
else {
reg1 = RAX;
reg2 = RSI;
}
R(reg1) = readmem(ctx, R(reg2), len);
flg = (R(reg1) == 0 ? flg|ZF : flg&~ZF);
STR_MOVE(reg2, len);
}
IMPL_START_0(lodsb)
{
lods_impl(ctx, p1, p2, 1);
}
IMPL_END;
IMPL_START_0(lodsw)
{
lods_impl(ctx, p1, p2, 2);
}
IMPL_END;
IMPL_START_0(lodsl)
{
lods_impl(ctx, p1, p2, 4);
}
IMPL_END;
IMPL_START_0(lodsq)
{
lods_impl(ctx, p1, p2, 8);
}
IMPL_END;
//----------------------------------------------------------------------------//
void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
ulong reg, val;
if (p2) {
DECV(v2, p2);
reg = p1->reg;
val = v2;
}
else if (p1) {
DECV(v1, p1);
reg = RDI;
val = v1;
}
else {
reg = RDI;
val = rax;
}
ulong x = readmem(ctx, R(reg), len);
COMPARE(x, val);
STR_MOVE(reg, len);
}
IMPL_START_0(scasb)
{
scas_impl(ctx, p1, p2, 1);
}
IMPL_END;
IMPL_START_0(scasw)
{
scas_impl(ctx, p1, p2, 2);
}
IMPL_END;
IMPL_START_0(scasl)
{
scas_impl(ctx, p1, p2, 4);
}
IMPL_END;
IMPL_START_0(scasq)
{
scas_impl(ctx, p1, p2, 8);
}
IMPL_END;
//----------------------------------------------------------------------------//
void cmps_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
ulong reg1, reg2;
if (p2) {
reg1 = p1->reg;
reg2 = p2->reg;
}
else if (p1) {
reg1 = RDI;
reg2 = p1->reg;
}
else {
reg1 = RDI;
reg2 = RSI;
}
ulong x1 = readmem(ctx, R(reg1), len);
ulong x2 = readmem(ctx, R(reg2), len);
COMPARE(x1, x2);
STR_MOVE(reg1, len);
STR_MOVE(reg2, len);
}
IMPL_START_0(cmpsb)
{
cmps_impl(ctx, p1, p2, 1);
}
IMPL_END;
IMPL_START_0(cmpsw)
{
cmps_impl(ctx, p1, p2, 2);
}
IMPL_END;
IMPL_START_0(cmpsl)
{
cmps_impl(ctx, p1, p2, 4);
}
IMPL_END;
IMPL_START_0(cmpsq)
{
cmps_impl(ctx, p1, p2, 8);
}
IMPL_END;
//----------------------------------------------------------------------------//
void cmpzs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
ulong reg1, reg2;
if (p2) {
reg1 = p1->reg;
reg2 = p2->reg;
}
else if (p1) {
reg1 = RDI;
reg2 = p1->reg;
}
else {
reg1 = RDI;
reg2 = RSI;
}
ulong x1 = readmem(ctx, R(reg1), len);
ulong x2 = readmem(ctx, R(reg2), len);
COMPARE(x1, x2);
if (!x1 && !x2)
flg &= ~ZF;
STR_MOVE(reg1, len);
STR_MOVE(reg2, len);
}
IMPL_START_0(cmpzsb)
{
cmpzs_impl(ctx, p1, p2, 1);
}
IMPL_END;
IMPL_START_0(cmzpsw)
{
cmpzs_impl(ctx, p1, p2, 2);
}
IMPL_END;
IMPL_START_0(cmpzsl)
{
cmpzs_impl(ctx, p1, p2, 4);
}
IMPL_END;
IMPL_START_0(cmpzsq)
{
cmpzs_impl(ctx, p1, p2, 8);
}
IMPL_END;
//----------------------------------------------------------------------------//
void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{
ulong reg1, reg2;
if (p2) {
reg1 = p1->reg;
reg2 = p2->reg;
}
else if (p1) {
reg1 = RDI;
reg2 = p1->reg;
}
else {
reg1 = RDI;
reg2 = RSI;
}
ulong x = readmem(ctx, R(reg2), len);
writemem(ctx, x, R(reg1), len);
flg = (x == 0 ? flg|ZF : flg&~ZF);
STR_MOVE(reg1, len);
STR_MOVE(reg2, len);
}
IMPL_START_0(movsb)
{
movs_impl(ctx, p1, p2, 1);
}
IMPL_END;
IMPL_START_0(movsw)
{
movs_impl(ctx, p1, p2, 2);
}
IMPL_END;
IMPL_START_0(movsl)
{
movs_impl(ctx, p1, p2, 4);
}
IMPL_END;
IMPL_START_0(movsq)
{
movs_impl(ctx, p1, p2, 8);
}
IMPL_END;
//----------------------------------------------------------------------------//
// 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_1(not)
{
v1 = ~v1;
}
IMPL_OUT;
//--------------------------------------------------------------------------
IMPL_START_2(test)
{
flg &= ~OF;
flg &= ~CF;
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;
}
IMPL_OUT;
IMPL_START_2(orf)
{
flg &= ~OF;
flg &= ~CF;
v1 |= v2;
}
IMPL_OUT_ZSF;
IMPL_START_2(xor)
{
v1 ^= v2;
}
IMPL_OUT;
IMPL_START_2(xorf)
{
flg &= ~OF;
flg &= ~CF;
v1 ^= v2;
}
IMPL_OUT_ZSF;
//--------------------------------------------------------------------------
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;
//--------------------------------------------------------------------------
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
enum
{
CD_NONE,
CD_C, CD_O, CD_Z, CD_S, CD_P,
CD_A, CD_AE, CD_B, CD_BE,
CD_G, CD_GE, CD_L, CD_LE,
CD_CXZ, COND_RES,
};
enum
{
PREF_LOCK = (1 << 15),
PREF_NOMORE = (1 << 14),
PREF_REP = (1 << 15),
BITS_COND = (1 << 14) | (1 << 13) | (1 << 12)
| (1 << 11) | (1 << 10),
COND_SHIFT = 10,
Fx_MASK = 0x1F,
F1_SHIFT = 5,
};
enum
{
A_NONE = 0b00000,
A_REG = 0b00001,
A_IMM64 = 0b00010,
AM_START = 0b00100,
AM_IMM64 = 0b00,
AM_RR = 0b01,
AM_RRI = 0b10,
AM_RRII = 0b11,
AM_8ACC = 0b00100,
AM_16ACC = 0b01000,
AM_32ACC = 0b01100,
AM_64ACC = 0b10000,
AM_MLEN_MASK = 0b11100,
AM_MFMT_MASK = 0b00011,
};
#define ACC_FMT_IS_MEM(x) ((x) >= AM_START && (x) <= (AM_64ACC|AM_RRII))
#define ACC_IS_MEM(x) (ACC_FMT_IS_MEM((x)->type))
struct acc_t
{
uint type;
ulong val;
// A_REG
ulong reg;
// AM_...
ulong addr;
uint mlen;
// For instruction dumping ONLY
ushort reg1, reg2;
short imm1, imm2;
};
enum { NOPRM, P_REG, P_IMM, P_MEM=4 };
struct instr_t
{
char *name;
char *full;
uint prm1;
uint prm2;
bool (*func)(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
};
void exec_instr(ctx_t *ctx,
instr_t *in,
acc_t *p1,
acc_t *p2,
bool lock,
bool rep,
uint cond,
ulong pc);
void extract_param(ctx_t *ctx,
acc_t *p,
uchar fmt);
void dump_instr(ctx_t *ctx,
instr_t *in,
acc_t *p1,
acc_t *p2,
bool lock,
bool rep,
uint cond,
ulong pc);
// 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 MEMOFF (1 * 1024 * 1024)
#define MEMSIZE (16 * 1024 * 1024) // 16MB
#define addr2real(p) (((p) - MEMOFF) / 2)
#define real2addr(p) (((p) + MEMOFF) / 2)
// Address of boot firmware stack
#define FWSTACK (MEMOFF * 2) // 2MB
ulong readmem(ctx_t *c, ulong addr, uint len);
void writemem(ctx_t *, ulong val, ulong addr, uint len);
ulong readmemzx(ctx_t *c, ulong addr, uint len);
void writememzx(ctx_t *, ulong val, ulong addr, uint len);
// 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 <pc/arch.h>
#define DEVLEN 32
#define DEVSLOTS 256
typedef long (*devfn_t)(ctx_t *, dev_t *);
enum
{
DEVPWOF, // Power off
DEVPLUG, // Unplugged or plugging
DEVGOOD, // Plugged and working
DEVFERR, // Fatal error
};
struct dev_t
{
dev_t *next;
char type[DEVLEN];
char name[DEVLEN];
char modl[DEVLEN];
char vend[DEVLEN];
int major;
int minor;
int revis;
ulong feats;
long id;
uint state;
void *data;
devfn_t fpwon;
devfn_t fpwoff;
devfn_t fplug;
devfn_t funplug;
devfn_t fslots[DEVSLOTS];
};
dev_t *devalloc(void);
void devfree(dev_t *);
dev_t *devget(ctx_t *, int);
void devattach(ctx_t *, dev_t *);
void devdetach(ctx_t *, dev_t *);
int devinit(ctx_t *, dev_t *);
int devfini(ctx_t *, dev_t *);
int devinitall(ctx_t *);
int devfiniall(ctx_t *);
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Register types
enum
{
GPR = 1 << 0, // General
CTL = 1 << 1, // Control
SEG = 1 << 2, // Segment
RES = 1 << 8, // Reserved for insternal use
SYS = 1 << 9, // Reserved for supervisor mode
};
// FLG register
enum
{
CF = 1 << 0, // Carry 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
IF = 1 << 16, // Interrupts enable flag
};
// CR0 register
enum
{
UF = 1 << 15, // User-mode flag
};
struct reg_t
{
char *name;
ulong val;
ulong flags;
};
enum
{
INV = 0,
RIP, FLG, RBP, RSP,
RX0, RX1, RX2,
#define inv R(INV)
#define rip R(RIP)
#define flg R(FLG)
#define rbp R(RBP)
#define rsp R(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)
NX0, NX1, NX2, NX3,
NX4, NX5, NX6, NX7,
#define nx0 R(NX0)
#define nx1 R(NX1)
#define nx2 R(NX2)
#define nx3 R(NX3)
AX0, AX1, AX2, AX3,
AX4, AX5, AX6, AX7,
#define ax0 R(AX0)
#define ax1 R(AX1)
#define ax2 R(AX2)
#define ax3 R(AX3)
#define ax4 R(AX4)
#define ax5 R(AX5)
#define ax6 R(AX6)
#define ax7 R(AX7)
LX0, LX1, LX2, LX3,
LX4, LX5, LX6, LX7,
CR0, CR1, CR2, CR3,
CR4, CR5, CR6, CR7,
#define cr0 R(CR0)
#define cr1 R(CR1)
#define cr2 R(CR2)
#define cr3 R(CR3)
SA0, SA1, SA2, SA3,
SA4, SA5, SA6, SA7,
#define sa0 R(SA0)
#define sa1 R(SA1)
#define sa2 R(SA2)
#define sa3 R(SA3)
NREGS
};
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#ifndef _ARCH_H
#define _ARCH_H
#define dev_t stddev_t
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <limits.h>
#undef dev_t
#define packed __attribute__ ((__packed__))
#define static_assert _Static_assert
#define alignof _Alignof
typedef unsigned int bool;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef struct reg_t reg_t;
typedef struct ctx_t ctx_t;
typedef struct instr_t instr_t;
typedef struct acc_t acc_t;
typedef struct arch_t arch_t;
typedef struct dev_t dev_t;
void log(const char *, ...);
void vlog(const char *, va_list);
#define KARCH_MAJOR 0
#define KARCH_MINOR 1
#define KARCH_REVIS 0
struct ctx_t
{
reg_t *r;
instr_t *i;
// Memory and memory size
ushort *mp;
ulong mz;
// Read next instruction
ushort (*get)(ctx_t *ctx);
// Step by step
int step;
// Devices list head
dev_t *dh;
};
#define R(X) ctx->r[X].val
static inline ushort bswap16(ushort u)
{ return ((u<<8) | (u>>8)); }
static inline char getmempref(ushort len)
{ return (len==1?'b':(len==2?'w':(len==4?'l':(len==8?'q':'x')))); }
enum
{
E_SHT, // Shutdown instruction
E_IMP, // Not implemented
E_ILL, // Ill-formed
E_ACC, // Invalid access
E_SYS, // Supervisor only
E_ALI, // Alignment error
E_STA, // Stack misalignment
E_STU, // Stack underflow
NEXCPTS
};
void dumpregs(ctx_t *);
void dumpinstr(ctx_t *, ulong, uint, ushort, acc_t *, acc_t *);
void dumpmem(ctx_t *, ulong, ulong);
void _except(ctx_t *, int, char *, ...) __attribute__((__noreturn__));
void decode(ctx_t *ctx);
#include <pc/mem.h>
#include <pc/regs.h>
#include <pc/decd.h>
#include <in/arch_i.h>
extern reg_t arch_r[NREGS];
extern instr_t arch_i[NINSTRS];
#endif
// Auto-generated by arch_i.py from INSTRS
#ifdef _NEED_ARCH_I
instr_t arch_i[] =
{
#endif
#ifdef _NEED_ARCH_I
{ "stop", "stop", NOPRM, NOPRM, i_stop },
#else
#define I_STOP 0
extern bool i_stop(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "not", "not_r", P_REG, NOPRM, i_not },
#else
#define I_NOT_R 1
extern bool i_not(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "not", "not_m", P_MEM, NOPRM, i_not },
#else
#define I_NOT_M 2
extern bool i_not(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "or", "or_r_r", P_REG, P_REG, i_or },
#else
#define I_OR_R_R 3
extern bool i_or(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "or", "or_r_i", P_REG, P_IMM, i_or },
#else
#define I_OR_R_I 4
extern bool i_or(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "or", "or_r_m", P_REG, P_MEM, i_or },
#else
#define I_OR_R_M 5
extern bool i_or(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "or", "or_m_r", P_MEM, P_REG, i_or },
#else
#define I_OR_M_R 6
extern bool i_or(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "or", "or_m_i", P_MEM, P_IMM, i_or },
#else
#define I_OR_M_I 7
extern bool i_or(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "or", "or_m_m", P_MEM, P_MEM, i_or },
#else
#define I_OR_M_M 8
extern bool i_or(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "orf", "orf_r_r", P_REG, P_REG, i_orf },
#else
#define I_ORF_R_R 9
extern bool i_orf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "orf", "orf_r_i", P_REG, P_IMM, i_orf },
#else
#define I_ORF_R_I 10
extern bool i_orf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "orf", "orf_r_m", P_REG, P_MEM, i_orf },
#else
#define I_ORF_R_M 11
extern bool i_orf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "orf", "orf_m_r", P_MEM, P_REG, i_orf },
#else
#define I_ORF_M_R 12
extern bool i_orf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "orf", "orf_m_i", P_MEM, P_IMM, i_orf },
#else
#define I_ORF_M_I 13
extern bool i_orf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "orf", "orf_m_m", P_MEM, P_MEM, i_orf },
#else
#define I_ORF_M_M 14
extern bool i_orf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "and", "and_r_r", P_REG, P_REG, i_and },
#else
#define I_AND_R_R 15
extern bool i_and(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "and", "and_r_i", P_REG, P_IMM, i_and },
#else
#define I_AND_R_I 16
extern bool i_and(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "and", "and_r_m", P_REG, P_MEM, i_and },
#else
#define I_AND_R_M 17
extern bool i_and(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "and", "and_m_r", P_MEM, P_REG, i_and },
#else
#define I_AND_M_R 18
extern bool i_and(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "and", "and_m_i", P_MEM, P_IMM, i_and },
#else
#define I_AND_M_I 19
extern bool i_and(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "and", "and_m_m", P_MEM, P_MEM, i_and },
#else
#define I_AND_M_M 20
extern bool i_and(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "andf", "andf_r_r", P_REG, P_REG, i_andf },
#else
#define I_ANDF_R_R 21
extern bool i_andf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "andf", "andf_r_i", P_REG, P_IMM, i_andf },
#else
#define I_ANDF_R_I 22
extern bool i_andf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "andf", "andf_r_m", P_REG, P_MEM, i_andf },
#else
#define I_ANDF_R_M 23
extern bool i_andf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "andf", "andf_m_r", P_MEM, P_REG, i_andf },
#else
#define I_ANDF_M_R 24
extern bool i_andf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "andf", "andf_m_i", P_MEM, P_IMM, i_andf },
#else
#define I_ANDF_M_I 25
extern bool i_andf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "andf", "andf_m_m", P_MEM, P_MEM, i_andf },
#else
#define I_ANDF_M_M 26
extern bool i_andf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xor", "xor_r_r", P_REG, P_REG, i_xor },
#else
#define I_XOR_R_R 27
extern bool i_xor(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xor", "xor_r_i", P_REG, P_IMM, i_xor },
#else
#define I_XOR_R_I 28
extern bool i_xor(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xor", "xor_r_m", P_REG, P_MEM, i_xor },
#else
#define I_XOR_R_M 29
extern bool i_xor(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xor", "xor_m_r", P_MEM, P_REG, i_xor },
#else
#define I_XOR_M_R 30
extern bool i_xor(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xor", "xor_m_i", P_MEM, P_IMM, i_xor },
#else
#define I_XOR_M_I 31
extern bool i_xor(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xor", "xor_m_m", P_MEM, P_MEM, i_xor },
#else
#define I_XOR_M_M 32
extern bool i_xor(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xorf", "xorf_r_r", P_REG, P_REG, i_xorf },
#else
#define I_XORF_R_R 33
extern bool i_xorf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xorf", "xorf_r_i", P_REG, P_IMM, i_xorf },
#else
#define I_XORF_R_I 34
extern bool i_xorf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xorf", "xorf_r_m", P_REG, P_MEM, i_xorf },
#else
#define I_XORF_R_M 35
extern bool i_xorf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xorf", "xorf_m_r", P_MEM, P_REG, i_xorf },
#else
#define I_XORF_M_R 36
extern bool i_xorf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xorf", "xorf_m_i", P_MEM, P_IMM, i_xorf },
#else
#define I_XORF_M_I 37
extern bool i_xorf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xorf", "xorf_m_m", P_MEM, P_MEM, i_xorf },
#else
#define I_XORF_M_M 38
extern bool i_xorf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shl", "shl_r_r", P_REG, P_REG, i_shl },
#else
#define I_SHL_R_R 39
extern bool i_shl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shl", "shl_r_i", P_REG, P_IMM, i_shl },
#else
#define I_SHL_R_I 40
extern bool i_shl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shl", "shl_r_m", P_REG, P_MEM, i_shl },
#else
#define I_SHL_R_M 41
extern bool i_shl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shl", "shl_m_r", P_MEM, P_REG, i_shl },
#else
#define I_SHL_M_R 42
extern bool i_shl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shl", "shl_m_i", P_MEM, P_IMM, i_shl },
#else
#define I_SHL_M_I 43
extern bool i_shl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shl", "shl_m_m", P_MEM, P_MEM, i_shl },
#else
#define I_SHL_M_M 44
extern bool i_shl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shr", "shr_r_r", P_REG, P_REG, i_shr },
#else
#define I_SHR_R_R 45
extern bool i_shr(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shr", "shr_r_i", P_REG, P_IMM, i_shr },
#else
#define I_SHR_R_I 46
extern bool i_shr(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shr", "shr_r_m", P_REG, P_MEM, i_shr },
#else
#define I_SHR_R_M 47
extern bool i_shr(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shr", "shr_m_r", P_MEM, P_REG, i_shr },
#else
#define I_SHR_M_R 48
extern bool i_shr(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shr", "shr_m_i", P_MEM, P_IMM, i_shr },
#else
#define I_SHR_M_I 49
extern bool i_shr(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shr", "shr_m_m", P_MEM, P_MEM, i_shr },
#else
#define I_SHR_M_M 50
extern bool i_shr(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shlf", "shlf_r_r", P_REG, P_REG, i_shlf },
#else
#define I_SHLF_R_R 51
extern bool i_shlf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shlf", "shlf_r_i", P_REG, P_IMM, i_shlf },
#else
#define I_SHLF_R_I 52
extern bool i_shlf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shlf", "shlf_r_m", P_REG, P_MEM, i_shlf },
#else
#define I_SHLF_R_M 53
extern bool i_shlf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shlf", "shlf_m_r", P_MEM, P_REG, i_shlf },
#else
#define I_SHLF_M_R 54
extern bool i_shlf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shlf", "shlf_m_i", P_MEM, P_IMM, i_shlf },
#else
#define I_SHLF_M_I 55
extern bool i_shlf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shlf", "shlf_m_m", P_MEM, P_MEM, i_shlf },
#else
#define I_SHLF_M_M 56
extern bool i_shlf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shrf", "shrf_r_r", P_REG, P_REG, i_shrf },
#else
#define I_SHRF_R_R 57
extern bool i_shrf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shrf", "shrf_r_i", P_REG, P_IMM, i_shrf },
#else
#define I_SHRF_R_I 58
extern bool i_shrf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shrf", "shrf_r_m", P_REG, P_MEM, i_shrf },
#else
#define I_SHRF_R_M 59
extern bool i_shrf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shrf", "shrf_m_r", P_MEM, P_REG, i_shrf },
#else
#define I_SHRF_M_R 60
extern bool i_shrf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shrf", "shrf_m_i", P_MEM, P_IMM, i_shrf },
#else
#define I_SHRF_M_I 61
extern bool i_shrf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "shrf", "shrf_m_m", P_MEM, P_MEM, i_shrf },
#else
#define I_SHRF_M_M 62
extern bool i_shrf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgn", "sgn_r_r", P_REG, P_REG, i_sgn },
#else
#define I_SGN_R_R 63
extern bool i_sgn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgn", "sgn_r_i", P_REG, P_IMM, i_sgn },
#else
#define I_SGN_R_I 64
extern bool i_sgn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgn", "sgn_r_m", P_REG, P_MEM, i_sgn },
#else
#define I_SGN_R_M 65
extern bool i_sgn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgn", "sgn_m_r", P_MEM, P_REG, i_sgn },
#else
#define I_SGN_M_R 66
extern bool i_sgn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgn", "sgn_m_i", P_MEM, P_IMM, i_sgn },
#else
#define I_SGN_M_I 67
extern bool i_sgn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgn", "sgn_m_m", P_MEM, P_MEM, i_sgn },
#else
#define I_SGN_M_M 68
extern bool i_sgn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgnf", "sgnf_r_r", P_REG, P_REG, i_sgnf },
#else
#define I_SGNF_R_R 69
extern bool i_sgnf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgnf", "sgnf_r_i", P_REG, P_IMM, i_sgnf },
#else
#define I_SGNF_R_I 70
extern bool i_sgnf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgnf", "sgnf_r_m", P_REG, P_MEM, i_sgnf },
#else
#define I_SGNF_R_M 71
extern bool i_sgnf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgnf", "sgnf_m_r", P_MEM, P_REG, i_sgnf },
#else
#define I_SGNF_M_R 72
extern bool i_sgnf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgnf", "sgnf_m_i", P_MEM, P_IMM, i_sgnf },
#else
#define I_SGNF_M_I 73
extern bool i_sgnf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sgnf", "sgnf_m_m", P_MEM, P_MEM, i_sgnf },
#else
#define I_SGNF_M_M 74
extern bool i_sgnf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "neg", "neg_r", P_REG, NOPRM, i_neg },
#else
#define I_NEG_R 75
extern bool i_neg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "neg", "neg_m", P_MEM, NOPRM, i_neg },
#else
#define I_NEG_M 76
extern bool i_neg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "negf", "negf_r", P_REG, NOPRM, i_negf },
#else
#define I_NEGF_R 77
extern bool i_negf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "negf", "negf_m", P_MEM, NOPRM, i_negf },
#else
#define I_NEGF_M 78
extern bool i_negf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "inc", "inc_r", P_REG, NOPRM, i_inc },
#else
#define I_INC_R 79
extern bool i_inc(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "inc", "inc_m", P_MEM, NOPRM, i_inc },
#else
#define I_INC_M 80
extern bool i_inc(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "incf", "incf_r", P_REG, NOPRM, i_incf },
#else
#define I_INCF_R 81
extern bool i_incf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "incf", "incf_m", P_MEM, NOPRM, i_incf },
#else
#define I_INCF_M 82
extern bool i_incf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "dec", "dec_r", P_REG, NOPRM, i_dec },
#else
#define I_DEC_R 83
extern bool i_dec(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "dec", "dec_m", P_MEM, NOPRM, i_dec },
#else
#define I_DEC_M 84
extern bool i_dec(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "decf", "decf_r", P_REG, NOPRM, i_decf },
#else
#define I_DECF_R 85
extern bool i_decf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "decf", "decf_m", P_MEM, NOPRM, i_decf },
#else
#define I_DECF_M 86
extern bool i_decf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "add", "add_r_r", P_REG, P_REG, i_add },
#else
#define I_ADD_R_R 87
extern bool i_add(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "add", "add_r_i", P_REG, P_IMM, i_add },
#else
#define I_ADD_R_I 88
extern bool i_add(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "add", "add_r_m", P_REG, P_MEM, i_add },
#else
#define I_ADD_R_M 89
extern bool i_add(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "add", "add_m_r", P_MEM, P_REG, i_add },
#else
#define I_ADD_M_R 90
extern bool i_add(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "add", "add_m_i", P_MEM, P_IMM, i_add },
#else
#define I_ADD_M_I 91
extern bool i_add(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "add", "add_m_m", P_MEM, P_MEM, i_add },
#else
#define I_ADD_M_M 92
extern bool i_add(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "addf", "addf_r_r", P_REG, P_REG, i_addf },
#else
#define I_ADDF_R_R 93
extern bool i_addf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "addf", "addf_r_i", P_REG, P_IMM, i_addf },
#else
#define I_ADDF_R_I 94
extern bool i_addf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "addf", "addf_r_m", P_REG, P_MEM, i_addf },
#else
#define I_ADDF_R_M 95
extern bool i_addf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "addf", "addf_m_r", P_MEM, P_REG, i_addf },
#else
#define I_ADDF_M_R 96
extern bool i_addf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "addf", "addf_m_i", P_MEM, P_IMM, i_addf },
#else
#define I_ADDF_M_I 97
extern bool i_addf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "addf", "addf_m_m", P_MEM, P_MEM, i_addf },
#else
#define I_ADDF_M_M 98
extern bool i_addf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sub", "sub_r_r", P_REG, P_REG, i_sub },
#else
#define I_SUB_R_R 99
extern bool i_sub(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sub", "sub_r_i", P_REG, P_IMM, i_sub },
#else
#define I_SUB_R_I 100
extern bool i_sub(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sub", "sub_r_m", P_REG, P_MEM, i_sub },
#else
#define I_SUB_R_M 101
extern bool i_sub(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sub", "sub_m_r", P_MEM, P_REG, i_sub },
#else
#define I_SUB_M_R 102
extern bool i_sub(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sub", "sub_m_i", P_MEM, P_IMM, i_sub },
#else
#define I_SUB_M_I 103
extern bool i_sub(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sub", "sub_m_m", P_MEM, P_MEM, i_sub },
#else
#define I_SUB_M_M 104
extern bool i_sub(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "subf", "subf_r_r", P_REG, P_REG, i_subf },
#else
#define I_SUBF_R_R 105
extern bool i_subf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "subf", "subf_r_i", P_REG, P_IMM, i_subf },
#else
#define I_SUBF_R_I 106
extern bool i_subf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "subf", "subf_r_m", P_REG, P_MEM, i_subf },
#else
#define I_SUBF_R_M 107
extern bool i_subf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "subf", "subf_m_r", P_MEM, P_REG, i_subf },
#else
#define I_SUBF_M_R 108
extern bool i_subf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "subf", "subf_m_i", P_MEM, P_IMM, i_subf },
#else
#define I_SUBF_M_I 109
extern bool i_subf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "subf", "subf_m_m", P_MEM, P_MEM, i_subf },
#else
#define I_SUBF_M_M 110
extern bool i_subf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul", "mul_r_r", P_REG, P_REG, i_mul },
#else
#define I_MUL_R_R 111
extern bool i_mul(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul", "mul_r_i", P_REG, P_IMM, i_mul },
#else
#define I_MUL_R_I 112
extern bool i_mul(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul", "mul_r_m", P_REG, P_MEM, i_mul },
#else
#define I_MUL_R_M 113
extern bool i_mul(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul", "mul_m_r", P_MEM, P_REG, i_mul },
#else
#define I_MUL_M_R 114
extern bool i_mul(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul", "mul_m_i", P_MEM, P_IMM, i_mul },
#else
#define I_MUL_M_I 115
extern bool i_mul(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul", "mul_m_m", P_MEM, P_MEM, i_mul },
#else
#define I_MUL_M_M 116
extern bool i_mul(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mulf", "mulf_r_r", P_REG, P_REG, i_mulf },
#else
#define I_MULF_R_R 117
extern bool i_mulf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mulf", "mulf_r_i", P_REG, P_IMM, i_mulf },
#else
#define I_MULF_R_I 118
extern bool i_mulf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mulf", "mulf_r_m", P_REG, P_MEM, i_mulf },
#else
#define I_MULF_R_M 119
extern bool i_mulf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mulf", "mulf_m_r", P_MEM, P_REG, i_mulf },
#else
#define I_MULF_M_R 120
extern bool i_mulf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mulf", "mulf_m_i", P_MEM, P_IMM, i_mulf },
#else
#define I_MULF_M_I 121
extern bool i_mulf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mulf", "mulf_m_m", P_MEM, P_MEM, i_mulf },
#else
#define I_MULF_M_M 122
extern bool i_mulf(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div", "div_r_r", P_REG, P_REG, i_div },
#else
#define I_DIV_R_R 123
extern bool i_div(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div", "div_r_i", P_REG, P_IMM, i_div },
#else
#define I_DIV_R_I 124
extern bool i_div(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div", "div_r_m", P_REG, P_MEM, i_div },
#else
#define I_DIV_R_M 125
extern bool i_div(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div", "div_m_r", P_MEM, P_REG, i_div },
#else
#define I_DIV_M_R 126
extern bool i_div(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div", "div_m_i", P_MEM, P_IMM, i_div },
#else
#define I_DIV_M_I 127
extern bool i_div(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div", "div_m_m", P_MEM, P_MEM, i_div },
#else
#define I_DIV_M_M 128
extern bool i_div(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mod", "mod_r_r", P_REG, P_REG, i_mod },
#else
#define I_MOD_R_R 129
extern bool i_mod(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mod", "mod_r_i", P_REG, P_IMM, i_mod },
#else
#define I_MOD_R_I 130
extern bool i_mod(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mod", "mod_r_m", P_REG, P_MEM, i_mod },
#else
#define I_MOD_R_M 131
extern bool i_mod(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mod", "mod_m_r", P_MEM, P_REG, i_mod },
#else
#define I_MOD_M_R 132
extern bool i_mod(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mod", "mod_m_i", P_MEM, P_IMM, i_mod },
#else
#define I_MOD_M_I 133
extern bool i_mod(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mod", "mod_m_m", P_MEM, P_MEM, i_mod },
#else
#define I_MOD_M_M 134
extern bool i_mod(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul2", "mul2_r", P_REG, NOPRM, i_mul2 },
#else
#define I_MUL2_R 135
extern bool i_mul2(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul2", "mul2_i", P_IMM, NOPRM, i_mul2 },
#else
#define I_MUL2_I 136
extern bool i_mul2(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul2", "mul2_m", P_MEM, NOPRM, i_mul2 },
#else
#define I_MUL2_M 137
extern bool i_mul2(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul2f", "mul2f_r", P_REG, NOPRM, i_mul2f },
#else
#define I_MUL2F_R 138
extern bool i_mul2f(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul2f", "mul2f_i", P_IMM, NOPRM, i_mul2f },
#else
#define I_MUL2F_I 139
extern bool i_mul2f(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mul2f", "mul2f_m", P_MEM, NOPRM, i_mul2f },
#else
#define I_MUL2F_M 140
extern bool i_mul2f(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div2", "div2_r", P_REG, NOPRM, i_div2 },
#else
#define I_DIV2_R 141
extern bool i_div2(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div2", "div2_i", P_IMM, NOPRM, i_div2 },
#else
#define I_DIV2_I 142
extern bool i_div2(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "div2", "div2_m", P_MEM, NOPRM, i_div2 },
#else
#define I_DIV2_M 143
extern bool i_div2(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_r_r", P_REG, P_REG, i_test },
#else
#define I_TEST_R_R 144
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_r_i", P_REG, P_IMM, i_test },
#else
#define I_TEST_R_I 145
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_r_m", P_REG, P_MEM, i_test },
#else
#define I_TEST_R_M 146
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_i_r", P_IMM, P_REG, i_test },
#else
#define I_TEST_I_R 147
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_i_i", P_IMM, P_IMM, i_test },
#else
#define I_TEST_I_I 148
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_i_m", P_IMM, P_MEM, i_test },
#else
#define I_TEST_I_M 149
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_m_r", P_MEM, P_REG, i_test },
#else
#define I_TEST_M_R 150
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_m_i", P_MEM, P_IMM, i_test },
#else
#define I_TEST_M_I 151
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "test", "test_m_m", P_MEM, P_MEM, i_test },
#else
#define I_TEST_M_M 152
extern bool i_test(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_r_r", P_REG, P_REG, i_cmp },
#else
#define I_CMP_R_R 153
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_r_i", P_REG, P_IMM, i_cmp },
#else
#define I_CMP_R_I 154
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_r_m", P_REG, P_MEM, i_cmp },
#else
#define I_CMP_R_M 155
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_i_r", P_IMM, P_REG, i_cmp },
#else
#define I_CMP_I_R 156
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_i_i", P_IMM, P_IMM, i_cmp },
#else
#define I_CMP_I_I 157
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_i_m", P_IMM, P_MEM, i_cmp },
#else
#define I_CMP_I_M 158
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_m_r", P_MEM, P_REG, i_cmp },
#else
#define I_CMP_M_R 159
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_m_i", P_MEM, P_IMM, i_cmp },
#else
#define I_CMP_M_I 160
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmp", "cmp_m_m", P_MEM, P_MEM, i_cmp },
#else
#define I_CMP_M_M 161
extern bool i_cmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "j", "j_r", P_REG, NOPRM, i_j },
#else
#define I_J_R 162
extern bool i_j(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "j", "j_i", P_IMM, NOPRM, i_j },
#else
#define I_J_I 163
extern bool i_j(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "jmp", "jmp_r", P_REG, NOPRM, i_jmp },
#else
#define I_JMP_R 164
extern bool i_jmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "jmp", "jmp_i", P_IMM, NOPRM, i_jmp },
#else
#define I_JMP_I 165
extern bool i_jmp(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "loop", "loop_r", P_REG, NOPRM, i_loop },
#else
#define I_LOOP_R 166
extern bool i_loop(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "loop", "loop_i", P_IMM, NOPRM, i_loop },
#else
#define I_LOOP_I 167
extern bool i_loop(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "lea", "lea_r_m", P_REG, P_MEM, i_lea },
#else
#define I_LEA_R_M 168
extern bool i_lea(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "lea", "lea_m_m", P_MEM, P_MEM, i_lea },
#else
#define I_LEA_M_M 169
extern bool i_lea(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mov", "mov_r_r", P_REG, P_REG, i_mov },
#else
#define I_MOV_R_R 170
extern bool i_mov(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mov", "mov_r_i", P_REG, P_IMM, i_mov },
#else
#define I_MOV_R_I 171
extern bool i_mov(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mov", "mov_r_m", P_REG, P_MEM, i_mov },
#else
#define I_MOV_R_M 172
extern bool i_mov(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mov", "mov_m_r", P_MEM, P_REG, i_mov },
#else
#define I_MOV_M_R 173
extern bool i_mov(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mov", "mov_m_i", P_MEM, P_IMM, i_mov },
#else
#define I_MOV_M_I 174
extern bool i_mov(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "mov", "mov_m_m", P_MEM, P_MEM, i_mov },
#else
#define I_MOV_M_M 175
extern bool i_mov(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "movzx", "movzx_r_m", P_REG, P_MEM, i_movzx },
#else
#define I_MOVZX_R_M 176
extern bool i_movzx(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "movzx", "movzx_m_m", P_MEM, P_MEM, i_movzx },
#else
#define I_MOVZX_M_M 177
extern bool i_movzx(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xchg", "xchg_r_r", P_REG, P_REG, i_xchg },
#else
#define I_XCHG_R_R 178
extern bool i_xchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xchg", "xchg_r_i", P_REG, P_IMM, i_xchg },
#else
#define I_XCHG_R_I 179
extern bool i_xchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xchg", "xchg_r_m", P_REG, P_MEM, i_xchg },
#else
#define I_XCHG_R_M 180
extern bool i_xchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xchg", "xchg_m_r", P_MEM, P_REG, i_xchg },
#else
#define I_XCHG_M_R 181
extern bool i_xchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xchg", "xchg_m_i", P_MEM, P_IMM, i_xchg },
#else
#define I_XCHG_M_I 182
extern bool i_xchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "xchg", "xchg_m_m", P_MEM, P_MEM, i_xchg },
#else
#define I_XCHG_M_M 183
extern bool i_xchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpxchg", "cmpxchg_r_r", P_REG, P_REG, i_cmpxchg },
#else
#define I_CMPXCHG_R_R 184
extern bool i_cmpxchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpxchg", "cmpxchg_r_i", P_REG, P_IMM, i_cmpxchg },
#else
#define I_CMPXCHG_R_I 185
extern bool i_cmpxchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpxchg", "cmpxchg_r_m", P_REG, P_MEM, i_cmpxchg },
#else
#define I_CMPXCHG_R_M 186
extern bool i_cmpxchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpxchg", "cmpxchg_m_r", P_MEM, P_REG, i_cmpxchg },
#else
#define I_CMPXCHG_M_R 187
extern bool i_cmpxchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpxchg", "cmpxchg_m_i", P_MEM, P_IMM, i_cmpxchg },
#else
#define I_CMPXCHG_M_I 188
extern bool i_cmpxchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpxchg", "cmpxchg_m_m", P_MEM, P_MEM, i_cmpxchg },
#else
#define I_CMPXCHG_M_M 189
extern bool i_cmpxchg(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "call", "call_r", P_REG, NOPRM, i_call },
#else
#define I_CALL_R 190
extern bool i_call(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "call", "call_i", P_IMM, NOPRM, i_call },
#else
#define I_CALL_I 191
extern bool i_call(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "call", "call_m", P_MEM, NOPRM, i_call },
#else
#define I_CALL_M 192
extern bool i_call(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "ret", "ret", NOPRM, NOPRM, i_ret },
#else
#define I_RET 193
extern bool i_ret(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "enter", "enter", NOPRM, NOPRM, i_enter },
#else
#define I_ENTER 194
extern bool i_enter(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "enter", "enter_i", P_IMM, NOPRM, i_enter },
#else
#define I_ENTER_I 195
extern bool i_enter(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "leave", "leave", NOPRM, NOPRM, i_leave },
#else
#define I_LEAVE 196
extern bool i_leave(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "stosb", "stosb", NOPRM, NOPRM, i_stosb },
#else
#define I_STOSB 197
extern bool i_stosb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "stosb", "stosb_r", P_REG, NOPRM, i_stosb },
#else
#define I_STOSB_R 198
extern bool i_stosb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "stosb", "stosb_i", P_IMM, NOPRM, i_stosb },
#else
#define I_STOSB_I 199
extern bool i_stosb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "stosb", "stosb_m", P_MEM, NOPRM, i_stosb },
#else
#define I_STOSB_M 200
extern bool i_stosb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "stosb", "stosb_r_r", P_REG, P_REG, i_stosb },
#else
#define I_STOSB_R_R 201
extern bool i_stosb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "stosb", "stosb_r_i", P_REG, P_IMM, i_stosb },
#else
#define I_STOSB_R_I 202
extern bool i_stosb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "stosb", "stosb_r_m", P_REG, P_MEM, i_stosb },
#else
#define I_STOSB_R_M 203
extern bool i_stosb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "lodsb", "lodsb", NOPRM, NOPRM, i_lodsb },
#else
#define I_LODSB 204
extern bool i_lodsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "lodsb", "lodsb_r", P_REG, NOPRM, i_lodsb },
#else
#define I_LODSB_R 205
extern bool i_lodsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "lodsb", "lodsb_r_r", P_REG, P_REG, i_lodsb },
#else
#define I_LODSB_R_R 206
extern bool i_lodsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "scasb", "scasb", NOPRM, NOPRM, i_scasb },
#else
#define I_SCASB 207
extern bool i_scasb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "scasb", "scasb_r", P_REG, NOPRM, i_scasb },
#else
#define I_SCASB_R 208
extern bool i_scasb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "scasb", "scasb_i", P_IMM, NOPRM, i_scasb },
#else
#define I_SCASB_I 209
extern bool i_scasb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "scasb", "scasb_m", P_MEM, NOPRM, i_scasb },
#else
#define I_SCASB_M 210
extern bool i_scasb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "scasb", "scasb_r_r", P_REG, P_REG, i_scasb },
#else
#define I_SCASB_R_R 211
extern bool i_scasb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "scasb", "scasb_r_i", P_REG, P_IMM, i_scasb },
#else
#define I_SCASB_R_I 212
extern bool i_scasb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "scasb", "scasb_r_m", P_REG, P_MEM, i_scasb },
#else
#define I_SCASB_R_M 213
extern bool i_scasb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpsb", "cmpsb", NOPRM, NOPRM, i_cmpsb },
#else
#define I_CMPSB 214
extern bool i_cmpsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpsb", "cmpsb_r", P_REG, NOPRM, i_cmpsb },
#else
#define I_CMPSB_R 215
extern bool i_cmpsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpsb", "cmpsb_r_r", P_REG, P_REG, i_cmpsb },
#else
#define I_CMPSB_R_R 216
extern bool i_cmpsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpzsb", "cmpzsb", NOPRM, NOPRM, i_cmpzsb },
#else
#define I_CMPZSB 217
extern bool i_cmpzsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpzsb", "cmpzsb_r", P_REG, NOPRM, i_cmpzsb },
#else
#define I_CMPZSB_R 218
extern bool i_cmpzsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmpzsb", "cmpzsb_r_r", P_REG, P_REG, i_cmpzsb },
#else
#define I_CMPZSB_R_R 219
extern bool i_cmpzsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "movsb", "movsb", NOPRM, NOPRM, i_movsb },
#else
#define I_MOVSB 220
extern bool i_movsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "movsb", "movsb_r", P_REG, NOPRM, i_movsb },
#else
#define I_MOVSB_R 221
extern bool i_movsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "movsb", "movsb_r_r", P_REG, P_REG, i_movsb },
#else
#define I_MOVSB_R_R 222
extern bool i_movsb(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_r_r", P_REG, P_REG, i_devctl },
#else
#define I_DEVCTL_R_R 223
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_r_i", P_REG, P_IMM, i_devctl },
#else
#define I_DEVCTL_R_I 224
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_r_m", P_REG, P_MEM, i_devctl },
#else
#define I_DEVCTL_R_M 225
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_i_r", P_IMM, P_REG, i_devctl },
#else
#define I_DEVCTL_I_R 226
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_i_i", P_IMM, P_IMM, i_devctl },
#else
#define I_DEVCTL_I_I 227
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_i_m", P_IMM, P_MEM, i_devctl },
#else
#define I_DEVCTL_I_M 228
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_m_r", P_MEM, P_REG, i_devctl },
#else
#define I_DEVCTL_M_R 229
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_m_i", P_MEM, P_IMM, i_devctl },
#else
#define I_DEVCTL_M_I 230
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "devctl", "devctl_m_m", P_MEM, P_MEM, i_devctl },
#else
#define I_DEVCTL_M_M 231
extern bool i_devctl(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_r_r", P_REG, P_REG, i_iocall },
#else
#define I_IOCALL_R_R 232
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_r_i", P_REG, P_IMM, i_iocall },
#else
#define I_IOCALL_R_I 233
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_r_m", P_REG, P_MEM, i_iocall },
#else
#define I_IOCALL_R_M 234
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_i_r", P_IMM, P_REG, i_iocall },
#else
#define I_IOCALL_I_R 235
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_i_i", P_IMM, P_IMM, i_iocall },
#else
#define I_IOCALL_I_I 236
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_i_m", P_IMM, P_MEM, i_iocall },
#else
#define I_IOCALL_I_M 237
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_m_r", P_MEM, P_REG, i_iocall },
#else
#define I_IOCALL_M_R 238
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_m_i", P_MEM, P_IMM, i_iocall },
#else
#define I_IOCALL_M_I 239
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "iocall", "iocall_m_m", P_MEM, P_MEM, i_iocall },
#else
#define I_IOCALL_M_M 240
extern bool i_iocall(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cli", "cli", NOPRM, NOPRM, i_cli },
#else
#define I_CLI 241
extern bool i_cli(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "sti", "sti", NOPRM, NOPRM, i_sti },
#else
#define I_STI 242
extern bool i_sti(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cld", "cld", NOPRM, NOPRM, i_cld },
#else
#define I_CLD 243
extern bool i_cld(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "std", "std", NOPRM, NOPRM, i_std },
#else
#define I_STD 244
extern bool i_std(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cmc", "cmc", NOPRM, NOPRM, i_cmc },
#else
#define I_CMC 245
extern bool i_cmc(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "clc", "clc", NOPRM, NOPRM, i_clc },
#else
#define I_CLC 246
extern bool i_clc(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "stc", "stc", NOPRM, NOPRM, i_stc },
#else
#define I_STC 247
extern bool i_stc(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "nop", "nop", NOPRM, NOPRM, i_nop },
#else
#define I_NOP 248
extern bool i_nop(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "gco", "gco_r", P_REG, NOPRM, i_gco },
#else
#define I_GCO_R 249
extern bool i_gco(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "gco", "gco_m", P_MEM, NOPRM, i_gco },
#else
#define I_GCO_M 250
extern bool i_gco(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "gcd", "gcd_r", P_REG, NOPRM, i_gcd },
#else
#define I_GCD_R 251
extern bool i_gcd(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "gcd", "gcd_m", P_MEM, NOPRM, i_gcd },
#else
#define I_GCD_M 252
extern bool i_gcd(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "prn", "prn_r", P_REG, NOPRM, i_prn },
#else
#define I_PRN_R 253
extern bool i_prn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "prn", "prn_i", P_IMM, NOPRM, i_prn },
#else
#define I_PRN_I 254
extern bool i_prn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "prn", "prn_m", P_MEM, NOPRM, i_prn },
#else
#define I_PRN_M 255
extern bool i_prn(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "break", "break", NOPRM, NOPRM, i_break },
#else
#define I_BREAK 256
extern bool i_break(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "step", "step_r", P_REG, NOPRM, i_step },
#else
#define I_STEP_R 257
extern bool i_step(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "step", "step_i", P_IMM, NOPRM, i_step },
#else
#define I_STEP_I 258
extern bool i_step(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "step", "step_m", P_MEM, NOPRM, i_step },
#else
#define I_STEP_M 259
extern bool i_step(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "clr", "clr", NOPRM, NOPRM, i_clr },
#else
#define I_CLR 260
extern bool i_clr(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
{ "cla", "cla", NOPRM, NOPRM, i_cla },
#else
#define I_CLA 261
extern bool i_cla(ctx_t *, acc_t *, acc_t *, ulong *, ulong *);
#endif
#ifdef _NEED_ARCH_I
};
#else
#define NINSTRS 262
#endif
// 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 PARITY(v) __builtin_parity(v)
#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 = (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)
#define COMPARE(v1, v2) \
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);
// 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 <pc/arch.h>
#include <in/flags.h>
#include <in/arch_i.h>
//----------------------------------------------------------------------------//
#define DECV(v, p) \
ulong v; \
GETV(v, p)
#define GETV(v, p) \
assert(p); \
if (ACC_FMT_IS_MEM(p->type)) \
v = readmem(ctx, p->addr, p->mlen); \
else v = p->val
#define DECVZX(v, p) \
ulong v; \
GETVZX(v, p)
#define GETVZX(v, p) \
assert(p); \
if (ACC_FMT_IS_MEM(p->type)) \
v = readmemzx(ctx, p->addr, p->mlen); \
else v = p->val
//----------------------------------------------------------------------------//
#define IMPL_START_0(name) \
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \
{
#define IMPL_START_1(name) \
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \
{ \
DECV(v1, p1);
#define IMPL_START_2(name) \
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \
{ \
DECV(v1, p1); \
DECV(v2, p2);
#define IMPL_OUT_ZSF \
SET_ZSF(v1); \
IMPL_OUT
#define IMPL_OUT \
*r1 = v1; \
return 1; \
}
#define IMPL_OUT_2 \
*r1 = v1; \
*r2 = v2; \
return 2; \
}
#define IMPL_END \
return 0; \
}
//----------------------------------------------------------------------------//
#define CHK_SUPERV() \
do { \
if ((cr0 & UF) > 0) { \
_except(ctx, E_SYS, "Supervisor-only INSTR"); \
} \
} while (0)
#define CHK_STACK(op) \
if (rsp % 8 > 0 || rbp % 8 > 0) { \
_except(ctx, E_STA, "Misaligned stack REGS"); \
} \
if (rbp op rsp) { \
_except(ctx, E_STU, "Stack underflow"); \
}
//----------------------------------------------------------------------------//
#define PUSH(v) \
rsp -= 8; \
writemem(ctx, v, rsp, 8);
#define POP(v) \
v = readmem(ctx, rsp, 8); \
rsp += 8;
#define JUMP(v) \
rip = v + cr1
//----------------------------------------------------------------------------//
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; Main function
;
main:
jmp ramdev_test
ramdev_test:
call DevGetMemOff
mov rdx, rax
call DevGetMemSize
ret
stosb_test:
cld
mov rcx, 11
mov rax, 33
mov rdi, .buf
mov rsi, .buf
rep stosb
mov rbx, rdi
sub rbx, rsi
mov ax0, .buf
mov ax1, 12
call print_n
ret
.str1 = "Hello World!\n"
.buf = [32]
movzx_test:
enter 1
mov q[rsp], 0xFABC1234CCCCDDDD
mov rax, b[rsp]
mov rbx, w[rsp]
mov rcx, l[rsp]
mov rdx, q[rsp]
movzx rsx, b[rsp]
movzx rbi, w[rsp]
movzx rdi, l[rsp]
movzx rsi, q[rsp]
leave
ret
itoa_test:
mov ax0, .buf
mov ax1, LONG_MIN
mov ax2, 10
call itoa
mov ax0, rax
call print
prn 10
mov ax0, .buf
mov ax1, 0xfff85ffffffffff4
mov ax2, 16
call itoa
mov ax0, rax
call print
ret
.buf = [32]
devtest:
mov ax0, .buf
devctl 0, 1
mov ax0, .buf
call print
iocall 0, 0
ret
.buf = [32]
str_test:
mov ax0, .msg
call print
mov ax0, .buf1
mov ax1, .msg
call strcpy
prn 10
mov ax0, .buf1
call print
mov ax0, .buf2
mov ax1, .msg
mov ax2, 8
call strnzcpy
prn 10
mov ax0, .buf2
mov ax1, 12
call print_n
mov ax0, .msg
mov ax1, .buf1
call strcmp
mov rbx, rax
mov ax0, .buf2
mov ax1, .msg
call strcmp
mov rsx, rax
mov ax0, .msg
call strlen
ret
.msg = "Hello World :)"
.buf1 = [32]
.buf2 = "!!!!!!!!!!!!!"
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
MEMDEV := 1
MEMDEV_GETMEMOFF := 0
MEMDEV_GETMEMSIZE := 1
DevGetMemOff:
iocall MEMDEV, MEMDEV_GETMEMOFF
ret
DevGetMemSize:
iocall MEMDEV, MEMDEV_GETMEMSIZE
ret
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; char *_itoa(char *buf, int num, int base, int unsi)
;
; Acts as itoa if unsi == 0, as utoa otherwise
;
_itoa:
mov rax, ax0
xor rdx, rdx
; make sure base is in [2, 32]
cmp ax2, 2
jmp.b .bad
cmp ax2, 36
jmp.a .bad
; deal with zero
test ax1, ax1
jmp.z .zero
; deal with base 10 signedness
test ax3, ax3 ; unsigned mode
jmp.nz .conv
cmp ax2, 10 ; base 10
jmp.nz .conv
sgn rdx, ax1 ; extract ax1 sign
cmp rdx, -1 ; negative?
neg.z ax1
; main loop
.conv:
test ax1, ax1
jmp.z .fini
mov rsx, ax1
mod rsx, ax2 ; ax1 % base
cmp rsx, 9 ; rsx > 9 ?
jmp.a .nondec
add rsx, 48 ; '0'
jmp .next
.nondec:
add rsx, 87 ; 'a' - 10
.next:
mov b[ax0], rsx
inc ax0
div ax1, ax2
jmp .conv
; add minus flag, null-terminate and reverse
.fini:
cmp rdx, -1
mov.z b[ax0], 45 ; '-'
inc.z ax0
mov b[ax0], 0
mov ax0, rax
call strrev2
ret
;
; exceptional cases
;
.bad:
mov q[errno], EINVAL
mov b[rax], 0
ret
.zero:
mov b[ax0], 48 ; '0'
mov b[ax0+1], 0
ret
;
; wrappers
;
itoa:
mov ax3, 0
jmp _itoa
utoa:
mov ax3, 1
jmp _itoa
; 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 "crt/fmt/itoa.k"
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
EOK := 0
EINVAL := 1
errno = 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.
;
; char *strchrnul(const char *str, int ch)
;
strchrnul:
ret
;
; char *strchr(const char *str, int ch)
;
strchr:
call strchrnul
test b[rax], b[rax]
mov.z rax, 0
ret
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; void strcpy(char *, const char *)
;
strcpy:
mov ax2, STRLEN_MAX
jmp strncpy
;
; void strncpy(char *, const char *, int)
;
strncpy:
mov rcx, ax2
ret.cxz
cld
rep.nz movsb ax0, ax1
ret
;
; void strnzcpy(char *, const char *, int)
;
strnzcpy:
mov rcx, ax2
ret.cxz
dec rcx
jmp.cxz .1
cld
rep.nz movsb ax0, ax1
.1:
mov b[ax0], 0
ret
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; int strnlen(char *, int)
;
strnlen:
cld
mov rcx, ax1
rep.nz scasb ax0, 0
mov rax, ax1
sub rax, rcx
ret
;
; int strlen(char *)
;
strlen:
mov ax1, STRLEN_MAX
jmp strnlen
; 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 "crt/str/strlen.k"
include "crt/str/strrev.k"
include "crt/str/strcpy.k"
include "crt/str/strcmp.k"
include "crt/str/strchr.k"
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; int strcmp(const char *str1, const char *str2)
;
; Returns:
; 0 if the contents of both strings are equal
; 1 if the first character that does not match has a greater value in str1 than in str2
; -1 if the first character that does not match has a lower value in str1 than in str2
;
strcmp:
mov ax2, STRLEN_MAX
jmp strncmp
;
; int strncmp(const char *str1, const char *str2, int maxn)
;
strncmp:
mov rcx, ax2
mov.cxz rax, 0
ret.cxz
cld
rep.e cmpzsb ax0, ax1
mov rax, b[ax0]
sub rax, b[ax1]
sgn rax, rax
ret
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; void strrev(char *buf, const char *str)
;
; buf and src must NOT overlap
;
strrev:
test b[ax1], b[ax1]
mov.z b[ax0], 0
ret.z
; save str's location
mov rdx, ax1
; go to str's end, just before
; the null terminator
.1:
test b[ax1+1], b[ax1+1]
inc.nz ax1
jmp.nz .1
.2:
; copy, going backward though str
; and forward through buf
mov b[ax0], b[ax1]
cmp ax1, rdx
mov.z b[ax0+1], 0
ret.z
inc ax0
dec ax1
jmp .2
;
; void strrev2(char *str)
;
; Inverses str
;
strrev2:
test b[ax0], b[ax0]
ret.z
mov ax1, ax0
; go to str's end, just before
; the null terminator
.1:
test b[ax1+1], b[ax1+1]
inc.nz ax1
jmp.nz .1
; increase ax0 while decreasing ax1, performing exchanges
.2:
cmp ax0, ax1
jmp.ae .3
xchg b[ax0], b[ax1]
inc ax0
dec ax1
jmp .2
.3:
ret
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; Max amount of characters that print() will print
;
v_print_max := 0xFF
;
; Print a string
;
print:
mov rcx, v_print_max
.1:
test b[ax0], b[ax0]
jmp.z .2
prn b[ax0]
inc ax0
loop .1
.2:
ret
;
; Print exactly ax1 characters
;
print_n:
mov rcx, ax1
.1:
prn b[ax0]
inc ax0
loop .1
ret
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; Entry point
;
_start:
mov rbp, 0x200000
mov rsp, rbp
call main
.1:
stop
jmp .1
;
; Some definitions
;
CHAR_MIN := 0x80
SHRT_MIN := 0x8000
INT_MIN := 0x80000000
LONG_MIN := 0x8000000000000000
XCHAR_MIN := 0xFFFFFFFFFFFFFF80
XSHRT_MIN := 0xFFFFFFFFFFFF8000
XINT_MIN := 0xFFFFFFFF80000000
CHAR_MAX := 0x7F
SHRT_MAX := 0x7FFF
INT_MAX := 0x7FFFFFFF
LONG_MAX := 0x7FFFFFFFFFFFFFFF
BYTE_MAX := 0xFF
WORD_MAX := 0xFFFF
LWORD_MAX := 0xFFFFFFFF
QWORD_MAX := 0xFFFFFFFFFFFFFFFF
STRLEN_MAX := 0xFFFFFFFF
;
; Include librairies
;
include "crt/err/errno.k"
include "crt/fmt/format.k"
include "crt/prn/print.k"
include "crt/str/string.k"
;
; Include drivers
;
include "sys/memdev.k"
;
; Disk Operating System
;
include "main.k"