]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Rehash handling of multiply insns in the x86 front end, so as to make
authorJulian Seward <jseward@acm.org>
Fri, 30 Jul 2004 01:52:45 +0000 (01:52 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 30 Jul 2004 01:52:45 +0000 (01:52 +0000)
the flags work right.

git-svn-id: svn://svn.valgrind.org/vex/trunk@160

VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c

index b86a392f95ab45cbf657f7a0070fb53f75e9ebaa..808e9a3142fde6ad3ca64f77e23741788045644f 100644 (file)
@@ -92,17 +92,13 @@ enum {
     CC_OP_RORW,
     CC_OP_RORL, /* 33 */
 
-    CC_OP_MULB, /* modify all flags, CC_DST = one arg */
-    CC_OP_MULW, /* CC_SRC = the other arg */
-    CC_OP_MULL, /* 36 */
+    CC_OP_UMULB, /* modify all flags, CC_DST = one arg */
+    CC_OP_UMULW, /* CC_SRC = the other arg */
+    CC_OP_UMULL, /* 36 */
 
-    CC_OP_MULLSB, /* modify all flags, CC_DST = one arg */
-    CC_OP_MULLSW, /* CC_SRC = the other arg */
-    CC_OP_MULLSL, /* 39 */
-
-    CC_OP_MULLUB, /* modify all flags, CC_DST = one arg */
-    CC_OP_MULLUW, /* CC_SRC = the other arg */
-    CC_OP_MULLUL, /* 42 */
+    CC_OP_SMULB, /* modify all flags, CC_DST = one arg */
+    CC_OP_SMULW, /* CC_SRC = the other arg */
+    CC_OP_SMULL, /* 39 */
 
     CC_OP_NUMBER
 };
index 6df69f6bdf295d18a39fde6b72a3f0c0ac217e85..9ab4beb5b81c3b092a85acff26ac03643b0ac05a 100644 (file)
@@ -256,17 +256,38 @@ static inline int lshift(int x, int n)
     return fl;                                                 \
 }
 
-#define ACTIONS_MUL(DATA_BITS,DATA_UTYPE,DATA_S2TYPE)                  \
+#define ACTIONS_SMUL(DATA_BITS,DATA_STYPE,DATA_S2TYPE)                 \
 {                                                                      \
     PREAMBLE(DATA_BITS);                                               \
     int cf, pf, af, zf, sf, of;                                                \
-    DATA_UTYPE  r  = ((DATA_UTYPE)CC_SRC)  * ((DATA_UTYPE)CC_DST);     \
-    DATA_S2TYPE rr = ((DATA_S2TYPE)CC_SRC) * ((DATA_S2TYPE)CC_DST);    \
-    cf = (r == (DATA_UTYPE)(rr >>/*signed*/ DATA_BITS));               \
-    pf = parity_table[(uint8_t)r];                                     \
+    DATA_STYPE  hi;                                                     \
+    DATA_STYPE  lo = ((DATA_STYPE)CC_SRC) * ((DATA_STYPE)CC_DST);       \
+    DATA_S2TYPE rr = ((DATA_S2TYPE)((DATA_STYPE)CC_SRC))                \
+                     * ((DATA_S2TYPE)((DATA_STYPE)CC_DST));            \
+    hi = (DATA_STYPE)(rr >>/*s*/ DATA_BITS);                           \
+    cf = (hi != (lo >>/*s*/ (DATA_BITS-1)));                            \
+    pf = parity_table[(uint8_t)lo];                                    \
     af = 0; /* undefined */                                            \
-    zf = (r == 0) << 6;                                                        \
-    sf = lshift(r, 8 - DATA_BITS) & 0x80;                              \
+    zf = (lo == 0) << 6;                                               \
+    sf = lshift(lo, 8 - DATA_BITS) & 0x80;                             \
+    of = cf << 11;                                                     \
+    return cf | pf | af | zf | sf | of;                                        \
+}
+
+#define ACTIONS_UMUL(DATA_BITS,DATA_UTYPE,DATA_U2TYPE)                 \
+{                                                                      \
+    PREAMBLE(DATA_BITS);                                               \
+    int cf, pf, af, zf, sf, of;                                                \
+    DATA_UTYPE  hi;                                                     \
+    DATA_UTYPE  lo = ((DATA_UTYPE)CC_SRC) * ((DATA_UTYPE)CC_DST);       \
+    DATA_U2TYPE rr = ((DATA_U2TYPE)((DATA_UTYPE)CC_SRC))                \
+                     * ((DATA_U2TYPE)((DATA_UTYPE)CC_DST));             \
+    hi = (DATA_UTYPE)(rr >>/*u*/ DATA_BITS);                           \
+    cf = (hi != 0);                                                     \
+    pf = parity_table[(uint8_t)lo];                                    \
+    af = 0; /* undefined */                                            \
+    zf = (lo == 0) << 6;                                               \
+    sf = lshift(lo, 8 - DATA_BITS) & 0x80;                             \
     of = cf << 11;                                                     \
     return cf | pf | af | zf | sf | of;                                        \
 }
@@ -324,7 +345,9 @@ static inline int lshift(int x, int n)
       case CC_OP_RORW:   ACTIONS_ROR( 16, UShort );
       case CC_OP_RORL:   ACTIONS_ROR( 32, UInt   );
 
-      case CC_OP_MULL:   ACTIONS_MUL( 32, UInt, Long );
+      case CC_OP_UMULL:  ACTIONS_UMUL( 32, UInt, ULong );
+
+      case CC_OP_SMULL:  ACTIONS_SMUL( 32, Int,  Long );
 
       default:
          /* shouldn't really make these calls from generated code */
index 770590b1f803092f36796a0a99754272da5aee2c..0830474b57ec5d7f61732816e40860f88c2436b1 100644 (file)
@@ -653,6 +653,10 @@ static IRExpr* calculate_condition ( Condcode cond )
                                  : mk_calculate_eflags_all() );
  
    switch (cond) {
+      case CondNO:
+      case CondO: /* OF == 1 */
+         e = flag_to_bit0( CC_MASK_O, eflags );
+         break;
       case CondNZ:
       case CondZ: /* ZF == 1 */
          e = flag_to_bit0( CC_MASK_Z, eflags );
@@ -671,6 +675,7 @@ static IRExpr* calculate_condition ( Condcode cond )
       case CondS: /* SF == 1 */
          e = flag_to_bit0( CC_MASK_S, eflags );
          break;
+      case CondNP:
       case CondP: /* PF == 1 */
          e = flag_to_bit0( CC_MASK_P, eflags );
          break;
@@ -2457,13 +2462,25 @@ static void codegen_mulL_A_D ( Int sz, Bool syned,
    case Ity_I32: {
       IRTemp res64   = newTemp(Ity_I64);
       IROp   mulOp   = syned ? Iop_MullS32 : Iop_MullU32;
-      UInt   thunkOp = syned ? CC_OP_MULLSB : CC_OP_MULLUB;
+      UInt   thunkOp = syned ? CC_OP_SMULB : CC_OP_UMULB;
       setFlags_MUL ( Ity_I32, t1, tmp, thunkOp );
       assign( res64, binop(mulOp, mkexpr(t1), mkexpr(tmp)) );
       putIReg(4, R_EDX, unop(Iop_64HIto32,mkexpr(res64)));
       putIReg(4, R_EAX, unop(Iop_64to32,mkexpr(res64)));
       break;
    }
+#if 0
+   case Ity_I16: {
+      IRTemp res32   = newTemp(Ity_I32);
+      IROp   mulOp   = syned ? Iop_MullS16 : Iop_MullU16;
+      UInt   thunkOp = syned ? CC_OP_MULLSB : CC_OP_MULLUB;
+      setFlags_MUL ( Ity_I16, t1, tmp, thunkOp );
+      assign( res32, binop(mulOp, mkexpr(t1), mkexpr(tmp)) );
+      putIReg(2, R_EDX, unop(Iop_32HIto16,mkexpr(res32)));
+      putIReg(2, R_EAX, unop(Iop_32to16,mkexpr(res32)));
+      break;
+   }
+#endif
    default:
       vpanic("codegen_mulL_A_D(x86)");
    }
@@ -2964,7 +2981,7 @@ static
 UInt dis_mul_E_G ( UChar       sorb,
                    Int         size, 
                    UInt        delta0,
-                   Bool        signed_multiply )
+                   Bool        syned )
 {
    Int    alen;
    UChar  dis_buf[50];
@@ -2973,17 +2990,17 @@ UInt dis_mul_E_G ( UChar       sorb,
    IRTemp te = newTemp(ty);
    IRTemp tg = newTemp(ty);
 
-   vassert(signed_multiply);
+   vassert(syned);
 
    if (epartIsReg(rm)) {
       assign( tg, getIReg(size, gregOfRM(rm)) );
       assign( te, getIReg(size, eregOfRM(rm)) );
-      setFlags_MUL ( ty, te, tg, CC_OP_MULB );
+      setFlags_MUL ( ty, te, tg, syned ? CC_OP_SMULB : CC_OP_UMULB );
       putIReg(size, gregOfRM(rm), 
              binop(mkSizedOp(ty,Iop_Mul8),
                    mkexpr(te), mkexpr(tg)));
 
-      DIP("%smul%c %s, %s\n", signed_multiply ? "i" : "",
+      DIP("%smul%c %s, %s\n", syned ? "i" : "",
                               nameISize(size), 
                               nameIReg(size,eregOfRM(rm)),
                               nameIReg(size,gregOfRM(rm)));
@@ -2992,12 +3009,12 @@ UInt dis_mul_E_G ( UChar       sorb,
       IRTemp addr = disAMode( &alen, sorb, delta0, dis_buf );
       assign( tg, getIReg(size, gregOfRM(rm)) );
       assign( te, loadLE(ty,mkexpr(addr)) );
-      setFlags_MUL ( ty, te, tg, CC_OP_MULB );
+      setFlags_MUL ( ty, te, tg, syned ? CC_OP_SMULB : CC_OP_UMULB );
       putIReg(size, gregOfRM(rm), 
              binop(mkSizedOp(ty,Iop_Mul8),
                    mkexpr(te), mkexpr(tg)));
 
-      DIP("%smul%c %s, %s\n", signed_multiply ? "i" : "",
+      DIP("%smul%c %s, %s\n", syned ? "i" : "",
                               nameISize(size), 
                               dis_buf, nameIReg(size,gregOfRM(rm)));
       return alen+delta0;
@@ -3036,7 +3053,7 @@ UInt dis_imul_I_E_G ( UChar       sorb,
    delta += litsize;
 
    assign(tl, mkU(ty,d32));
-   setFlags_MUL ( ty, te, tl, CC_OP_MULB );
+   setFlags_MUL ( ty, te, tl, CC_OP_SMULB );
    putIReg(size, gregOfRM(rm), 
            binop(mkSizedOp(ty,Iop_Mul8),
                  mkexpr(te), mkexpr(tl)));