]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
x86: handle divw/idivw. Needs proper testing.
authorJulian Seward <jseward@acm.org>
Sat, 11 Sep 2004 19:43:51 +0000 (19:43 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 11 Sep 2004 19:43:51 +0000 (19:43 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@259

VEX/priv/guest-x86/toIR.c
VEX/priv/host-x86/isel.c
VEX/priv/ir/irdefs.c
VEX/pub/libvex_ir.h

index 79edaa7dc5e1b11242941ec0814956a1a2e6f9ff..53c8bf5031b99fd222adecab38e765d1520ae492 100644 (file)
@@ -11,6 +11,7 @@
    is Iop_Neg* used?
    MOVAPS fix (vg_to_ucode rev 1.143)
    check flag settings for cmpxchg
+   check 16/8 bit div/idiv
    FUCOMI(P): what happens to A and S flags?  Currently are forced
       to zero.
 */
@@ -1999,17 +2000,27 @@ UInt dis_movx_E_G ( UChar       sorb,
 static
 void codegen_div ( Int sz, IRTemp t, Bool signed_divide )
 {
+   IROp   op    = signed_divide ? Iop_DivModS64to32 : Iop_DivModU64to32;
+   IRTemp src64 = newTemp(Ity_I64);
+   IRTemp dst64 = newTemp(Ity_I64);
    switch (sz) {
-      case 4: {
-         IROp   op    = signed_divide ? Iop_DivModS64to32 : Iop_DivModU64to32;
-         IRTemp src64 = newTemp(Ity_I64);
-         IRTemp dst64 = newTemp(Ity_I64);
+      case 4:
          assign( src64, binop(Iop_32HLto64, 
-                 getIReg(4,R_EDX), getIReg(4,R_EAX)) );
+                              getIReg(4,R_EDX), getIReg(4,R_EAX)) );
          assign( dst64, binop(op, mkexpr(src64), mkexpr(t)) );
          putIReg( 4, R_EAX, unop(Iop_64to32,mkexpr(dst64)) );
          putIReg( 4, R_EDX, unop(Iop_64HIto32,mkexpr(dst64)) );
          break;
+      case 2: {
+         IROp widen3264 = signed_divide ? Iop_32Sto64 : Iop_32Uto64;
+         IROp widen1632 = signed_divide ? Iop_16Sto32 : Iop_16Uto32;
+         assign( src64, unop(widen3264,
+                             binop(Iop_16HLto32, 
+                                   getIReg(2,R_EDX), getIReg(2,R_EAX))) );
+         assign( dst64, binop(op, mkexpr(src64), unop(widen1632,mkexpr(t))) );
+         putIReg( 2, R_EAX, unop(Iop_32to16,unop(Iop_64to32,mkexpr(dst64))) );
+         putIReg( 2, R_EDX, unop(Iop_32to16,unop(Iop_64HIto32,mkexpr(dst64))) );
+         break;
       }
       default: vpanic("codegen_div(x86)");
    }
index 509200160282a6397d8d26bbf6498119dc1a57f6..eb406cb3c589f6c93664c7b21014e620e536b260 100644 (file)
@@ -1305,6 +1305,19 @@ static void iselIntExpr64_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
       return;
    }
 
+   /* 32Uto64(e) */
+   if (e->tag == Iex_Unop
+       && e->Iex.Unop.op == Iop_32Uto64) {
+      HReg tLo = newVRegI(env);
+      HReg tHi = newVRegI(env);
+      HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
+      addInstr(env, mk_MOVsd_RR(src,tLo));
+      addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(0), tHi));
+      *rHi = tHi;
+      *rLo = tLo;
+      return;
+   }
+
    /* 64-bit shifts */
    if (e->tag == Iex_Binop
        && e->Iex.Binop.op == Iop_Shl64) {
index 1b369a1505aac41b22e3160ac49fdb2605525f06..0549ced43954e4c2dc5b54dff222b59f023ca113 100644 (file)
@@ -94,6 +94,7 @@ void ppIROp ( IROp op )
       case Iop_8Sto32:   vex_printf("8Sto32");  return;
       case Iop_16Sto32:  vex_printf("16Sto32"); return;
       case Iop_32Sto64:  vex_printf("32Sto64"); return;
+      case Iop_32Uto64:  vex_printf("32Uto64"); return;
       case Iop_32to8:    vex_printf("32to8");   return;
       case Iop_32to1:    vex_printf("32to1");   return;
       case Iop_1Uto8:    vex_printf("1Uto8");   return;
@@ -636,6 +637,7 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 )
       case Iop_16Uto32: UNARY(Ity_I32,Ity_I16);
       case Iop_16Sto32: UNARY(Ity_I32,Ity_I16);
       case Iop_32Sto64: UNARY(Ity_I64,Ity_I32);
+      case Iop_32Uto64: UNARY(Ity_I64,Ity_I32);
       case Iop_32to8:   UNARY(Ity_I8,Ity_I32);
 
       case Iop_PRemF64:
index 60487245e850233f061768740032c5b3316a17ce..6d78e05c27f372f42385765795ea685aafc659e7 100644 (file)
@@ -136,7 +136,7 @@ typedef
                          // of which lo half is div and hi half is mod
       Iop_DivModS64to32, // ditto, signed
       /* Widening conversions */
-      Iop_8Uto16, Iop_8Uto32, Iop_16Uto32,
+      Iop_8Uto16, Iop_8Uto32, Iop_16Uto32, Iop_32Uto64,
       Iop_8Sto16, Iop_8Sto32, Iop_16Sto32, Iop_32Sto64,
       /* Narrowing conversions */
       Iop_32to8,