From 81b739a7395743bab0db8e73bfee4b6aa5d1e2d8 Mon Sep 17 00:00:00 2001 From: julianb0 Date: Thu, 6 Jun 2019 14:57:34 +0200 Subject: [PATCH] mem --- as/k-as.py | 26 ++++++--- ka/main.k | 4 ++ vm/in/INSTRS | 150 +++++++++++------------------------------------- vm/in/arch_i.py | 43 ++++++++++---- vm/in/arith.c | 5 +- vm/in/instrs.h | 66 +++++++++++++++++---- vm/in/jumps.c | 28 --------- vm/in/mov.c | 8 ++- vm/pc/arch.h | 1 + vm/pc/decd.c | 1 + 10 files changed, 156 insertions(+), 176 deletions(-) diff --git a/as/k-as.py b/as/k-as.py index 4ebd1ce..74c6ac5 100755 --- a/as/k-as.py +++ b/as/k-as.py @@ -364,7 +364,7 @@ def parse_instr(line): word = word[1:].strip() assert(word[0] == '[') - # [reg+off] or [imm64] + # [reg+off], [reg+regoff+off] or [imm64] if word[0] == '[': assert(word[-1] == ']') word = word[1:-1] @@ -378,20 +378,32 @@ def parse_instr(line): instr_args += "{}".format(pref) if '+' in word: - # +2 for A_OFF, +2 for offset, +2 for register - size += 2 + 2 + 2 + # +2 for A_OFF, +2 for offset, +2 for regoff, +2 for register + size += 2 + 2 + 2 + 2 instr_args += "off " assert(len(word) > 3) - reg, off = word.split('+', 1) - reg = reg.strip() - off = off.strip() + regoff = "inv" - instr_args += "{} {}".format(off, reg) + # [reg+off] + if len(word.split('+')) == 2: + reg, off = word.split('+', 1) + + # [reg+regoff+off] + else: + assert(len(word.split('+')) == 3) + reg, regoff, off = word.split('+', 2) + + off = off.strip() + reg = reg.strip() + regoff = regoff.strip() + + instr_args += "{} {} {}".format(off, regoff, reg) continue + # [imm64] else: # +2 for A_MEM size += 2 diff --git a/ka/main.k b/ka/main.k index a29639e..2876e57 100644 --- a/ka/main.k +++ b/ka/main.k @@ -24,6 +24,10 @@ main: mov ax0, rax call print + mov rsi, 0x10 + mov rdi, 8 + lea rbi, b[rsi + rdi + 1] + leave ret diff --git a/vm/in/INSTRS b/vm/in/INSTRS index 09c1a50..7158385 100644 --- a/vm/in/INSTRS +++ b/vm/in/INSTRS @@ -8,69 +8,33 @@ nop # Logical instructions # -not rm -and rm rim -or rm rim -xor rm rim -shl rm rim -shr rm rim - -cnotz rm -candz rm rim -corz rm rim -cxorz rm rim -cshlz rm rim -cshrz rm rim - -cnotnz rm -candnz rm rim -cornz rm rim -cxornz rm rim -cshlnz rm rim -cshrnz rm rim +!not rm +!and rm rim +!or rm rim +!xor rm rim +!shl rm rim +!shr rm rim # # Unsigned arithmetic instructions # -# mul: +!inc rm +!dec rm +!add rm rim +!sub rm rim +!mul rm rim +!div rm rim +!mod rm rim +!sgn rm rim + # rdx = hi(rax * $0) # rax = lo(rax * $0) +!mul2 rim -# div: # rdx = rax % $0 # rax = rax / $0 - -sgn rm rim - -inc rm -dec rm -add rm rim -sub rm rim - -mul rm rim -mul2 rim - -div rm rim -div2 rim - -mod rm rim - -csgnz rm rim -caddz rm rim -csubz rm rim -cmulz rim -cdivz rim -cincz rm -cdecz rm - -csgnnz rm rim -caddnz rm rim -csubnz rm rim -cmulnz rim -cdivnz rim -cincnz rm -cdecnz rm +!div2 rim # # Comparison instruction @@ -92,76 +56,35 @@ testt rim rim # Jump instructions # -jmp ri - -cjmpz ri -cjmpnz ri - -cjmpa ri -cjmpae ri - -cjmpb ri -cjmpbe ri +!jmp ri jcxz ri jcxnz ri -loop ri -cloopz ri -cloopnz ri +!loop ri # # Movement instructions # -lea rm m -mov rm rim -xchg rm rim -cmpxchg rm rim +!lea rm m +!mov rm rim +!xchg rm rim +!cmpxchg rm rim -cleaz rm m -cmovz rm rim -cxchgz rm rim -ccmpxchgz rm rim - -cleanz rm m -cmovnz rm rim -cxchgnz rm rim -ccmpxchgnz rm rim - -movb rm rim -movw rm rim -movl rm rim -movt rm rim - -cmovbz rm rim -cmovwz rm rim -cmovlz rm rim -cmovtz rm rim - -cmovbnz rm rim -cmovwnz rm rim -cmovlnz rm rim -cmovtnz rm rim +!movb rm rim +!movw rm rim +!movl rm rim +!movt rm rim # # Stack manipulation instructions # -push rim -call rim -pop rm -ret - -cpushz rim -ccallz rim -cpopz rm -cretz - -cpushnz rim -ccallnz rim -cpopnz rm -cretnz +!push rim +!call rim +!pop rm +!ret # push rbp # mov rbp, rsp @@ -169,18 +92,15 @@ enter # add rsp, 8 # mov rbp, [rsp] -leave -cleavez -cleavenz +!leave pushf +popf # # Supervisor only instructions # -popf - cli sti @@ -206,9 +126,7 @@ prn rim # # Debugging instructions # -break -cbreakz -cbreaknz +!break step rim diff --git a/vm/in/arch_i.py b/vm/in/arch_i.py index 9f009eb..d0513e3 100644 --- a/vm/in/arch_i.py +++ b/vm/in/arch_i.py @@ -29,7 +29,24 @@ def getflag(s): if s == "m": return "P_MEM" - return "__ERROR__" + return "__FLAG_ERROR__" + +def doprnt(i, p1, p2, cond): + doprnt_2(i, p1, p2) + + if cond: + doprnt_2('c' + i + 'z', p1, p2) + doprnt_2('c' + i + 'a', p1, p2) + doprnt_2('c' + i + 'b', p1, p2) + doprnt_2('c' + i + 'nz', p1, p2) + doprnt_2('c' + i + 'ae', p1, p2) + doprnt_2('c' + i + 'be', p1, p2) + +def doprnt_2(i, p1, p2): + for c1 in p1: + for c2 in p2: + fp.write("{} {} {}".format(i, c1, c2).strip()) + fp.write('\n') # "instr ri ri" => "instr r r\ninstr r i\ninstr i r..." # not optimal but will do for now @@ -42,28 +59,32 @@ for _, line in enumerate(fi): if len(tok) == 0: continue + cond = False + if tok[0][0] == '!': + assert(len(tok[0]) > 1) + tok[0] = tok[0][1:] + cond = True + i = tok[0].strip() if len(tok) == 1: - fp.write("{}\n".format(i)) + doprnt(i, ' ', ' ', cond) continue if len(tok) == 2: p = tok[1].strip() - for c in p: - fp.write("{} {}\n".format(i, c)) + doprnt(i, p, ' ', cond) continue assert(len(tok) == 3) p1 = tok[1].strip() p2 = tok[2].strip() - - for c1 in p1: - for c2 in p2: - fp.write("{} {} {}\n".format(i, c1, c2)) + + doprnt(i, p1, p2, cond) fp.seek(0) + for _, line in enumerate(fp): tok = line.strip().split(' ') @@ -83,9 +104,9 @@ for _, line in enumerate(fp): p2 = getflag(tok[2]) else: - name = "__ERROR__" - p1 = "__ERROR__" - p2 = "__ERROR__" + name = "__TOK_ERROR__" + p1 = "__TOK_ERROR__" + p2 = "__TOK_ERROR__" ls.write("{}\n".format(name)); diff --git a/vm/in/arith.c b/vm/in/arith.c index 6f18d91..bb12a81 100644 --- a/vm/in/arith.c +++ b/vm/in/arith.c @@ -3,13 +3,16 @@ #include +IMPL_COND(sgn); IMPL_COND(inc); IMPL_COND(dec); IMPL_COND(add); IMPL_COND(sub); IMPL_COND(mul); IMPL_COND(div); -IMPL_COND(sgn); +IMPL_COND(mod); +IMPL_COND(mul2); +IMPL_COND(div2); // // Unsigned arithmetic instructions diff --git a/vm/in/instrs.h b/vm/in/instrs.h index 25a5f6b..9b94261 100644 --- a/vm/in/instrs.h +++ b/vm/in/instrs.h @@ -4,6 +4,12 @@ #include #include +#define DECV(p, v) \ + ulong v = (p->type == A_REG ? R(p->val) : p->val); \ + if (p->mem) { \ + v = readmem(ctx, v + p->off + R(p->offreg), p1->mlen); \ + } + #define IMPL_START_0(name) \ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ { @@ -11,28 +17,24 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ #define IMPL_START_1(name) \ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ { \ - ulong v1 = (p1->type == A_REG ? R(p1->val) : p1->val); \ - if (p1->mem) v1 = readmem(ctx, v1 + p1->off, p1->mlen); + DECV(p1, v1); #define IMPL_START_2(name) \ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ { \ - ulong v1 = (p1->type == A_REG ? R(p1->val) : p1->val); \ - ulong v2 = (p2->type == A_REG ? R(p2->val) : p2->val); \ - if (p1->mem) v1 = readmem(ctx, v1 + p1->off, p1->mlen); \ - if (p2->mem) v2 = readmem(ctx, v2 + p2->off, p2->mlen); + DECV(p1, v1); \ + DECV(p2, v2); #define IMPL_START_3(name) \ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ { \ - ulong v2 = (p2->type == A_REG ? R(p2->val) : p2->val); \ - if (p2->mem) v2 = readmem(ctx, v2 + p2->off, p2->mlen); + DECV(p2, v2); #define IMPL_OUT \ assert(p1->type == A_REG || p1->mem); \ if (p1->mem) { \ ulong addr = p1->type == A_REG ? R(p1->val) : p1->val; \ - writemem(ctx, v1, addr + p1->off, p1->mlen); \ + writemem(ctx, v1, addr + p1->off + R(p1->offreg), p1->mlen); \ } \ else R(p1->val) = v1; \ } @@ -41,14 +43,14 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ assert(p1->type == A_REG || p1->mem); \ if (p1->mem) { \ ulong addr = p1->type == A_REG ? R(p1->val) : p1->val; \ - writemem(ctx, v1, addr + p1->off, p1->mlen); \ + writemem(ctx, v1, addr + p1->off + R(p1->offreg), p1->mlen); \ } \ else R(p1->val) = v1; \ \ assert(p2->type == A_REG || p2->mem); \ if (p2->mem) { \ ulong addr = p2->type == A_REG ? R(p2->val) : p2->val; \ - writemem(ctx, v2, addr + p2->off, p2->mlen); \ + writemem(ctx, v2, addr + p2->off + R(p2->offreg), p2->mlen); \ } \ else R(p2->val) = v2; \ } @@ -78,9 +80,49 @@ IMPL_START_0(c##name##nz) \ } \ IMPL_END +#define IMPL_CxxxA(name) \ +IMPL_START_0(c##name##a) \ +{ \ + if (!(flg & ZF) && !(flg & CF)) { \ + i_##name(ctx, p1, p2); \ + } \ +} \ +IMPL_END + +#define IMPL_CxxxAE(name) \ +IMPL_START_0(c##name##ae) \ +{ \ + if (!(flg & CF)) { \ + i_##name(ctx, p1, p2); \ + } \ +} \ +IMPL_END + +#define IMPL_CxxxB(name) \ +IMPL_START_0(c##name##b) \ +{ \ + if (!(flg & ZF) && (flg & CF)) { \ + i_##name(ctx, p1, p2); \ + } \ +} \ +IMPL_END + +#define IMPL_CxxxBE(name) \ +IMPL_START_0(c##name##be) \ +{ \ + if (flg & CF) { \ + i_##name(ctx, p1, p2); \ + } \ +} \ +IMPL_END + #define IMPL_COND(name) \ IMPL_CxxxZ(name); \ - IMPL_CxxxNZ(name) + IMPL_CxxxA(name); \ + IMPL_CxxxB(name); \ + IMPL_CxxxNZ(name); \ + IMPL_CxxxAE(name); \ + IMPL_CxxxBE(name) // // Consistency checks diff --git a/vm/in/jumps.c b/vm/in/jumps.c index 937fa1d..58cfaba 100644 --- a/vm/in/jumps.c +++ b/vm/in/jumps.c @@ -25,34 +25,6 @@ IMPL_START_1(loop) } IMPL_END; -IMPL_START_1(cjmpa) -{ - if (!(flg & ZF) && !(flg & CF)) - JUMP(v1); -} -IMPL_END; - -IMPL_START_1(cjmpae) -{ - if (!(flg & CF)) - JUMP(v1); -} -IMPL_END; - -IMPL_START_1(cjmpb) -{ - if (!(flg & ZF) && flg & CF) - JUMP(v1); -} -IMPL_END; - -IMPL_START_1(cjmpbe) -{ - if (flg & CF) - JUMP(v1); -} -IMPL_END; - IMPL_START_1(jcxz) { if (!rcx) diff --git a/vm/in/mov.c b/vm/in/mov.c index cf58310..c147004 100644 --- a/vm/in/mov.c +++ b/vm/in/mov.c @@ -67,7 +67,13 @@ IMPL_OUT_2; IMPL_START_1(lea) { - v1 = (p2->type == A_REG ? R(p2->val) : p2->val) + p2->off; + ulong v2 = (p2->type == A_REG ? R(p2->val) : p2->val); + + if (p2->mem) { + v2 += p2->off + R(p2->offreg); + } + + v1 = v2; } IMPL_OUT; diff --git a/vm/pc/arch.h b/vm/pc/arch.h index 1645fd4..53481e1 100644 --- a/vm/pc/arch.h +++ b/vm/pc/arch.h @@ -70,6 +70,7 @@ struct acc_t bool mem; uint mlen; short off; + uint offreg; uint type; uint ilen; diff --git a/vm/pc/decd.c b/vm/pc/decd.c index 5e8ee4e..f1f5549 100644 --- a/vm/pc/decd.c +++ b/vm/pc/decd.c @@ -44,6 +44,7 @@ static void scan_param(ctx_t *ctx, acc_t *p) p->mem = 1; p->mlen = c & 0xF; p->off = (short)ctx->get(ctx); + p->offreg = ctx->get(ctx); c = ctx->get(ctx); }