translate: some bugfixes
authornotaz <notasas@gmail.com>
Wed, 1 Apr 2015 20:53:26 +0000 (23:53 +0300)
committernotaz <notasas@gmail.com>
Wed, 1 Apr 2015 20:53:26 +0000 (23:53 +0300)
run_imp.sh
tests/Makefile
tests/ops.asm [new file with mode: 0644]
tests/ops.expect.c [new file with mode: 0644]
tests/ops.seed.h [new file with mode: 0644]
tools/translate.c

index 665b3f9..15381b7 100755 (executable)
@@ -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
 
index 360c2e6..8d81519 100644 (file)
@@ -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 (file)
index 0000000..472a024
--- /dev/null
@@ -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 (file)
index 0000000..3b59db1
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
index 1bdc884..ae90107 100644 (file)
@@ -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;