mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
5210 lines
105 KiB
Plaintext
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"
|
|
|