From: <sv...@va...> - 2007-04-29 10:39:17
|
Author: sewardj Date: 2007-04-29 11:39:16 +0100 (Sun, 29 Apr 2007) New Revision: 1758 Log: Merge r1749 (Implement lahf/sahf on amd64. Also set NDEP on x86 sahf. Fixes #143907.) Modified: branches/VEX_3_2_BRANCH/priv/guest-amd64/toIR.c branches/VEX_3_2_BRANCH/priv/guest-x86/toIR.c Modified: branches/VEX_3_2_BRANCH/priv/guest-amd64/toIR.c =================================================================== --- branches/VEX_3_2_BRANCH/priv/guest-amd64/toIR.c 2007-04-29 10:34:42 UTC (rev 1757) +++ branches/VEX_3_2_BRANCH/priv/guest-amd64/toIR.c 2007-04-29 10:39:16 UTC (rev 1758) @@ -7122,52 +7122,58 @@ } -//.. 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, Prefix pfx, @@ -12355,16 +12361,16 @@ /* ------------------------ 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"); Modified: branches/VEX_3_2_BRANCH/priv/guest-x86/toIR.c =================================================================== --- branches/VEX_3_2_BRANCH/priv/guest-x86/toIR.c 2007-04-29 10:34:42 UTC (rev 1757) +++ branches/VEX_3_2_BRANCH/priv/guest-x86/toIR.c 2007-04-29 10:39:16 UTC (rev 1758) @@ -6145,6 +6145,7 @@ 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, |