From 3947cf245e051c129e15fda46120c93154b804c4 Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 1 Apr 2015 23:53:26 +0300 Subject: [PATCH] translate: some bugfixes --- run_imp.sh | 6 +++--- tests/Makefile | 2 +- tests/ops.asm | 48 ++++++++++++++++++++++++++++++++++++++++++++++ tests/ops.expect.c | 38 ++++++++++++++++++++++++++++++++++++ tests/ops.seed.h | 0 tools/translate.c | 46 +++++++++++++++++++++++--------------------- 6 files changed, 114 insertions(+), 26 deletions(-) create mode 100644 tests/ops.asm create mode 100644 tests/ops.expect.c create mode 100644 tests/ops.seed.h diff --git a/run_imp.sh b/run_imp.sh index 665b3f9..15381b7 100755 --- a/run_imp.sh +++ b/run_imp.sh @@ -27,9 +27,9 @@ cat $implist | while read i; do ;; esac - grep "\<_\?_$si\>" /usr/$mingwb/lib/lib* "$@" | awk '{print $3}' | \ + grep -e "\<_\?_$si\>" -e "@$si\>" /usr/$mingwb/lib/lib* "$@" | awk '{print $3}' | \ while read f; do - sym=`${mingwb}-nm $f | grep "\<_\?_$si\>" | grep ' T ' | awk '{print $3}'` + sym=`${mingwb}-nm $f | grep -e "\<_\?_$si\>" -e " @$si\>" | grep ' T ' | awk '{print $3}'` if test -n "$sym"; then echo $sym > $tmpsym break @@ -37,7 +37,7 @@ cat $implist | while read i; do done sym=`cat $tmpsym` if test -z "$sym"; then - echo "no file/sym for $i, lf $f" + echo "$target_s: no file/sym for $i" exit 1 fi diff --git a/tests/Makefile b/tests/Makefile index 360c2e6..8d81519 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,6 @@ TESTS = reg_call1 reg_call2 reg_call3 reg_call_tail reg_save \ - varargs + varargs ops all: $(addsuffix .ok,$(TESTS)) diff --git a/tests/ops.asm b/tests/ops.asm new file mode 100644 index 0000000..472a024 --- /dev/null +++ b/tests/ops.asm @@ -0,0 +1,48 @@ +; test random ops + +_text segment para public 'CODE' use32 + +sub_test proc near + push ebp + push ebx + push esi + push edi + mov ebx, 10000h + mov esi, 20000h + mov edi, 30000h + mov ecx, 10 +loop: + lodsb + xlat + stosb + lodsw + neg ax + stosw + lodsd + stosd + movsb + cmpsw + scasb + loop loop + + std + stosb + stosw + stosd + cld + + cdq + bsf eax, ecx + + push 1 + pop eax + pop edi + pop esi + pop ebx + pop ebp + retn +sub_test endp + +_text ends + +; vim:expandtab diff --git a/tests/ops.expect.c b/tests/ops.expect.c new file mode 100644 index 0000000..3b59db1 --- /dev/null +++ b/tests/ops.expect.c @@ -0,0 +1,38 @@ +int sub_test() +{ + u32 eax; + u32 ebx; + u32 ecx; + u32 edx; + u32 esi; + u32 edi; + u32 cond_z; + + ebx = 0x10000; + esi = 0x20000; + edi = 0x30000; + ecx = 0x0a; + +loop: + LOBYTE(eax) = *(u8 *)esi; esi += 1; // lods + LOBYTE(eax) = *(u8 *)(ebx + LOBYTE(eax)); // xlat + *(u8 *)edi = eax; edi += 1; // stos + LOWORD(eax) = *(u16 *)esi; esi += 2; // lods + LOWORD(eax) = -(s16)(u16)eax; + *(u16 *)edi = eax; edi += 2; // stos + eax = *(u32 *)esi; esi += 4; // lods + *(u32 *)edi = eax; edi += 4; // stos + *(u8 *)edi = *(u8 *)esi; edi += 1; esi += 1; // movs + cond_z = (*(u16 *)esi == *(u16 *)edi); esi += 2; edi += 2; // cmps + cond_z = ((u8)eax == *(u8 *)edi); edi += 1; // scas + if (--ecx != 0) + goto loop; // loop + *(u8 *)edi = eax; edi -= 1; // stos + *(u16 *)edi = eax; edi -= 2; // stos + *(u32 *)edi = eax; edi -= 4; // stos + edx = (s32)eax >> 31; // cdq + eax = ecx ? __builtin_ffs(ecx) - 1 : 0; // bsf + eax = 1; + return eax; +} + diff --git a/tests/ops.seed.h b/tests/ops.seed.h new file mode 100644 index 0000000..e69de29 diff --git a/tools/translate.c b/tools/translate.c index 1bdc884..ae90107 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -1087,7 +1087,7 @@ static void parse_op(struct parsed_op *op, char words[16][256], int wordc) op->operand_cnt = 2; setup_reg_opr(&op->operand[0], xAX, OPLM_BYTE, &op->regmask_src); op->regmask_dst = op->regmask_src; - setup_reg_opr(&op->operand[1], xDX, OPLM_DWORD, &op->regmask_src); + setup_reg_opr(&op->operand[1], xBX, OPLM_DWORD, &op->regmask_src); break; case OP_CDQ: @@ -1099,8 +1099,6 @@ static void parse_op(struct parsed_op *op, char words[16][256], int wordc) case OP_LODS: case OP_STOS: case OP_SCAS: - if (op->operand_cnt != 0) - break; if (words[op_w][4] == 'b') lmod = OPLM_BYTE; else if (words[op_w][4] == 'w') @@ -1108,20 +1106,21 @@ static void parse_op(struct parsed_op *op, char words[16][256], int wordc) else if (words[op_w][4] == 'd') lmod = OPLM_DWORD; j = 0; + op->regmask_src = 0; setup_reg_opr(&op->operand[j++], op->op == OP_LODS ? xSI : xDI, - lmod, &op->regmask_src); - if (op->flags & OPF_REP) - setup_reg_opr(&op->operand[j++], xCX, OPLM_DWORD, &op->regmask_src); + OPLM_DWORD, &op->regmask_src); op->regmask_dst = op->regmask_src; - setup_reg_opr(&op->operand[j++], xAX, OPLM_DWORD, + setup_reg_opr(&op->operand[j++], xAX, lmod, op->op == OP_LODS ? &op->regmask_dst : &op->regmask_src); + if (op->flags & OPF_REP) { + setup_reg_opr(&op->operand[j++], xCX, OPLM_DWORD, &op->regmask_src); + op->regmask_dst |= 1 << xCX; + } op->operand_cnt = j; break; case OP_MOVS: case OP_CMPS: - if (op->operand_cnt != 0) - break; if (words[op_w][4] == 'b') lmod = OPLM_BYTE; else if (words[op_w][4] == 'w') @@ -1129,6 +1128,8 @@ static void parse_op(struct parsed_op *op, char words[16][256], int wordc) else if (words[op_w][4] == 'd') lmod = OPLM_DWORD; j = 0; + op->regmask_src = 0; + // note: lmod is not correct, don't have where to place it setup_reg_opr(&op->operand[j++], xDI, lmod, &op->regmask_src); setup_reg_opr(&op->operand[j++], xSI, OPLM_DWORD, &op->regmask_src); if (op->flags & OPF_REP) @@ -5298,10 +5299,11 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) } else { assert_operand_cnt(2); - fprintf(fout, " eax = %sesi; esi %c= %d;", - lmod_cast_u_ptr(po, po->operand[0].lmod), + fprintf(fout, " %s = %sesi; esi %c= %d;", + out_dst_opr(buf1, sizeof(buf1), po, &po->operand[1]), + lmod_cast_u_ptr(po, po->operand[1].lmod), (po->flags & OPF_DF) ? '-' : '+', - lmod_bytes(po, po->operand[0].lmod)); + lmod_bytes(po, po->operand[1].lmod)); strcpy(g_comment, "lods"); } break; @@ -5311,17 +5313,17 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) assert_operand_cnt(3); fprintf(fout, " for (; ecx != 0; ecx--, edi %c= %d)\n", (po->flags & OPF_DF) ? '-' : '+', - lmod_bytes(po, po->operand[0].lmod)); + lmod_bytes(po, po->operand[1].lmod)); fprintf(fout, " %sedi = eax;", - lmod_cast_u_ptr(po, po->operand[0].lmod)); + lmod_cast_u_ptr(po, po->operand[1].lmod)); strcpy(g_comment, "rep stos"); } else { assert_operand_cnt(2); fprintf(fout, " %sedi = eax; edi %c= %d;", - lmod_cast_u_ptr(po, po->operand[0].lmod), + lmod_cast_u_ptr(po, po->operand[1].lmod), (po->flags & OPF_DF) ? '-' : '+', - lmod_bytes(po, po->operand[0].lmod)); + lmod_bytes(po, po->operand[1].lmod)); strcpy(g_comment, "stos"); } break; @@ -5388,7 +5390,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) case OP_SCAS: // only does ZF (for now) // repe ~ repeat while ZF=1 - j = lmod_bytes(po, po->operand[0].lmod); + j = lmod_bytes(po, po->operand[1].lmod); l = (po->flags & OPF_DF) ? '-' : '+'; if (po->flags & OPF_REP) { assert_operand_cnt(3); @@ -5396,8 +5398,8 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) " for (; ecx != 0; ecx--) {\n"); fprintf(fout, " cond_z = (%seax == %sedi); edi %c= %d;\n", - lmod_cast_u(po, po->operand[0].lmod), - lmod_cast_u_ptr(po, po->operand[0].lmod), l, j); + lmod_cast_u(po, po->operand[1].lmod), + lmod_cast_u_ptr(po, po->operand[1].lmod), l, j); fprintf(fout, " if (cond_z %s 0) break;\n", (po->flags & OPF_REPZ) ? "==" : "!="); @@ -5409,8 +5411,8 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) else { assert_operand_cnt(2); fprintf(fout, " cond_z = (%seax == %sedi); edi %c= %d;", - lmod_cast_u(po, po->operand[0].lmod), - lmod_cast_u_ptr(po, po->operand[0].lmod), l, j); + lmod_cast_u(po, po->operand[1].lmod), + lmod_cast_u_ptr(po, po->operand[1].lmod), l, j); strcpy(g_comment, "scas"); } pfomask &= ~(1 << PFO_Z); @@ -5851,7 +5853,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) break; case OP_LOOP: - fprintf(fout, " if (--ecx == 0)\n"); + fprintf(fout, " if (--ecx != 0)\n"); fprintf(fout, " goto %s;", po->operand[0].name); strcat(g_comment, "loop"); break; -- 2.39.2