// 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 i_add(ctx_t *ctx, acc_t *p1, acc_t *p2) { if (p1->type != A_REG) { _except(ctx, E_ILL, "ADD into IMM"); } if (p1->mem || p2->mem) { _except(ctx, E_IMP, "Memory access"); } ctx->r[p1->val].val += p2->type >= A_IMM16 ? p2->val : ctx->r[p2->val].val; } void i_sub(ctx_t *ctx, acc_t *p1, acc_t *p2) { if (p1->type != A_REG) { _except(ctx, E_ILL, "SUB into IMM"); } if (p1->mem || p2->mem) { _except(ctx, E_IMP, "Memory access"); } ctx->r[p1->val].val -= p2->type >= A_IMM16 ? p2->val : ctx->r[p2->val].val; } void i_mul(ctx_t *ctx, acc_t *p1, acc_t *p2) { if (p1->mem) { _except(ctx, E_IMP, "Memory access"); } // Adapted from www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring ulong u = p1->type >= A_IMM16 ? p1->val : ctx->r[p1->val].val; ulong v = ctx->r[RAX].val; 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); ctx->r[RDX].val = (u * v) + w1 + k; ctx->r[RAX].val = (t << 32) + w3; } void i_div(ctx_t *ctx, acc_t *p1, acc_t *p2) { if (p1->mem) { _except(ctx, E_IMP, "Memory access"); } ulong val = p1->type >= A_IMM16 ? p1->val : ctx->r[p1->val].val; ctx->r[RDX].val = ctx->r[RAX].val % val; ctx->r[RAX].val = ctx->r[RAX].val / val; } void i_inc(ctx_t *ctx, acc_t *p1, acc_t *p2) { if (p1->type != A_REG) { _except(ctx, E_ILL, "INC on an IMM"); } if (p1->mem) { _except(ctx, E_IMP, "Memory access"); } ctx->r[p1->val].val++; } void i_dec(ctx_t *ctx, acc_t *p1, acc_t *p2) { if (p1->type != A_REG) { _except(ctx, E_ILL, "DEC on an IMM"); } if (p1->mem) { _except(ctx, E_IMP, "Memory access"); } ctx->r[p1->val].val--; } void i_mov(ctx_t *ctx, acc_t *p1, acc_t *p2) { if (p1->type != A_REG) { _except(ctx, E_ILL, "MOV into IMM"); } if (p1->mem || p2->mem) { _except(ctx, E_IMP, "Memory access"); } ctx->r[p1->val].val = p2->type >= A_IMM16 ? p2->val : ctx->r[p2->val].val; } void i_xchg(ctx_t *ctx, acc_t *p1, acc_t *p2) { if (p1->type != A_REG || p2->type != A_REG) { _except(ctx, E_ILL, "XCHG of IMM(s)"); } if (p1->mem || p2->mem) { _except(ctx, E_IMP, "Memory access"); } ulong temp = ctx->r[p1->val].val; ctx->r[p1->val].val = ctx->r[p2->val].val; ctx->r[p2->val].val = temp; } instr_t arch_i[NINSTRS] = { [I_ADD] = { "ADD", 2, i_add }, [I_SUB] = { "SUB", 2, i_sub }, [I_MUL] = { "MUL", 1, i_mul }, [I_DIV] = { "DIV", 1, i_div }, [I_INC] = { "INC", 1, i_inc }, [I_DEC] = { "DEC", 1, i_dec }, [I_MOV] = { "MOV", 2, i_mov }, [I_XCHG] = { "XCHG", 2, i_xchg }, };