From a56621ad9a098364fff49b9e263ef68a56b09346 Mon Sep 17 00:00:00 2001 From: julianb0 Date: Wed, 15 May 2019 21:47:08 +0200 Subject: [PATCH] stuff --- .gitignore | 3 + INSTRS | 26 -------- LICENCE => LICENSE | 0 Makefile | 18 ++++-- instr/INSTRS | 45 +++++++++++++ instr/instrs.c | 79 +++++++++++++++++++++++ instr/instrs.h | 25 ++++++++ instr/instrs.py | 68 ++++++++++++++++++++ instrs.c | 141 ----------------------------------------- arch.c => karch/arch.c | 8 +-- arch.h => karch/arch.h | 27 +++----- main.c => karch/main.c | 14 ++-- regs.c => karch/regs.c | 0 13 files changed, 253 insertions(+), 201 deletions(-) create mode 100644 .gitignore delete mode 100644 INSTRS rename LICENCE => LICENSE (100%) create mode 100644 instr/INSTRS create mode 100644 instr/instrs.c create mode 100644 instr/instrs.h create mode 100644 instr/instrs.py delete mode 100644 instrs.c rename arch.c => karch/arch.c (94%) rename arch.h => karch/arch.h (89%) rename main.c => karch/main.c (68%) rename regs.c => karch/regs.c (100%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c07e34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +k.exe +*.o +arch_i.h diff --git a/INSTRS b/INSTRS deleted file mode 100644 index 2fe9ef9..0000000 --- a/INSTRS +++ /dev/null @@ -1,26 +0,0 @@ -# The OS/K Team licences this file to you under the MIT license. -# See the LICENCE 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/LICENCE b/LICENSE similarity index 100% rename from LICENCE rename to LICENSE diff --git a/Makefile b/Makefile index 1f255a1..4c525ad 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,21 @@ # The OS/K Team licences this file to you under the MIT license. # See the LICENCE file in the project root for more information. -src = arch.c instrs.c main.c regs.c +all: k.exe + +src = instr/instrs.c karch/arch.c karch/main.c karch/regs.c obj = $(patsubst %.c,%.o,$(src)) -%.o: %.c - @gcc -O2 -Wall -c $< -o $@ +%.o: %.c instrs/i_arch.h + @gcc -O2 -Wall -I./karch -c $< -o $@ -k.exe: $(obj) +instrs/i_arch.h: instr/INSTRS instr/instrs.py + @python3 instr/instrs.py + +clean: + @rm */*.o + +k.exe: $(obj) instrs/i_arch.h instr/INSTRS instr/instrs.py @gcc -O2 -Wall $(obj) -o k.exe - @rm *.o + @rm */*.o diff --git a/instr/INSTRS b/instr/INSTRS new file mode 100644 index 0000000..4ccddfd --- /dev/null +++ b/instr/INSTRS @@ -0,0 +1,45 @@ +# The OS/K Team licences this file to you under the MIT license. +# See the LICENCE file in the project root for more information. + +add r r +add r i +add r m +add m r +add m i +add m m + %0 = %0 + %1 + +sub r r +sub r i +sub r m +sub m r +sub m i +sub m m + %0 = %0 + %1 + +mul r +mul i + rax = hi(rax * %0) + rax = lo(rax * %0) + +div r +div i + rdx = rax % %0 + rax = rax / %0 + +inc r +inc m + %0 = %0 + 1 + +dec r +dec m + %0 = %0 - 1 + +mov r r +mov r i +mov r m +mov m r +mov m i +mov m m + %0 = %1 + diff --git a/instr/instrs.c b/instr/instrs.c new file mode 100644 index 0000000..f19cdb1 --- /dev/null +++ b/instr/instrs.c @@ -0,0 +1,79 @@ +// The OS/K Team licences this file to you under the MIT license. +// See the LICENCE file in the project root for more information. + +#include "instrs.h" + +IMPL_START_2(add) +{ + v1 += v2; +} +IMPL_OUT; + +IMPL_START_2(sub) +{ + v1 -= v2; +} +IMPL_OUT; + +IMPL_START_1(mul) +{ + // Adapted from www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring + ulong v2 = v1; + v1 = ctx->r[RAX].val; + + ulong u1 = (v1 & 0xffffffff); + ulong u2 = (v2 & 0xffffffff); + ulong t = (u1 * u2); + ulong w3 = (t & 0xffffffff); + ulong k = (t >> 32); + + v1 >>= 32; + t = (v1 * u2) + k; + k = (t & 0xffffffff); + ulong w1 = (t >> 32); + + v2 >>= 32; + t = (u1 * v2) + k; + k = (t >> 32); + + ctx->r[RDX].val = (v1 * v2) + w1 + k; + ctx->r[RAX].val = (t << 32) + w3; +} +IMPL_END; + +IMPL_START_1(div) +{ + ctx->r[RDX].val = ctx->r[RAX].val % v1; + ctx->r[RAX].val = ctx->r[RAX].val / v1; +} +IMPL_END; + +IMPL_START_1(inc) +{ + v1++; +} +IMPL_OUT; + +IMPL_START_1(dec) +{ + v1--; +} +IMPL_OUT; + +IMPL_START_2(mov) +{ + v1 = v2; +} +IMPL_OUT; + +IMPL_START_2(xchg) +{ + ulong t = v1; + v1 = v2; + v2 = t; +} +IMPL_OUT; + +#define _NEED_ARCH_I +#include "arch_i.h" + diff --git a/instr/instrs.h b/instr/instrs.h new file mode 100644 index 0000000..df7e94a --- /dev/null +++ b/instr/instrs.h @@ -0,0 +1,25 @@ +// The OS/K Team licences this file to you under the MIT license. +// See the LICENCE file in the project root for more information. + +#include "arch.h" + +#define IMPL_START_1(name) \ +void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ +{ \ + ulong v1 = (p1->type == A_REG ? ctx->r[p1->val].val : p1->val); \ + +#define IMPL_START_2(name) \ +void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ +{ \ + ulong v1 = (p1->type == A_REG ? ctx->r[p1->val].val : p1->val); \ + ulong v2 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val); \ + +#define IMPL_OUT \ + assert(p1->type == A_REG); \ + ctx->r[p1->val].val = v1; \ +} \ + +#define IMPL_END \ +} + + diff --git a/instr/instrs.py b/instr/instrs.py new file mode 100644 index 0000000..2a3f597 --- /dev/null +++ b/instr/instrs.py @@ -0,0 +1,68 @@ +#!/usr/bin/python + +# The OS/K Team licences this file to you under the MIT license. +# See the LICENCE file in the project root for more information. + +fi = open("instr/INSTRS") +hd = open("instr/arch_i.h", "w") + +count = 0 + +hd.write("#ifdef _NEED_ARCH_I\n") +hd.write("instr_t arch_i[] =\n{\n\n") +hd.write("#endif\n") + +def getflag(s): + if s == "r": + return "P_REG" + + if s == "i": + return "P_IMM" + + if s == "m": + return "P_MEM" + + return "__ERROR__" + +for _, line in enumerate(fi): + if line[0] == '#' or line[0] == ' ' or line[0] == '\n': + continue + + tok = line.split(' ') + + if len(tok) == 1: + name = tok[0].strip() + p1 = "NOPRM" + p2 = "NOPRM" + + elif len(tok) == 2: + name = "{}_{}".format(tok[0], tok[1].strip()) + p1 = getflag(tok[1].strip()) + p2 = "NOPRM" + + elif len(tok) == 3: + name = "{}_{}_{}".format(tok[0], tok[1], tok[2].strip()) + p1 = getflag(tok[1]) + p2 = getflag(tok[2].strip()) + + else: + name = "__ERROR__" + p1 = "__ERROR__" + p2 = "__ERROR__" + + hd.write("#define I_{} {}\n".format(name.upper(), count)) + hd.write("#ifdef _NEED_ARCH_I\n") + hd.write('{{ "{}", "{}", {}, {}, i_{} }},\n'\ + .format(tok[0], name, p1, p2, tok[0])) + hd.write("#endif\n\n") + + count = count + 1 +hd.write("#define NINSTRS {}\n\n".format(count)) + +hd.write("#ifdef _NEED_ARCH_I\n") +hd.write("};\n") +hd.write("#endif\n") + +hd.close() +fi.close() + diff --git a/instrs.c b/instrs.c deleted file mode 100644 index ac65158..0000000 --- a/instrs.c +++ /dev/null @@ -1,141 +0,0 @@ -// The OS/K Team licences this file to you under the MIT license. -// See the LICENCE 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/arch.c b/karch/arch.c similarity index 94% rename from arch.c rename to karch/arch.c index 727e228..1f10b0c 100644 --- a/arch.c +++ b/karch/arch.c @@ -69,7 +69,7 @@ void dumpinstr(ctx_t *ctx, ushort c, acc_t *p1, acc_t *p2) instr_t *i = &ctx->i[c]; log("%s", i->name); - if (i->prms > 0) + if (i->prm1 != NOPRM) p = p1; lp: if (p != 0) { @@ -82,7 +82,7 @@ lp: if (p->mem) log("]"); - if (p == p1 && i->prms == 2) { + if (p == p1 && i->prm2 != NOPRM) { p = p2; goto lp; } @@ -115,9 +115,9 @@ void decode(ctx_t *ctx) i = &ctx->i[c]; // Scan for parameters - if (i->prms > 0) { + if (i->prm1 != NOPRM) { scan_param(ctx, &p1); - if (i->prms == 2) { + if (i->prm2 != NOPRM) { scan_param(ctx, &p2); } } diff --git a/arch.h b/karch/arch.h similarity index 89% rename from arch.h rename to karch/arch.h index d4173ee..e77bfb6 100644 --- a/arch.h +++ b/karch/arch.h @@ -33,23 +33,6 @@ enum NREGS }; -enum -{ - I_ADD, I_SUB, I_MUL, I_DIV, I_INC, I_DEC, - I_AND, I_OR, I_XOR, I_NEG, I_CMD, I_TST, - - I_PUSH, I_PUSHF, I_PUSHA, - I_POP, I_POPF, I_POPA, - - I_MOV, I_XCHG, - - I_BSWP, - - I_PSE, I_HLT, I_INT, - - NINSTRS -}; - enum { GPR = 1 << 0, // General @@ -81,10 +64,16 @@ enum { NOPREF, PREF_REP=0x8000, PREF_LOCK, NPREFS }; #define ISPREF(x) ((x) & 0x8000 && (x)