diff --git a/.sum b/.sum new file mode 100644 index 0000000..4d0df9f --- /dev/null +++ b/.sum @@ -0,0 +1,5209 @@ +// 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 + +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 + +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 +#include + +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 + +//----------------------------------------------------------------------------// + +#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 + +// +// 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 + +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 + +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 + +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 + +//----------------------------------------------------------------------------// + +// +// 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 +#include +#include +#include + +#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 +#include + +// +// 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 + +#define _NEED_ARCH_I +#include + +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 + +// +// 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 + +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 + +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 + +// +// 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 + +//-------------------------------------------------------------------------- + +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 + +// +// 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 + +//----------------------------------------------------------------------------// + +#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 + +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 + +#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 +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include + +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 + +#include +#include + +//----------------------------------------------------------------------------// + +#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" + diff --git a/Makefile b/Makefile index 5cfcb1d..2105f2b 100644 --- a/Makefile +++ b/Makefile @@ -29,3 +29,6 @@ test: kas vm/a.out @echo "<<<<<<<<" @echo +wc: + @cat $(shell find -name *.[kch]) $(shell find -name *.py) | wc -l + diff --git a/ka/dos.k b/ka/dos.k index ff5b3bd..e912faa 100644 --- a/ka/dos.k +++ b/ka/dos.k @@ -15,29 +15,10 @@ _start: jmp .1 ; -; Some definitions +; Preprocessor misc. ; - -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 "inc/limits.k" +include "inc/regs.k" ; ; Include librairies diff --git a/ka/inc/limits.k b/ka/inc/limits.k new file mode 100644 index 0000000..36ebe78 --- /dev/null +++ b/ka/inc/limits.k @@ -0,0 +1,23 @@ +; 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_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 diff --git a/ka/inc/regs.k b/ka/inc/regs.k new file mode 100644 index 0000000..4967b1d --- /dev/null +++ b/ka/inc/regs.k @@ -0,0 +1,66 @@ +; The OS/K Team licenses this file to you under the MIT license. +; See the LICENSE file in the project root for more information. + +ID_INV := 0 +ID_RIP := 1 +ID_FLG := 2 +ID_RBP := 3 +ID_RSP := 4 +ID_RX0 := 5 +ID_RX1 := 6 +ID_RX2 := 7 + +ID_RAX := 8 +ID_RBX := 9 +ID_RCX := 10 +ID_RDX := 11 +ID_RSX := 12 +ID_RBI := 13 +ID_RDI := 14 +ID_RSI := 15 + +ID_NX0 := 16 +ID_NX1 := 17 +ID_NX2 := 18 +ID_NX3 := 19 +ID_NX4 := 20 +ID_NX5 := 21 +ID_NX6 := 22 +ID_NX7 := 23 + +ID_AX0 := 24 +ID_AX1 := 25 +ID_AX2 := 26 +ID_AX3 := 27 +ID_AX4 := 28 +ID_AX5 := 29 +ID_AX6 := 30 +ID_AX7 := 31 + +ID_LX0 := 32 +ID_LX1 := 33 +ID_LX2 := 34 +ID_LX3 := 35 +ID_LX4 := 36 +ID_LX5 := 37 +ID_LX6 := 38 +ID_LX7 := 39 + +ID_CR0 := 40 +ID_CR1 := 41 +ID_CR2 := 42 +ID_CR3 := 43 +ID_CR4 := 44 +ID_CR5 := 45 +ID_CR6 := 46 +ID_CR7 := 47 + +ID_SA0 := 48 +ID_SA1 := 49 +ID_SA2 := 50 +ID_SA3 := 51 +ID_SA4 := 52 +ID_SA5 := 53 +ID_SA6 := 54 +ID_SA7 := 55 + diff --git a/vm/dv/CPUDEV b/vm/dv/CPUDEV new file mode 100644 index 0000000..6bf8294 --- /dev/null +++ b/vm/dv/CPUDEV @@ -0,0 +1,29 @@ +# The OS/K Team licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. + +CPU device function slots: + + slot ax0 ax1 ax2 thr name desc + 0-15 - - - - (reserved) (reserved) + 16 - - - - getmaxidx rax = maximal index for a register frame + 17 - - - - getrfusage rax = number of register frames active + 18 - - - - getcuridx rax = index of the current register frame + 19 i - - - isactive rax = is register frame #ax0 active? + 20 i - - y activate activates register frame #ax0 + 21 i - - y deactivate deactivates register frame #ax0 (losing all its contents!) + 22 i i - y copyframe copy contents of frame #ax1 into (active) frame #ax0 + 23 i i - y moveframe move frame #ax1 to (inactive) frame index #ax0 + 24-31 - - - - (reserved) (reserved) + 32 i - - - loadargs load registers ax0-ax7 from frame #ax0 + 33 i r - - loadreg rax = register #ax1 from frame #ax0 + 34-47 - - - - (reserved) (reserved) + 48 i r i y storereg store ax2 into register #ax1 from frame #ax0 + 49-63 - - - - (reserved) (reserved) + 64 i i - y idtadd mark interrupt #ax0 as handled by register frame #ax1 + 65 i - - y idtdel mark interrupt #ax0 as unhandled + 66 i - - - idtquery rax = interrupt #ax0 handled? rdx = index of handling frame + +Arguments: + i immediate + r register index (0=inv, 1=rip, etc...) + diff --git a/vm/dv/cpudev.c b/vm/dv/cpudev.c index d35ec35..2a03a27 100644 --- a/vm/dv/cpudev.c +++ b/vm/dv/cpudev.c @@ -3,10 +3,16 @@ #include +#define MAX_RFRAME_IDX 255 + +// +// Register frales +// +reg_t **rfs = NULL; +size_t rfs_used = 0; + long cpudev_testfn(ctx_t *ctx, dev_t *dev) { - assert(dev == &cpudev); - rax = 4; rdx = 3; @@ -15,10 +21,22 @@ long cpudev_testfn(ctx_t *ctx, dev_t *dev) long cpudev_poweron(ctx_t *ctx, dev_t *dev) { - assert(dev == &cpudev); + rfs = malloc(sizeof(reg_t *) * (MAX_RFRAME_IDX + 1)); + + if (rfs == NULL) + return -1; - dev->fslots[0] = cpudev_testfn; dev->state = DEVGOOD; + + dev->fslots[0] = cpudev_testfn; + + return 0; +} + +long cpudev_poweroff(ctx_t *ctx, dev_t *dev) +{ + if (rfs) + free(rfs); return 0; } diff --git a/vm/pc/arch.h b/vm/pc/arch.h index 9f627fb..16a2b51 100644 --- a/vm/pc/arch.h +++ b/vm/pc/arch.h @@ -60,37 +60,16 @@ struct ctx_t #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 #include #include +#include #include extern reg_t arch_r[NREGS]; diff --git a/vm/pc/except.h b/vm/pc/except.h new file mode 100644 index 0000000..f03edc9 --- /dev/null +++ b/vm/pc/except.h @@ -0,0 +1,18 @@ +// 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 +{ + E_SHT, // Shutdown instruction + E_UDF, // Undefined behavior + 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 _except(ctx_t *, int, char *, ...) __attribute__((__noreturn__)); diff --git a/vm/pc/mem.h b/vm/pc/mem.h index c2af6b4..9cda0e1 100644 --- a/vm/pc/mem.h +++ b/vm/pc/mem.h @@ -1,6 +1,12 @@ // The OS/K Team licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +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')))); } + #define MEMOFF (1 * 1024 * 1024) #define MEMSIZE (16 * 1024 * 1024) // 16MB