]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Sync x86/amd64 flag helpers with the trunk.
authorJulian Seward <jseward@acm.org>
Fri, 29 Dec 2006 05:06:51 +0000 (05:06 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 29 Dec 2006 05:06:51 +0000 (05:06 +0000)
git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_2_BRANCH@1715

VEX/priv/guest-amd64/ghelpers.c
VEX/priv/guest-x86/ghelpers.c

index 19b40ac78ce6fceb5fab15c965ffc333c5009426..a211c67f30478f5a0c85d6dbcd859b69da661d9a 100644 (file)
@@ -904,7 +904,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
          return unop(Iop_1Uto64,
                      binop(Iop_CmpEQ64,cc_dep1,cc_dep2));
       }
-
       if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNZ)) {
          /* long long sub/cmp, then NZ --> test dst!=src */
          return unop(Iop_1Uto64,
@@ -924,7 +923,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
          return unop(Iop_1Uto64,
                      binop(Iop_CmpLT64U, cc_dep1, cc_dep2));
       }
-
       if (isU64(cc_op, AMD64G_CC_OP_SUBQ) && isU64(cond, AMD64CondNB)) {
          /* long long sub/cmp, then NB (unsigned greater than or equal)
             --> test src <=u dst */
@@ -949,7 +947,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                            binop(Iop_Shl64,cc_dep1,mkU8(32)),
                            binop(Iop_Shl64,cc_dep2,mkU8(32))));
       }
-
       if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNZ)) {
          /* long sub/cmp, then NZ --> test dst!=src */
          return unop(Iop_1Uto64,
@@ -985,7 +982,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                            binop(Iop_Shl64,cc_dep1,mkU8(32)),
                            binop(Iop_Shl64,cc_dep2,mkU8(32))));
       }
-
       if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNBE)) {
          /* long sub/cmp, then NBE (unsigned greater than)
             --> test src <u dst */
@@ -1025,7 +1021,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                            unop(Iop_64to8,cc_dep1),
                            unop(Iop_64to8,cc_dep2)));
       }
-
       if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondNZ)) {
          /* byte sub/cmp, then NZ --> test dst!=src */
          return unop(Iop_1Uto64,
@@ -1049,25 +1044,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                       mkU64(1));
       }
 
-//      if (isU64(cc_op, AMD64G_CC_OP_SUBB) && isU64(cond, AMD64CondNZ)) {
-//         /* byte sub/cmp, then NZ --> test dst!=src */
-//         return unop(Iop_32Uto64,
-//                unop(Iop_1Uto32,
-//                     binop(Iop_CmpNE8, 
-//                           unop(Iop_32to8,unop(Iop_64to32,cc_dep1)),
-//                           unop(Iop_32to8,unop(Iop_64to32,cc_dep2)))));
-//      }
-
-//..       if (isU32(cc_op, AMD64G_CC_OP_SUBB) && isU32(cond, X86CondNBE)) {
-//..          /* long sub/cmp, then NBE (unsigned greater than)
-//..             --> test src <u dst */
-//..          /* Note, args are opposite way round from the usual */
-//..          return unop(Iop_1Uto32,
-//..                      binop(Iop_CmpLT32U, 
-//..                            binop(Iop_And32,cc_dep2,mkU32(0xFF)),
-//..                      binop(Iop_And32,cc_dep1,mkU32(0xFF))));
-//..       }
-
       /*---------------- LOGICQ ----------------*/
 
       if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondZ)) {
@@ -1107,11 +1083,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                            mkU64(0)));
       }
 
-//..       if (isU32(cc_op, AMD64G_CC_OP_LOGICL) && isU32(cond, X86CondS)) {
-//..          /* long and/or/xor, then S --> test dst <s 0 */
-//..          return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0)));
-//..       }
-
       if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondLE)) {
          /* long and/or/xor, then LE
             This is pretty subtle.  LOGIC sets SF and ZF according to the
@@ -1125,24 +1096,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                            mkU64(0)));
       }
 
-//..       if (isU32(cc_op, AMD64G_CC_OP_LOGICL) && isU32(cond, X86CondBE)) {
-//..          /* long and/or/xor, then BE
-//..             LOGIC sets ZF according to the result and makes CF be zero.
-//..             BE computes (CF | ZF), but CF is zero, so this reduces ZF 
-//..             -- which will be 1 iff the result is zero.  Hence ...
-//..          */
-//..          return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
-//..       }
-//.. 
-//..       /*---------------- LOGICW ----------------*/
-//.. 
-//..       if (isU32(cc_op, AMD64G_CC_OP_LOGICW) && isU32(cond, X86CondZ)) {
-//..          /* byte and/or/xor, then Z --> test dst==0 */
-//..          return unop(Iop_1Uto32,
-//..                      binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(0xFFFF)), 
-//..                                         mkU32(0)));
-//..       }
-
       /*---------------- LOGICB ----------------*/
 
       if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondZ)) {
@@ -1175,6 +1128,16 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                            mkU64(0)));
       }
 
+      /*---------------- INCW ----------------*/
+
+      if (isU64(cc_op, AMD64G_CC_OP_INCW) && isU64(cond, AMD64CondZ)) {
+         /* 16-bit inc, then Z --> test dst == 0 */
+         return unop(Iop_1Uto64,
+                     binop(Iop_CmpEQ64, 
+                           binop(Iop_Shl64,cc_dep1,mkU8(48)), 
+                           mkU64(0)));
+      }
+
       /*---------------- DECL ----------------*/
 
       if (isU64(cc_op, AMD64G_CC_OP_DECL) && isU64(cond, AMD64CondZ)) {
@@ -1195,25 +1158,6 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
                            mkU64(0)));
       }
 
-//..       /*---------------- DECL ----------------*/
-//.. 
-//..       if (isU32(cc_op, AMD64G_CC_OP_DECL) && isU32(cond, X86CondZ)) {
-//..          /* dec L, then Z --> test dst == 0 */
-//..          return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
-//..       }
-//.. 
-//..       if (isU32(cc_op, AMD64G_CC_OP_DECL) && isU32(cond, X86CondS)) {
-//..          /* dec L, then S --> compare DST <s 0 */
-//..          return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0)));
-//..       }
-//.. 
-//..       /*---------------- SHRL ----------------*/
-//.. 
-//..       if (isU32(cc_op, AMD64G_CC_OP_SHRL) && isU32(cond, X86CondZ)) {
-//..          /* SHRL, then Z --> test dep1 == 0 */
-//..          return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
-//..       }
-
       /*---------------- COPY ----------------*/
       /* This can happen, as a result of amd64 FP compares: "comisd ... ;
          jbe" for example. */
@@ -1261,6 +1205,43 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
             );
       }
 
+      if (isU64(cc_op, AMD64G_CC_OP_COPY) 
+          && (isU64(cond, AMD64CondZ) || isU64(cond, AMD64CondNZ))) {
+         /* COPY, then Z --> extract Z from dep1, and test (Z == 1). */
+         /* COPY, then NZ --> extract Z from dep1, and test (Z == 0). */
+         UInt nnn = isU64(cond, AMD64CondZ) ? 1 : 0;
+         return
+            unop(
+               Iop_1Uto64,
+               binop(
+                  Iop_CmpEQ64,
+                  binop(
+                     Iop_And64,
+                     binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_Z)),
+                     mkU64(1)
+                  ),
+                  mkU64(nnn)
+               )
+            );
+      }
+
+      if (isU64(cc_op, AMD64G_CC_OP_COPY) && isU64(cond, AMD64CondP)) {
+         /* COPY, then P --> extract P from dep1, and test (P == 1). */
+         return
+            unop(
+               Iop_1Uto64,
+               binop(
+                  Iop_CmpNE64,
+                  binop(
+                     Iop_And64,
+                     binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_P)),
+                     mkU64(1)
+                  ),
+                  mkU64(0)
+               )
+            );
+      }
+
       return NULL;
    }
 
@@ -1308,48 +1289,16 @@ IRExpr* guest_amd64_spechelper ( HChar* function_name,
          /* If the thunk is dec or inc, the cflag is supplied as CC_NDEP. */
          return cc_ndep;
       }
-//..       if (isU64(cc_op, AMD64G_CC_OP_COPY)) {
-//..          /* cflag after COPY is stored in DEP1. */
-//..          return
-//..             binop(
-//..                Iop_And64,
-//..                binop(Iop_Shr64, cc_dep1, mkU8(AMD64G_CC_SHIFT_C)),
-//..                mkU64(1)
-//..             );
-//..       }
-//.. #     if 0
-//..       if (cc_op->tag == Iex_Const) {
-//..          vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n");
-//..       }
-//.. #     endif
+
+#     if 0
+      if (cc_op->tag == Iex_Const) {
+         vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n");
+      }
+#     endif
 
       return NULL;
    }
 
-//..    /* --------- specialising "x86g_calculate_rflags_all" --------- */
-//.. 
-//..    if (vex_streq(function_name, "x86g_calculate_rflags_all")) {
-//..       /* specialise calls to above "calculate_rflags_all" function */
-//..       IRExpr *cc_op, *cc_dep1, *cc_dep2, *cc_ndep;
-//..       vassert(arity == 4);
-//..       cc_op   = args[0];
-//..       cc_dep1 = args[1];
-//..       cc_dep2 = args[2];
-//..       cc_ndep = args[3];
-//.. 
-//..       if (isU32(cc_op, AMD64G_CC_OP_COPY)) {
-//..          /* eflags after COPY are stored in DEP1. */
-//..          return
-//..             binop(
-//..                Iop_And32,
-//..                cc_dep1,
-//..                mkU32(AMD64G_CC_MASK_O | AMD64G_CC_MASK_S | AMD64G_CC_MASK_Z 
-//..                      | AMD64G_CC_MASK_A | AMD64G_CC_MASK_C | AMD64G_CC_MASK_P)
-//..             );
-//..       }
-//..       return NULL;
-//..   }
-
 #  undef unop
 #  undef binop
 #  undef mkU64
index 5ad6210aedfad89624b2e1d2542e9a175aa40872..90f4126541d83381e40734e103896f0db1dd0789 100644 (file)
@@ -832,7 +832,6 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
          return unop(Iop_1Uto32,
                      binop(Iop_CmpEQ32, cc_dep1, cc_dep2));
       }
-
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNZ)) {
          /* long sub/cmp, then NZ --> test dst!=src */
          return unop(Iop_1Uto32,
@@ -845,6 +844,14 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
          return unop(Iop_1Uto32,
                      binop(Iop_CmpLT32S, cc_dep1, cc_dep2));
       }
+      if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNL)) {
+         /* long sub/cmp, then NL (signed greater than or equal) 
+            --> test !(dst <s src) */
+         return binop(Iop_Xor32,
+                      unop(Iop_1Uto32,
+                           binop(Iop_CmpLT32S, cc_dep1, cc_dep2)),
+                      mkU32(1));
+      }
 
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondLE)) {
          /* long sub/cmp, then LE (signed less than or equal)
@@ -852,9 +859,8 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
          return unop(Iop_1Uto32,
                      binop(Iop_CmpLE32S, cc_dep1, cc_dep2));
       }
-
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNLE)) {
-         /* long sub/cmp, then LE (signed not less than or equal)
+         /* long sub/cmp, then NLE (signed not less than or equal)
             --> test dst >s src 
             --> test !(dst <=s src) */
          return binop(Iop_Xor32,
@@ -869,6 +875,14 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
          return unop(Iop_1Uto32,
                      binop(Iop_CmpLE32U, cc_dep1, cc_dep2));
       }
+      if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNBE)) {
+         /* long sub/cmp, then BE (unsigned greater than)
+            --> test !(dst <=u src) */
+         return binop(Iop_Xor32,
+                      unop(Iop_1Uto32,
+                           binop(Iop_CmpLE32U, cc_dep1, cc_dep2)),
+                      mkU32(1));
+      }
 
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondB)) {
          /* long sub/cmp, then B (unsigned less than)
@@ -876,14 +890,31 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
          return unop(Iop_1Uto32,
                      binop(Iop_CmpLT32U, cc_dep1, cc_dep2));
       }
+      if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNB)) {
+         /* long sub/cmp, then NB (unsigned greater than or equal)
+            --> test !(dst <u src) */
+         return binop(Iop_Xor32,
+                      unop(Iop_1Uto32,
+                           binop(Iop_CmpLT32U, cc_dep1, cc_dep2)),
+                      mkU32(1));
+      }
 
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondS)) {
-         /* long sub/cmp, then S --> test (dst-src <s 0) */
+         /* long sub/cmp, then S (negative) --> test (dst-src <s 0) */
          return unop(Iop_1Uto32,
                      binop(Iop_CmpLT32S, 
                            binop(Iop_Sub32, cc_dep1, cc_dep2),
                            mkU32(0)));
       }
+      if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNS)) {
+         /* long sub/cmp, then NS (not negative) --> test !(dst-src <s 0) */
+         return binop(Iop_Xor32,
+                      unop(Iop_1Uto32,
+                           binop(Iop_CmpLT32S, 
+                                 binop(Iop_Sub32, cc_dep1, cc_dep2),
+                                 mkU32(0))),
+                      mkU32(1));
+      }
 
       /*---------------- SUBW ----------------*/
 
@@ -904,7 +935,6 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
                            unop(Iop_32to8,cc_dep1), 
                            unop(Iop_32to8,cc_dep2)));
       }
-
       if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNZ)) {
          /* byte sub/cmp, then NZ --> test dst!=src */
          return unop(Iop_1Uto32,
@@ -944,7 +974,6 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
          /* long and/or/xor, then Z --> test dst==0 */
          return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
       }
-
       if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondNZ)) {
          /* long and/or/xor, then NZ --> test dst!=0 */
          return unop(Iop_1Uto32,binop(Iop_CmpNE32, cc_dep1, mkU32(0)));
@@ -1002,17 +1031,6 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
                       binop(Iop_Shr32,cc_dep1,mkU8(15)),
                       mkU32(1));
       }
-      //Probably correct, but no test case for it yet found
-      //if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondNS)) {
-      //   /* see comment below for (LOGICB, CondNS) */
-      //   /* word and/or/xor, then S --> (UInt) ~ result[15] */
-      //   vassert(0+0);
-      //   return binop(Iop_Xor32,
-      //          binop(Iop_And32,
-      //                binop(Iop_Shr32,cc_dep1,mkU8(15)),
-      //                mkU32(1)),
-      //          mkU32(1));
-      //}
 
       /*---------------- LOGICB ----------------*/
 
@@ -1022,7 +1040,6 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
                      binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(255)), 
                                         mkU32(0)));
       }
-
       if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNZ)) {
          /* byte and/or/xor, then Z --> test dst!=0 */
          /* b9ac9:       84 c0                   test   %al,%al
@@ -1100,10 +1117,10 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
 
       if (isU32(cc_op, X86G_CC_OP_COPY) && 
           (isU32(cond, X86CondBE) || isU32(cond, X86CondNBE))) {
-         /* COPY, then BE --> extract C and Z from dep1, and test (C
-            or Z == 1). */
-         /* COPY, then NBE --> extract C and Z from dep1, and test (C
-            or Z == 0). */
+         /* COPY, then BE --> extract C and Z from dep1, and test 
+            (C or Z) == 1. */
+         /* COPY, then NBE --> extract C and Z from dep1, and test
+            (C or Z) == 0. */
          UInt nnn = isU32(cond, X86CondBE) ? 1 : 0;
          return
             unop(
@@ -1124,8 +1141,8 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
             );
       }
       
-      if (isU32(cc_op, X86G_CC_OP_COPY) && 
-          (isU32(cond, X86CondB) || isU32(cond, X86CondNB))) {
+      if (isU32(cc_op, X86G_CC_OP_COPY) 
+          && (isU32(cond, X86CondB) || isU32(cond, X86CondNB))) {
          /* COPY, then B --> extract C from dep1, and test (C == 1). */
          /* COPY, then NB --> extract C from dep1, and test (C == 0). */
          UInt nnn = isU32(cond, X86CondB) ? 1 : 0;
@@ -1144,36 +1161,42 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
             );
       }
 
-      if (isU32(cc_op, X86G_CC_OP_COPY) && isU32(cond, X86CondZ)) {
+      if (isU32(cc_op, X86G_CC_OP_COPY) 
+          && (isU32(cond, X86CondZ) || isU32(cond, X86CondNZ))) {
          /* COPY, then Z --> extract Z from dep1, and test (Z == 1). */
+         /* COPY, then NZ --> extract Z from dep1, and test (Z == 0). */
+         UInt nnn = isU32(cond, X86CondZ) ? 1 : 0;
          return
             unop(
                Iop_1Uto32,
                binop(
-                  Iop_CmpNE32,
+                  Iop_CmpEQ32,
                   binop(
                      Iop_And32,
                      binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z)),
                      mkU32(1)
                   ),
-                  mkU32(0)
+                  mkU32(nnn)
                )
             );
       }
 
-      if (isU32(cc_op, X86G_CC_OP_COPY) && isU32(cond, X86CondP)) {
+      if (isU32(cc_op, X86G_CC_OP_COPY) 
+          && (isU32(cond, X86CondP) || isU32(cond, X86CondNP))) {
          /* COPY, then P --> extract P from dep1, and test (P == 1). */
+         /* COPY, then NP --> extract P from dep1, and test (P == 0). */
+         UInt nnn = isU32(cond, X86CondP) ? 1 : 0;
          return
             unop(
                Iop_1Uto32,
                binop(
-                  Iop_CmpNE32,
+                  Iop_CmpEQ32,
                   binop(
                      Iop_And32,
                      binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_P)),
                      mkU32(1)
                   ),
-                  mkU32(0)
+                  mkU32(nnn)
                )
             );
       }
@@ -1223,6 +1246,13 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
                mkU32(1)
             );
       }
+      if (isU32(cc_op, X86G_CC_OP_ADDL)) {
+         /* C after add denotes sum <u either arg */
+         return unop(Iop_1Uto32,
+                     binop(Iop_CmpLT32U, 
+                           binop(Iop_Add32, cc_dep1, cc_dep2), 
+                           cc_dep1));
+      }
 #     if 0
       if (cc_op->tag == Iex_Const) {
          vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n");