// 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 "arch.h" void scan_param(ctx_t *ctx, acc_t *p) { ushort c; reg_t *r; assert(p != 0); c = ctx->get(ctx); if (c == A_MEM) { p->mem = 1; p->off = 0; c = ctx->get(ctx); } else if (c == A_OFF) { p->mem = 1; p->off = (short)ctx->get(ctx); c = ctx->get(ctx); } if (c >= A_IMM16) { assert(p->type == A_REG); p->type = c; c = ctx->get(ctx); } p->val = c; if (p->type == A_IMM32) { p->val = (p->val << 16) | ctx->get(ctx); } else if (p->type == A_IMM64) { p->val = (p->val << 16) | ctx->get(ctx); p->val = (p->val << 16) | ctx->get(ctx); p->val = (p->val << 16) | ctx->get(ctx); } else if (p->type == A_REG) { if (p->val > NREGS) { _except(ctx, E_ILL, "Inexistent REG"); } r = &ctx->r[p->val]; if (r->flags & (RES | CTL)) { _except(ctx, E_ACC, "Reserved REG"); } } } void decode(ctx_t *ctx) { instr_t *i; acc_t p1 = { 0 }, p2 = { 0 }; ulong rip = ctx->r[RIP].val; ushort c = ctx->get(ctx); if (c == 0xFFFF) { log("0x%016lX: stop\n", rip); _except(ctx, E_SHT, "Shutdown INSTR"); } else if (ISPREF(c)) { // nothing for now } else if (!ISINSTR(c)) { _except(ctx, E_ILL, "Bad opcode 0x%4hX", c); } // Scanning an instruction i = &ctx->i[c]; // Scan for parameters if (i->prm1 != NOPRM) { scan_param(ctx, &p1); if (i->prm2 != NOPRM) { scan_param(ctx, &p2); } } dumpinstr(ctx, rip, c, &p1, &p2); i->func(ctx, &p1, &p2); }