diff --git a/dos/prn/print.k b/dos/prn/print.k index b12ddcf..7c5a41e 100644 --- a/dos/prn/print.k +++ b/dos/prn/print.k @@ -15,7 +15,7 @@ print: .1: test b[ax0], b[ax0] - jz .2 + cjmpz .2 prn b[ax0] inc ax0 loop .1 diff --git a/dos/str/strcpy.k b/dos/str/strcpy.k index 8336202..819031c 100644 --- a/dos/str/strcpy.k +++ b/dos/str/strcpy.k @@ -5,6 +5,15 @@ ; void strcpy(char *, const char *) ; strcpy: + test b[ax1], b[ax1] + cmovz b[ax0], 0 + cretz + +.1: + test b[ax1], b[ax1] + cmovz b[ax0], 0 + cretz + ret ; diff --git a/dos/str/strlen.k b/dos/str/strlen.k index e8bc4de..9bc9a58 100644 --- a/dos/str/strlen.k +++ b/dos/str/strlen.k @@ -9,31 +9,27 @@ strlen: .1: test b[ax0], b[ax0] - jz .2 + cretz inc rax inc ax0 jmp .1 -.2: - ret - ; ; int strnlen(char *, int) ; strnlen: xor rax, rax mov rcx, ax1 - jcxz .2 + ;jcxz .2 dec rcx .1: test b[ax0], b[ax0] - jz .2 + cretz inc rax inc ax0 loop .1 -.2: ret diff --git a/dos/str/strrev.k b/dos/str/strrev.k index 002afbd..48c24db 100644 --- a/dos/str/strrev.k +++ b/dos/str/strrev.k @@ -7,7 +7,7 @@ strrev: test b[ax1], b[ax1] cmovz b[ax0], 0 - jz .4 + cretz ; save str's location mov rdx, ax1 @@ -16,25 +16,19 @@ strrev: ; the null terminator .1: test b[ax1+1], b[ax1+1] - jz .2 - - inc ax1 - jmp .1 + cincnz ax1 + cjmpnz .1 +.2: ; copy, going backward though str ; and forward through buf -.2: mov b[ax0], b[ax1] cmp ax1, rdx - je .3 + cmovz b[ax0+1], 0 + cretz inc ax0 dec ax1 jmp .2 -.3: - mov b[ax0+1], 0 - -.4: - ret diff --git a/pc/Makefile b/pc/Makefile index 4d1ad7c..1e54f5f 100644 --- a/pc/Makefile +++ b/pc/Makefile @@ -12,7 +12,7 @@ obj = $(patsubst %.c,%.o,$(src)) CFLAGS=-O2 -g -Wall -fno-builtin-log -%.o: %.c i_arch.h *.h $(src) +%.o: %.c i_arch.h *.h */*.h $(src) @gcc $(CFLAGS) -c $< -o $@ i_arch.h: instrs/INSTRS instrs/arch_i.py diff --git a/pc/instrs/INSTRS b/pc/instrs/INSTRS index 9a021e9..2ee728f 100644 --- a/pc/instrs/INSTRS +++ b/pc/instrs/INSTRS @@ -59,6 +59,20 @@ add m r add m i add m m +caddz r r +caddz r i +caddz r m +caddz m r +caddz m i +caddz m m + +caddnz r r +caddnz r i +caddnz r m +caddnz m r +caddnz m i +caddnz m m + sub r r sub r i sub r m @@ -66,22 +80,60 @@ sub m r sub m i sub m m +csubz r r +csubz r i +csubz r m +csubz m r +csubz m i +csubz m m + +csubnz r r +csubnz r i +csubnz r m +csubnz m r +csubnz m i +csubnz m m + # rdx = hi(rax * $0) # rax = lo(rax * $0) mul r mul i +cmulz r +cmulz i + +cmulnz r +cmulnz i + # rdx = rax % $0 # rax = rax / $0 div r div i +cdivz r +cdivz i + +cdivnz r +cdivnz i + inc r inc m +cincz r +cincz m + +cincnz r +cincnz m + dec r dec m +cdecz r +cdecz m + +cdecnz r +cdecnz m + # # Comparison instruction # @@ -115,30 +167,34 @@ test m m jmp r jmp i -loop r -loop i +cjmpz r +cjmpz i +cjmpnz r +cjmpnz i -jz r -jz i -jnz r -jnz i -je r -je i -jne r -jne i +cjmpa r +cjmpa i +cjmpae r +cjmpae i -ja r -ja i -jae r -jae i - -jb r -jb i -jbe r -jbe i +cjmpb r +cjmpb i +cjmpbe r +cjmpbe i jcxz r jcxz i +jcxnz r +jcxnz i + +loop r +loop i + +cloopz r +cloopz i + +cloopnz r +cloopnz i # # Movement instructions @@ -151,16 +207,6 @@ mov m r mov m i mov m m -xchg r r -xchg r i -xchg r m -xchg m r -xchg m i -xchg m m - -lea r m -lea m m - cmovz r r cmovz r i cmovz r m @@ -175,6 +221,36 @@ cmovnz m r cmovnz m i cmovnz m m +xchg r r +xchg r i +xchg r m +xchg m r +xchg m i +xchg m m + +cxchgz r r +cxchgz r i +cxchgz r m +cxchgz m r +cxchgz m i +cxchgz m m + +cxchgnz r r +cxchgnz r i +cxchgnz r m +cxchgnz m r +cxchgnz m i +cxchgnz m m + +lea r m +lea m m + +cleaz r m +cleaz m m + +cleanz r m +cleanz m m + # # Stack manipulation instructions # @@ -191,6 +267,8 @@ call i call m ret +cretz +cretnz # push rbp # mov rbp, rsp @@ -199,6 +277,8 @@ enter # mov rbp, [rsp+8] # add rsp, 8 leave +cleavez +cleavenz pushf diff --git a/pc/instrs/arith.c b/pc/instrs/arith.c index c3d2503..c249253 100644 --- a/pc/instrs/arith.c +++ b/pc/instrs/arith.c @@ -4,6 +4,13 @@ #include "instrs.h" #include "arch_i.h" +IMPL_COND(inc); +IMPL_COND(dec); +IMPL_COND(add); +IMPL_COND(sub); +IMPL_COND(mul); +IMPL_COND(div); + // // Unsigned arithmetic instructions // diff --git a/pc/instrs/debug.c b/pc/instrs/debug.c index 3283093..71dcd6c 100644 --- a/pc/instrs/debug.c +++ b/pc/instrs/debug.c @@ -4,6 +4,8 @@ #include "instrs.h" #include "arch_i.h" +IMPL_COND(break); + IMPL_START_0(break) { log("\nExecuting BREAK INSTR\n"); diff --git a/pc/instrs/instrs.h b/pc/instrs/instrs.h index 07dd1e5..cdf8291 100644 --- a/pc/instrs/instrs.h +++ b/pc/instrs/instrs.h @@ -5,13 +5,13 @@ #define IMPL_START_0(name) \ 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 ? ctx->r[p1->val].val : p1->val); \ - if (p1->mem) v1 = readmem(ctx, v1 + p1->off, p1->mlen); \ + if (p1->mem) v1 = readmem(ctx, v1 + p1->off, p1->mlen); #define IMPL_START_2(name) \ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ @@ -19,13 +19,13 @@ 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); \ if (p1->mem) v1 = readmem(ctx, v1 + p1->off, p1->mlen); \ - if (p2->mem) v2 = readmem(ctx, v2 + p2->off, p2->mlen); \ + if (p2->mem) v2 = readmem(ctx, v2 + p2->off, p2->mlen); #define IMPL_START_3(name) \ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ { \ ulong v2 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val); \ - if (p2->mem) v2 = readmem(ctx, v2 + p2->off, p2->mlen); \ + if (p2->mem) v2 = readmem(ctx, v2 + p2->off, p2->mlen); #define IMPL_OUT \ assert(p1->type == A_REG || p1->mem); \ @@ -34,11 +34,41 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ writemem(ctx, v1, addr + p1->off, p1->mlen); \ } \ else ctx->r[p1->val].val = v1; \ -} \ +} #define IMPL_END \ } +// +// c...z instructions easy implementation +// + +#define IMPL_CxxxZ(name) \ +IMPL_START_0(c##name##z) \ +{ \ + if (ctx->r[FLG].val & ZF) { \ + i_##name(ctx, p1, p2); \ + } \ +} \ +IMPL_END + +#define IMPL_CxxxNZ(name) \ +IMPL_START_0(c##name##nz) \ +{ \ + if (!(ctx->r[FLG].val & ZF)) { \ + i_##name(ctx, p1, p2); \ + } \ +} \ +IMPL_END + +#define IMPL_COND(name) \ + IMPL_CxxxZ(name); \ + IMPL_CxxxNZ(name) + +// +// Consistency checks +// + #define CHK_SUPERV() \ do { \ if ((ctx->r[CR0].val & UF) == 1) { \ @@ -54,9 +84,14 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ _except(ctx, E_STK, "RSP above RBP"); \ } + +// +// Common operations +// + #define PUSH(v) \ writemem64(ctx, v, ctx->r[RSP].val); \ - ctx->r[RSP].val -= 8; \ + ctx->r[RSP].val -= 8; #define POP(v) \ ctx->r[RSP].val += 8; \ diff --git a/pc/instrs/jumps.c b/pc/instrs/jumps.c index 4fbf6fe..b74e11b 100644 --- a/pc/instrs/jumps.c +++ b/pc/instrs/jumps.c @@ -4,6 +4,9 @@ #include "instrs.h" #include "arch_i.h" +IMPL_COND(jmp); +IMPL_COND(loop); + // // Jump instructions // @@ -23,56 +26,28 @@ IMPL_START_1(loop) } IMPL_END; -IMPL_START_1(jz) -{ - if (ctx->r[FLG].val & ZF) - JUMP(v1); -} -IMPL_END; - -IMPL_START_1(jnz) -{ - if (!(ctx->r[FLG].val & ZF)) - JUMP(v1); -} -IMPL_END; - -IMPL_START_1(je) -{ - if (ctx->r[FLG].val & ZF) - JUMP(v1); -} -IMPL_END; - -IMPL_START_1(jne) -{ - if (!(ctx->r[FLG].val & ZF)) - JUMP(v1); -} -IMPL_END; - -IMPL_START_1(ja) +IMPL_START_1(cjmpa) { if (!(ctx->r[FLG].val & ZF) && !(ctx->r[FLG].val & CF)) JUMP(v1); } IMPL_END; -IMPL_START_1(jae) +IMPL_START_1(cjmpae) { if (!(ctx->r[FLG].val & CF)) JUMP(v1); } IMPL_END; -IMPL_START_1(jb) +IMPL_START_1(cjmpb) { if (!(ctx->r[FLG].val & ZF) && ctx->r[FLG].val & CF) JUMP(v1); } IMPL_END; -IMPL_START_1(jbe) +IMPL_START_1(cjmpbe) { if (ctx->r[FLG].val & CF) JUMP(v1); @@ -85,3 +60,11 @@ IMPL_START_1(jcxz) JUMP(v1); } IMPL_END; + +IMPL_START_1(jcxnz) +{ + if (ctx->r[RCX].val) + JUMP(v1); +} +IMPL_END; + diff --git a/pc/instrs/mov.c b/pc/instrs/mov.c index 87ecd68..ca6bd30 100644 --- a/pc/instrs/mov.c +++ b/pc/instrs/mov.c @@ -4,6 +4,10 @@ #include "instrs.h" #include "arch_i.h" +IMPL_COND(mov); +IMPL_COND(lea); +IMPL_COND(xchg); + // // Movement instructions // @@ -38,17 +42,3 @@ IMPL_START_1(gcs) } IMPL_OUT; -IMPL_START_2(cmovz) -{ - if (ctx->r[FLG].val & ZF) - v1 = v2; -} -IMPL_OUT; - -IMPL_START_2(cmovnz) -{ - if (!(ctx->r[FLG].val & ZF)) - v1 = v2; -} -IMPL_OUT; - diff --git a/pc/instrs/stack.c b/pc/instrs/stack.c index cf96805..245c42a 100644 --- a/pc/instrs/stack.c +++ b/pc/instrs/stack.c @@ -4,6 +4,9 @@ #include "instrs.h" #include "arch_i.h" +IMPL_COND(ret); +IMPL_COND(leave); + // // Stack manipulation instructions //