kvisc/karch/decd.c

95 lines
1.9 KiB
C

// 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);
}