]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
x86toIR: reorganise multiply stuff, and make a start on division stuff
authorJulian Seward <jseward@acm.org>
Wed, 14 Jul 2004 01:39:17 +0000 (01:39 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 14 Jul 2004 01:39:17 +0000 (01:39 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@81

VEX/priv/guest-x86/x86toIR.c
VEX/priv/ir/ir_defs.c
VEX/pub/libvex_ir.h

index 98a611a6abd1c65c86d822828b281539c0c19703..d9626fefad1d271accfa327a07ac8428ff8e9460 100644 (file)
@@ -1784,12 +1784,27 @@ UInt dis_movx_E_G ( UChar       sorb,
    }
 }
 
-//-- 
-//-- /* Generate code to divide ArchRegs EDX:EAX / DX:AX / AX by the 32 /
-//--    16 / 8 bit quantity in the given TempReg.  */
-//-- static
-//-- void codegen_div ( UCodeBlock* cb, Int sz, Int t, Bool signed_divide )
-//-- {
+
+/* Generate code to divide ArchRegs EDX:EAX / DX:AX / AX by the 32 /
+   16 / 8 bit quantity in the given IRTemp.  */
+static
+void codegen_div ( Int sz, IRTemp t, Bool signed_divide )
+{
+   switch (sz) {
+      case 4: {
+         IROp   op    = signed_divide ? Iop_DivModS64to32 : Iop_DivModU64to32;
+         IRTemp src64 = newTemp(Ity_I64);
+         IRTemp dst64 = newTemp(Ity_I64);
+         assign( src64, binop(Iop_32HLto64, 
+                 getIReg(4,R_EDX), getIReg(4,R_EAX)) );
+         assign( dst64, binop(op, mkexpr(src64), mkexpr(t)) );
+         putIReg( 4, R_EAX, unop(Iop_64LOto32,mkexpr(dst64)) );
+         putIReg( 4, R_EDX, unop(Iop_64HIto32,mkexpr(dst64)) );
+         break;
+      }
+      default: vpanic("codegen_div(x86)");
+   }
+}
 //--    Int  helper;
 //--    Int  ta = newTemp(cb);
 //--    Int  td = newTemp(cb);
@@ -2133,7 +2148,6 @@ static void codegen_mul_A_D_Reg ( Int sz,
    IRType ty = szToITy(sz);
    IRTemp t1 = newTemp(ty);
    IRTemp t2 = newTemp(ty);
-   IRTemp tr = newTemp(ty);
 
 //--    uInstr0(cb, CALLM_S, 0);
 //--    uInstr2(cb, GET,   sz, ArchReg, eregOfRM(modrm), TempReg, t1);
@@ -2142,14 +2156,13 @@ static void codegen_mul_A_D_Reg ( Int sz,
 
    switch (ty) {
    case Ity_I32: {
-      IROp   hiOp   = signed_multiply ? Iop_MullS32_hi32 : Iop_MullU32_hi32;
-      IRTemp trHi32 = newTemp(Ity_I32);
-      setFlags_MUL ( Ity_I32, t1, t2, 
-                     signed_multiply ? CC_OP_MULLSB : CC_OP_MULLUB );
-      assign( tr,     binop(Iop_Mul32, mkexpr(t1), mkexpr(t2) ) );
-      assign( trHi32, binop(hiOp,  mkexpr(t1), mkexpr(t2) ) );
-      putIReg(4, R_EAX, mkexpr(tr));
-      putIReg(4, R_EDX, mkexpr(trHi32));
+      IRTemp res64   = newTemp(Ity_I64);
+      IROp   mulOp   = signed_multiply ? Iop_MullS32 : Iop_MullU32;
+      UInt   thunkOp = signed_multiply ? CC_OP_MULLSB : CC_OP_MULLUB;
+      setFlags_MUL ( Ity_I32, t1, t2, thunkOp );
+      assign( res64, binop(mulOp, mkexpr(t1), mkexpr(t2)) );
+      putIReg(4, R_EDX, unop(Iop_64HIto32,mkexpr(res64)));
+      putIReg(4, R_EAX, unop(Iop_64LOto32,mkexpr(res64)));
       break;
    }
    default:
@@ -2327,10 +2340,10 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta )
 //--          case 5: /* IMUL */
 //--             codegen_mul_A_D_Temp ( cb, sz, t1, True, dis_buf );
 //--             break;
-//--          case 6: /* DIV */
-//--             codegen_div ( cb, sz, t1, False );
-//--             DIP("div%c %s\n", nameISize(sz), dis_buf);
-//--             break;
+         case 6: /* DIV */
+            codegen_div ( sz, t1, False );
+            DIP("div%c %s\n", nameISize(sz), dis_buf);
+            break;
 //--          case 7: /* IDIV */
 //--             codegen_div ( cb, sz, t1, True );
 //--             DIP("idiv%c %s\n", nameISize(sz), dis_buf);
index 6defc2e93e5c86afc5415016fc0a4ec6f1d78686..1f72e34621ad792244673e8a192a13d21e9dff54 100644 (file)
@@ -79,21 +79,30 @@ void ppIROp ( IROp op )
       case Iop_Not8 ... Iop_Not64:
          str = "Not"; base = Iop_Not8; break;
       /* other cases must explicitly "return;" */
-      case Iop_8Uto16:  vex_printf("8Uto16");  return;
-      case Iop_8Uto32:  vex_printf("8Uto32");  return;
-      case Iop_16Uto32: vex_printf("16Uto32"); return;
-      case Iop_8Sto16:  vex_printf("8Sto16");  return;
-      case Iop_8Sto32:  vex_printf("8Sto32");  return;
-      case Iop_16Sto32: vex_printf("16Sto32"); return;
-      case Iop_32to1:   vex_printf("32to1");   return;
-      case Iop_1Uto8:   vex_printf("1Uto8");   return;
-      case Iop_MullS8:  vex_printf("MullS8");  return;
-      case Iop_MullS16: vex_printf("MullS16"); return;
-      case Iop_MullS32_hi32: vex_printf("MullS32_hi32"); return;
-      case Iop_MullU8:       vex_printf("MullU8");       return;
-      case Iop_MullU16:      vex_printf("MullU16");      return;
-      case Iop_MullU32_hi32: vex_printf("MullU32_hi32"); return;
-      default:        vpanic("ppIROp(1)");
+      case Iop_8Uto16:   vex_printf("8Uto16");  return;
+      case Iop_8Uto32:   vex_printf("8Uto32");  return;
+      case Iop_16Uto32:  vex_printf("16Uto32"); return;
+      case Iop_8Sto16:   vex_printf("8Sto16");  return;
+      case Iop_8Sto32:   vex_printf("8Sto32");  return;
+      case Iop_16Sto32:  vex_printf("16Sto32"); return;
+      case Iop_32to1:    vex_printf("32to1");   return;
+      case Iop_1Uto8:    vex_printf("1Uto8");   return;
+
+      case Iop_MullS8:   vex_printf("MullS8");  return;
+      case Iop_MullS16:  vex_printf("MullS16"); return;
+      case Iop_MullS32:  vex_printf("MullS32"); return;
+      case Iop_MullU8:   vex_printf("MullU8");  return;
+      case Iop_MullU16:  vex_printf("MullU16"); return;
+      case Iop_MullU32:  vex_printf("MullU32"); return;
+
+      case Iop_DivModU64to32: vex_printf("DivModU64to32"); return;
+      case Iop_DivModS64to32: vex_printf("DivModS64to32"); return;
+
+      case Iop_64HIto32: vex_printf("64HIto32"); return;
+      case Iop_64LOto32: vex_printf("64LOto32"); return;
+      case Iop_32HLto64: vex_printf("32HLto64"); return;
+
+      default:           vpanic("ppIROp(1)");
    }
   
    switch (op - base) {
index 72e2238cc6764d9e7af2df7ba42c048a41074d49..ef3ff2bb383fe777e63d74c5d3e3677eafe4c51a 100644 (file)
@@ -86,12 +86,21 @@ typedef
       /* Tags for unary ops */
       Iop_Not8,  Iop_Not16,  Iop_Not32,  Iop_Not64,
       Iop_Neg8,  Iop_Neg16,  Iop_Neg32,  Iop_Neg64,
-      /* Conversions */
+      /* Widening multiplies */
+      Iop_MullS8, Iop_MullS16, Iop_MullS32,
+      Iop_MullU8, Iop_MullU16, Iop_MullU32,
+      /* Ordering not important after here. */
+      /* Division */
+      Iop_DivModU64to32, // :: I64,I32 -> I64
+                         // of which lo half is div and hi half is mod
+      Iop_DivModS64to32, // ditto, signed
+      /* Widening conversions */
       Iop_8Uto16, Iop_8Uto32, Iop_16Uto32,
       Iop_8Sto16, Iop_8Sto32, Iop_16Sto32,
-      /* Widening multiplies */
-      Iop_MullS8, Iop_MullS16, Iop_MullS32_hi32,
-      Iop_MullU8, Iop_MullU16, Iop_MullU32_hi32,
+      /* 32 <-> 64 bit conversions */
+      Iop_64LOto32,   // :: I64 -> I32, low half
+      Iop_64HIto32,   // :: I64 -> I32, high half
+      Iop_32HLto64,   // :: (I32,I32) -> I64
       /* 1-bit stuff */
       Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */
       Iop_1Uto8  /* :: Ity_Bit -> Ity_I8, unsigned widen */