diff --git a/.gitignore b/.gitignore index 4c07e34..3ff52c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ k.exe *.o arch_i.h + diff --git a/INSTRS b/INSTRS new file mode 100644 index 0000000..0f9f469 --- /dev/null +++ b/INSTRS @@ -0,0 +1,26 @@ +# The OS/K Team licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. + +ADD r ri + %0 = %0 + %1 + +SUB r ri + %0 = %0 + %1 + +MUL ri + RDX = hi(%0 * %1) + RAX = lo(%0 * %1) + +DIV ri + RDX = RAX % %0 + RAX = RAX / %0 + +INC r + %0 = %0 + 1 + +DEC r + %0 = %0 - 1 + +MOV ri ri + %0 = %1 + diff --git a/Makefile b/Makefile index 4c525ad..f2a2016 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -# The OS/K Team licences this file to you under the MIT license. -# See the LICENCE file in the project root for more information. +# The OS/K Team licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. all: k.exe diff --git a/instrs.c b/instrs.c new file mode 100644 index 0000000..f4cce91 --- /dev/null +++ b/instrs.c @@ -0,0 +1,141 @@ +// 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 }, +}; + diff --git a/karch/arch.c b/karch/arch.c index 1f10b0c..963b1c0 100644 --- a/karch/arch.c +++ b/karch/arch.c @@ -1,5 +1,5 @@ -// The OS/K Team licences this file to you under the MIT license. -// See the LICENCE file in the project root for more information. +// 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" diff --git a/karch/arch.h b/karch/arch.h index e77bfb6..60848c7 100644 --- a/karch/arch.h +++ b/karch/arch.h @@ -1,5 +1,5 @@ -// The OS/K Team licences this file to you under the MIT license. -// See the LICENCE file in the project root for more information. +// 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 diff --git a/karch/regs.c b/karch/regs.c index 9c5082f..2aa379e 100644 --- a/karch/regs.c +++ b/karch/regs.c @@ -1,5 +1,5 @@ -// The OS/K Team licences this file to you under the MIT license. -// See the LICENCE file in the project root for more information. +// 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"