]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge r1749 (Implement lahf/sahf on amd64. Also set NDEP on x86 sahf.
authorJulian Seward <jseward@acm.org>
Sun, 29 Apr 2007 10:39:16 +0000 (10:39 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 29 Apr 2007 10:39:16 +0000 (10:39 +0000)
Fixes #143907.)

git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_2_BRANCH@1758

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

index d07598bdd1be384e421c289b551efdbb5f09b617..a3c28bd511275db96b06a326a7a9e2d9641f2540 100644 (file)
@@ -7122,51 +7122,57 @@ void codegen_xchg_rAX_Reg ( Prefix pfx, Int sz, UInt regLo3 )
 }
 
 
-//.. static 
-//.. void codegen_SAHF ( void )
-//.. {
-//..    /* Set the flags to:
-//..       (x86g_calculate_flags_all() & X86G_CC_MASK_O)  -- retain the old O flag
-//..       | (%AH & (X86G_CC_MASK_S|X86G_CC_MASK_Z|X86G_CC_MASK_A
-//..                 |X86G_CC_MASK_P|X86G_CC_MASK_C)
-//..    */
-//..    UInt   mask_SZACP = X86G_CC_MASK_S|X86G_CC_MASK_Z|X86G_CC_MASK_A
-//..                        |X86G_CC_MASK_C|X86G_CC_MASK_P;
-//..    IRTemp oldflags   = newTemp(Ity_I32);
-//..    assign( oldflags, mk_x86g_calculate_eflags_all() );
-//..    stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(X86G_CC_OP_COPY) ));
-//..    stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
-//..    stmt( IRStmt_Put( OFFB_CC_DEP1,
-//..          binop(Iop_Or32,
-//..                binop(Iop_And32, mkexpr(oldflags), mkU32(X86G_CC_MASK_O)),
-//..                binop(Iop_And32, 
-//..                      binop(Iop_Shr32, getIReg(4, R_EAX), mkU8(8)),
-//..                      mkU32(mask_SZACP))
-//..               )
-//..    ));
-//.. }
-//.. 
-//.. 
-//.. //-- static 
-//.. //-- void codegen_LAHF ( UCodeBlock* cb )
-//.. //-- {
-//.. //--    Int t = newTemp(cb);
-//.. //-- 
-//.. //--    /* Pushed arg is ignored, it just provides somewhere to put the
-//.. //--       return value. */
-//.. //--    uInstr2(cb, GET,   4, ArchReg, R_EAX, TempReg, t);
-//.. //--    uInstr0(cb, CALLM_S, 0);
-//.. //--    uInstr1(cb, PUSH,  4, TempReg, t);
-//.. //--    uInstr1(cb, CALLM, 0, Lit16,   VGOFF_(helper_LAHF));
-//.. //--    uFlagsRWU(cb, FlagsSZACP, FlagsEmpty, FlagsEmpty);
-//.. //--    uInstr1(cb, POP,   4, TempReg, t);
-//.. //--    uInstr0(cb, CALLM_E, 0);
-//.. //-- 
-//.. //--    /* At this point, the %ah sub-register in %eax has been updated,
-//.. //--       the rest is the same, so do a PUT of the whole thing. */
-//.. //--    uInstr2(cb, PUT,   4,  TempReg, t,   ArchReg, R_EAX);
-//.. //-- }
-//.. //-- 
+static 
+void codegen_SAHF ( void )
+{
+   /* Set the flags to:
+      (amd64g_calculate_flags_all() & AMD64G_CC_MASK_O) 
+                                    -- retain the old O flag
+      | (%AH & (AMD64G_CC_MASK_S|AMD64G_CC_MASK_Z|AMD64G_CC_MASK_A
+                |AMD64G_CC_MASK_P|AMD64G_CC_MASK_C)
+   */
+   ULong  mask_SZACP = AMD64G_CC_MASK_S|AMD64G_CC_MASK_Z|AMD64G_CC_MASK_A
+                       |AMD64G_CC_MASK_C|AMD64G_CC_MASK_P;
+   IRTemp oldflags   = newTemp(Ity_I64);
+   assign( oldflags, mk_amd64g_calculate_rflags_all() );
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU64(AMD64G_CC_OP_COPY) ));
+   stmt( IRStmt_Put( OFFB_CC_NDEP, mkU64(0) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU64(0) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP1,
+         binop(Iop_Or64,
+               binop(Iop_And64, mkexpr(oldflags), mkU64(AMD64G_CC_MASK_O)),
+               binop(Iop_And64, 
+                     binop(Iop_Shr64, getIReg64(R_RAX), mkU8(8)),
+                     mkU64(mask_SZACP))
+              )
+   ));
+}
+
+
+static 
+void codegen_LAHF ( void  )
+{
+   /* AH <- EFLAGS(SF:ZF:0:AF:0:PF:1:CF) */
+   IRExpr* rax_with_hole;
+   IRExpr* new_byte;
+   IRExpr* new_rax;
+   ULong   mask_SZACP = AMD64G_CC_MASK_S|AMD64G_CC_MASK_Z|AMD64G_CC_MASK_A
+                        |AMD64G_CC_MASK_C|AMD64G_CC_MASK_P;
+
+   IRTemp  flags = newTemp(Ity_I64);
+   assign( flags, mk_amd64g_calculate_rflags_all() );
+
+   rax_with_hole 
+      = binop(Iop_And64, getIReg64(R_RAX), mkU64(~0xFF00ULL));
+   new_byte 
+      = binop(Iop_Or64, binop(Iop_And64, mkexpr(flags), mkU64(mask_SZACP)),
+                        mkU64(1<<1));
+   new_rax 
+      = binop(Iop_Or64, rax_with_hole,
+                        binop(Iop_Shl64, new_byte, mkU8(8)));
+   putIReg64(R_RAX, new_rax);
+}
+
 
 static
 ULong dis_cmpxchg_G_E ( /*OUT*/Bool* ok,
@@ -12355,16 +12361,16 @@ DisResult disInstr_AMD64_WRK (
 
    /* ------------------------ FPU ops -------------------- */
 
-//..    case 0x9E: /* SAHF */
-//..       codegen_SAHF();
-//..       DIP("sahf\n");
-//..       break;
-//.. 
-//.. //--    case 0x9F: /* LAHF */
-//.. //--       codegen_LAHF ( cb );
-//.. //--       DIP("lahf\n");
-//.. //--       break;
-//.. //-- 
+   case 0x9E: /* SAHF */
+      codegen_SAHF();
+      DIP("sahf\n");
+      break;
+
+   case 0x9F: /* LAHF */
+      codegen_LAHF();
+      DIP("lahf\n");
+      break;
+
    case 0x9B: /* FWAIT */
       /* ignore? */
       DIP("fwait\n");
index dbc560288936c67c5b3a6419d24fe68587882250..4095b7c437ba016258e81368e49eee51190c422c 100644 (file)
@@ -6145,6 +6145,7 @@ void codegen_SAHF ( void )
    IRTemp oldflags   = newTemp(Ity_I32);
    assign( oldflags, mk_x86g_calculate_eflags_all() );
    stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(X86G_CC_OP_COPY) ));
+   stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
    stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
    stmt( IRStmt_Put( OFFB_CC_DEP1,
          binop(Iop_Or32,