]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix various front-end anomalies found by the amd64 test program.
authorJulian Seward <jseward@acm.org>
Sat, 19 Feb 2005 22:47:41 +0000 (22:47 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 19 Feb 2005 22:47:41 +0000 (22:47 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@932

VEX/priv/guest-amd64/toIR.c
VEX/priv/host-amd64/isel.c
VEX/priv/ir/irdefs.c

index c089a19d7ada1d8cdfff40ff4aee50b246949083..2e409463ebb3f50f39e5f9322bf73f9f4fb902ca 100644 (file)
@@ -3492,8 +3492,10 @@ ULong dis_Grp5 ( Prefix pfx, Int sz, ULong delta, DisResult* whatNext )
                        nameIRegB(pfx, sz, eregOfRM(modrm)));
    } else {
       addr = disAMode ( &len, pfx, delta, dis_buf, 0 );
-      if (gregOfRM(modrm) != 2 && gregOfRM(modrm) != 4)
+      if (gregOfRM(modrm) != 2 && gregOfRM(modrm) != 4
+                               && gregOfRM(modrm) != 6) {
          assign(t1, loadLE(ty,mkexpr(addr)));
+      }
       switch (gregOfRM(modrm)) {
          case 0: /* INC */ 
             t2 = newTemp(ty);
@@ -3537,12 +3539,17 @@ ULong dis_Grp5 ( Prefix pfx, Int sz, ULong delta, DisResult* whatNext )
             /* There is no encoding for 32-bit operand size; hence ... */
             if (sz == 4) sz = 8;
             vassert(sz == 8 || sz == 2);
-            if (sz != 8) goto unhandled; /* awaiting test case */
-            t2 = newTemp(Ity_I64);
-            assign( t2, binop(Iop_Sub64,getIReg64(R_RSP),mkU64(sz)) );
-            putIReg64(R_RSP, mkexpr(t2) );
-            storeLE( mkexpr(t2), mkexpr(t1) );
-            break;
+            if (sz == 8) {
+               t3 = newTemp(Ity_I64);
+               assign(t3, loadLE(Ity_I64,mkexpr(addr)));
+               t2 = newTemp(Ity_I64);
+               assign( t2, binop(Iop_Sub64,getIReg64(R_RSP),mkU64(sz)) );
+               putIReg64(R_RSP, mkexpr(t2) );
+               storeLE( mkexpr(t2), mkexpr(t3) );
+               break;
+           } else {
+               goto unhandled; /* awaiting test case */
+           }
          default: 
          unhandled:
             vex_printf(
@@ -3580,43 +3587,35 @@ void dis_string_op_increment ( Int sz, IRTemp t_inc )
    }
 }
 
-//.. static
-//.. void dis_string_op( void (*dis_OP)( Int, IRTemp ), 
-//..                     Int sz, Char* name, UChar sorb )
-//.. {
-//..    IRTemp t_inc = newTemp(Ity_I32);
-//..    vassert(sorb == 0);
-//..    dis_string_op_increment(sz, t_inc);
-//..    dis_OP( sz, t_inc );
-//..    DIP("%s%c\n", name, nameISize(sz));
-//.. }
-//.. 
-//.. static 
-//.. void dis_MOVS ( Int sz, IRTemp t_inc )
-//.. {
-//..    IRType ty = szToITy(sz);
-//..    //IRTemp tv = newTemp(ty);        /* value being copied */
-//..    IRTemp td = newTemp(Ity_I32);   /* EDI */
-//..    IRTemp ts = newTemp(Ity_I32);   /* ESI */
-//.. 
-//..    //uInstr2(cb, GET,   4, ArchReg, R_EDI, TempReg, td);
-//..    //uInstr2(cb, GET,   4, ArchReg, R_ESI, TempReg, ts);
-//..    assign( td, getIReg(4, R_EDI) );
-//..    assign( ts, getIReg(4, R_ESI) );
-//.. 
-//..    //uInstr2(cb, LOAD, sz, TempReg, ts,    TempReg, tv);
-//..    //uInstr2(cb, STORE,sz, TempReg, tv,    TempReg, td);
-//..    storeLE( mkexpr(td), loadLE(ty,mkexpr(ts)) );
-//.. 
-//..    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, td);
-//..    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, ts);
-//.. 
-//..    //uInstr2(cb, PUT,   4, TempReg, td,    ArchReg, R_EDI);
-//..    //uInstr2(cb, PUT,   4, TempReg, ts,    ArchReg, R_ESI);
-//..    putIReg( 4, R_EDI, binop(Iop_Add32, mkexpr(td), mkexpr(t_inc)) );
-//..    putIReg( 4, R_ESI, binop(Iop_Add32, mkexpr(ts), mkexpr(t_inc)) );
-//.. }
-//.. 
+static
+void dis_string_op( void (*dis_OP)( Int, IRTemp ), 
+                    Int sz, HChar* name, Prefix pfx )
+{
+   IRTemp t_inc = newTemp(Ity_I64);
+   /* Really we ought to inspect the override prefixes, but we don't.
+      The following assertion catches any resulting sillyness. */
+   vassert(pfx == clearSegBits(pfx));
+   dis_string_op_increment(sz, t_inc);
+   dis_OP( sz, t_inc );
+   DIP("%s%c\n", name, nameISize(sz));
+}
+
+static 
+void dis_MOVS ( Int sz, IRTemp t_inc )
+{
+   IRType ty = szToITy(sz);
+   IRTemp td = newTemp(Ity_I64);   /* RDI */
+   IRTemp ts = newTemp(Ity_I64);   /* RSI */
+
+   assign( td, getIReg64(R_RDI) );
+   assign( ts, getIReg64(R_RSI) );
+
+   storeLE( mkexpr(td), loadLE(ty,mkexpr(ts)) );
+
+   putIReg64( R_RDI, binop(Iop_Add64, mkexpr(td), mkexpr(t_inc)) );
+   putIReg64( R_RSI, binop(Iop_Add64, mkexpr(ts), mkexpr(t_inc)) );
+}
+
 //.. //-- static 
 //.. //-- void dis_LODS ( UCodeBlock* cb, Int sz, Int t_inc )
 //.. //-- {
@@ -3697,11 +3696,16 @@ void dis_SCAS ( Int sz, IRTemp t_inc )
 static 
 void dis_REP_op ( AMD64Condcode cond,
                   void (*dis_OP)(Int, IRTemp),
-                  Int sz, Addr64 rip, Addr64 rip_next, HChar* name )
+                  Int sz, Addr64 rip, Addr64 rip_next, HChar* name,
+                  Prefix pfx )
 {
    IRTemp t_inc = newTemp(Ity_I64);
    IRTemp tc    = newTemp(Ity_I64);  /*  RCX  */
 
+   /* Really we ought to inspect the override prefixes, but we don't.
+      The following assertion catches any resulting sillyness. */
+   vassert(pfx == clearSegBits(pfx));
+
    assign( tc, getIReg64(R_RCX) );
 
    stmt( IRStmt_Exit( binop(Iop_CmpEQ64,mkexpr(tc),mkU64(0)),
@@ -11810,12 +11814,15 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
       d64 = getSDisp(imin(4,sz),delta); 
       delta += imin(4,sz);
       goto do_push_I;
-//..    case 0x6A: /* PUSH Ib, sign-extended to sz */
-//..       d32 = getSDisp8(delta); delta += 1;
-//..       goto do_push_I;
+   case 0x6A: /* PUSH Ib, sign-extended to sz */
+      /* Note, sz==4 is not possible in 64-bit mode.  Hence ... */
+      if (sz == 4) sz = 8;
+      d64 = getSDisp8(delta); delta += 1;
+      goto do_push_I;
    do_push_I:
       ty = szToITy(sz);
-      t1 = newTemp(Ity_I64); t2 = newTemp(ty);
+      t1 = newTemp(Ity_I64);
+      t2 = newTemp(ty);
       assign( t1, binop(Iop_Sub64,getIReg64(R_RSP),mkU64(sz)) );
       putIReg64(R_RSP, mkexpr(t1) );
       storeLE( mkexpr(t1), mkU(ty,d64) );
@@ -11921,10 +11928,6 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
 //..      dis_string_op( dis_CMPS, ( opc == 0xA6 ? 1 : sz ), "cmps", sorb );
 //..      break;
 //.. //-- 
-//..    case 0xAA: /* STOS, no REP prefix */
-//..    case 0xAB:
-//..       dis_string_op( dis_STOS, ( opc == 0xAA ? 1 : sz ), "stos", sorb );
-//..       break;
 //.. //--    
 //.. //--    case 0xAC: /* LODS, no REP prefix */
 //.. //--    case 0xAD:
@@ -11942,11 +11945,11 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
       DIP("cld\n");
       break;
 
-//..    case 0xFD: /* STD */
-//..       stmt( IRStmt_Put( OFFB_DFLAG, mkU32(0xFFFFFFFF)) );
-//..       DIP("std\n");
-//..       break;
-//.. 
+   case 0xFD: /* STD */
+      stmt( IRStmt_Put( OFFB_DFLAG, mkU64(-1ULL)) );
+      DIP("std\n");
+      break;
+
 //.. //--    case 0xF8: /* CLC */
 //.. //--       uInstr0(cb, CALLM_S, 0);
 //.. //--       uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CLC));
@@ -12007,44 +12010,96 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
 //..       break;
 //..    }
 
-   /* REPNE (F2) prefix insn */
-   case 0xAE: /* F2 AE: repne scasb */
+   /* ------ AE: SCAS variants ------ */
+   case 0xAE:
+   case 0xAF:
+      /* F2 AE/AF: repne scasb/repne scas{w,l,q} */
       if (haveF2(pfx) && !haveF3(pfx)) {
          if (opc == 0xAE)
             sz = 1;
          dis_REP_op ( AMD64CondNZ, dis_SCAS, sz, 
                       guest_rip_curr_instr,
-                      guest_rip_bbstart+delta, "repne scas" );
+                      guest_rip_bbstart+delta, "repne scas", pfx );
          whatNext = Dis_StopHere;
          break;
       }
+      /* AE/AF: scasb/scas{w,l,q} */
+      if (!haveF2(pfx) && !haveF3(pfx)) {
+         if (opc == 0xAE)
+            sz = 1;
+         dis_string_op( dis_SCAS, sz, "scas", pfx );
+         break;
+      }
       goto decode_failure;
 
-   /* REP/REPE (F3) prefix insn (for SCAS and CMPS, 0xF3 means REPE,
-      for the rest, it means REP) */
-   case 0xA6: /* F3 A6: repe cmpsb */
-   case 0xA7: /* F3 {48} A7: repe cmps{w,l,q} */
+   /* ------ A6, A7: CMPS variants ------ */
+   case 0xA6:
+   case 0xA7:
+      /* F3 A6/A7: repe cmps/rep cmps{w,l,q} */
       if (haveF3(pfx) && !haveF2(pfx)) {
          if (opc == 0xA6)
             sz = 1;
          dis_REP_op ( AMD64CondZ, dis_CMPS, sz, 
                       guest_rip_curr_instr,
-                      guest_rip_bbstart+delta, "repe cmps" );
+                      guest_rip_bbstart+delta, "repe cmps", pfx );
          whatNext = Dis_StopHere;
          break;
       }
       goto decode_failure;
 
-   case 0xAB: /* F3 {48} AB: rep stos{w,l,q} */
+   /* ------ AA, AB: STOS variants ------ */
+   case 0xAA:
+   case 0xAB:
+      /* F3 AA/AB: rep stosb/rep stos{w,l,q} */
       if (haveF3(pfx) && !haveF2(pfx)) {
+         if (opc == 0xAA)
+            sz = 1;
          dis_REP_op ( AMD64CondAlways, dis_STOS, sz,
                       guest_rip_curr_instr,
-                      guest_rip_bbstart+delta, "rep stos" );
-         whatNext = Dis_StopHere;
+                      guest_rip_bbstart+delta, "rep stos", pfx );
+        whatNext = Dis_StopHere;
+        break;
+      }
+      /* AA/AB: stosb/stos{w,l,q} */
+      if (!haveF3(pfx) && !haveF2(pfx)) {
+         if (opc == 0xAA)
+            sz = 1;
+         dis_string_op( dis_STOS, sz, "stos", pfx );
          break;
       }
       goto decode_failure;
 
+   /* ------ A4, A5: MOVS variants ------ */
+   case 0xA4:
+   case 0xA5:
+      /* F3 A4: rep movsb */
+      if (haveF3(pfx) && !haveF2(pfx)) {
+         if (opc == 0xA4)
+            sz = 1;
+         dis_REP_op ( AMD64CondAlways, dis_MOVS, sz,
+                      guest_rip_curr_instr,
+                      guest_rip_bbstart+delta, "rep movs", pfx );
+        whatNext = Dis_StopHere;
+        break;
+      }
+      /* A4: movsb */
+      if (!haveF3(pfx) && !haveF2(pfx)) {
+         if (opc == 0xA4)
+            sz = 1;
+         dis_string_op( dis_MOVS, sz, "movs", pfx );
+         break;
+      }
+      goto decode_failure;
+
+//..    case 0xA5: 
+//..       dis_string_op( dis_MOVS, ( opc == 0xA4 ? 1 : sz ), "movs", sorb );
+//..       break;
+
+//..    case 0xA4: /* MOVS, no REP prefix */
+//..    case 0xA5: 
+//..       dis_string_op( dis_MOVS, ( opc == 0xA4 ? 1 : sz ), "movs", sorb );
+//..       break;
+
 //..   case 0xF3: { 
 //..       Addr32 eip_orig = guest_eip_bbstart + delta - 1;
 //..       vassert(sorb == 0);
index 9b80be0874ce32dd4296dfbf4e0bafb1ed4f9c58..3950ba1835fd954bd52907888b90c161f8df550e 100644 (file)
@@ -837,8 +837,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
                                 Aalu_AND, AMD64RMI_Imm(0xFFFF), dst));
                break;
             case Iop_Shr32:
-               addInstr(env, AMD64Instr_Alu64R(
-                                Aalu_AND, AMD64RMI_Imm(0xFFFFFFFF), dst));
+               addInstr(env, AMD64Instr_MovZLQ(dst,dst));
                break;
 //..             case Iop_Sar8:
 //..                addInstr(env, X86Instr_Sh32(Xsh_SHL, 24, X86RM_Reg(dst)));
@@ -853,7 +852,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
                addInstr(env, AMD64Instr_Sh64(Ash_SAR, 32, AMD64RM_Reg(dst)));
                break;
             default: 
-             ppIROp(e->Iex.Binop.op);
+               ppIROp(e->Iex.Binop.op);
                vassert(0);
          }
 
@@ -892,17 +891,15 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          HReg      dst     = newVRegI(env);
          Bool      syned   = e->Iex.Binop.op == Iop_DivModS64to32;
          AMD64RM*  rmRight = iselIntExpr_RM(env, e->Iex.Binop.arg2);
-         AMD64RMI* mask    = AMD64RMI_Imm(0xFFFFFFFF);
          /* Compute the left operand into a reg, and then 
             put the top half in edx and the bottom in eax. */
          HReg left64 = iselIntExpr_R(env, e->Iex.Binop.arg1);
-
          addInstr(env, mk_iMOVsd_RR(left64, rdx));
          addInstr(env, mk_iMOVsd_RR(left64, rax));
-         addInstr(env, AMD64Instr_Sh64(Ash_SAR, 32, AMD64RM_Reg(rdx)));
+         addInstr(env, AMD64Instr_Sh64(Ash_SHR, 32, AMD64RM_Reg(rdx)));
          addInstr(env, AMD64Instr_Div(syned, 4, rmRight));
-         addInstr(env, AMD64Instr_Alu64R(Aalu_AND, mask, rdx));
-         addInstr(env, AMD64Instr_Alu64R(Aalu_AND, mask, rax));
+        addInstr(env, AMD64Instr_MovZLQ(rdx,rdx));
+        addInstr(env, AMD64Instr_MovZLQ(rax,rax));
          addInstr(env, AMD64Instr_Sh64(Ash_SHL, 32, AMD64RM_Reg(rdx)));
          addInstr(env, mk_iMOVsd_RR(rax, dst));
          addInstr(env, AMD64Instr_Alu64R(Aalu_OR, AMD64RMI_Reg(rdx), dst));
@@ -917,8 +914,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          addInstr(env, mk_iMOVsd_RR(hi32s, hi32));
          addInstr(env, mk_iMOVsd_RR(lo32s, lo32));
          addInstr(env, AMD64Instr_Sh64(Ash_SHL, 32, AMD64RM_Reg(hi32)));
-         addInstr(env, AMD64Instr_Alu64R(
-                          Aalu_AND, AMD64RMI_Imm(0xFFFFFFFF), lo32));
+        addInstr(env, AMD64Instr_MovZLQ(lo32,lo32));
          addInstr(env, AMD64Instr_Alu64R(
                           Aalu_OR, AMD64RMI_Reg(lo32), hi32));
          return hi32;
index 38ad7dee51d6139471f6945d87d647a7639bde50..a30076e1d50257ec0f44f874633198ab8a218d4b 100644 (file)
@@ -507,7 +507,7 @@ void ppIRExpr ( IRExpr* e )
       vex_printf(")");
       break;
     default:
-      vpanic("ppIExpr");
+      vpanic("ppIRExpr");
   }
 }