From: Julian Seward Date: Tue, 23 Aug 2005 19:24:29 +0000 (+0000) Subject: Implement RDTSC on x86. X-Git-Tag: svn/VALGRIND_3_1_1^2~136 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4892383c6d5c7f3c6810943166fdda76758e796a;p=thirdparty%2Fvalgrind.git Implement RDTSC on x86. git-svn-id: svn://svn.valgrind.org/vex/trunk@1344 --- diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index 1df4a446e3..d1d3d29037 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -151,6 +151,8 @@ extern void x86g_dirtyhelper_FXSAVE ( VexGuestX86State*, HWord ); extern void x86g_dirtyhelper_FSAVE ( VexGuestX86State*, HWord ); extern void x86g_dirtyhelper_FSTENV ( VexGuestX86State*, HWord ); +extern ULong x86g_dirtyhelper_RDTSC ( void ); + extern VexEmWarn x86g_dirtyhelper_FRSTOR ( VexGuestX86State*, HWord ); diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 5aaaf9a45b..b188718b8d 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -1693,6 +1693,21 @@ ULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) } +/* CALLED FROM GENERATED CODE */ +/* DIRTY HELPER (non-referentially-transparent) */ +/* Horrible hack. On non-x86 platforms, return 1. */ +ULong x86g_dirtyhelper_RDTSC ( void ) +{ +# if defined(__i386__) + ULong res; + __asm__ __volatile__("rdtsc" : "=A" (res)); + return res; +# else + return 1ULL; +# endif +} + + /* CALLED FROM GENERATED CODE */ /* DIRTY HELPER (modifies guest state) */ /* Claim to be a P55C (Intel Pentium/MMX) */ diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 18e647f15c..515785dd5d 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -11967,34 +11967,23 @@ DisResult disInstr_X86_WRK ( break; /* =-=-=-=-=-=-=-=-=- RDTSC -=-=-=-=-=-=-=-=-=-=-= */ - - case 0x31: /* RDTSC */ - if (0) vex_printf("vex x86->IR: kludged rdtsc\n"); - putIReg(4, R_EAX, mkU32(1)); - putIReg(4, R_EDX, mkU32(0)); - -//-- t1 = newTemp(cb); -//-- t2 = newTemp(cb); -//-- t3 = newTemp(cb); -//-- uInstr0(cb, CALLM_S, 0); -//-- // Nb: even though these args aren't used by RDTSC_helper, need -//-- // them to be defined (for Memcheck). The TempRegs pushed must -//-- // also be distinct. -//-- uInstr2(cb, MOV, 4, Literal, 0, TempReg, t1); -//-- uLiteral(cb, 0); -//-- uInstr1(cb, PUSH, 4, TempReg, t1); -//-- uInstr2(cb, MOV, 4, Literal, 0, TempReg, t2); -//-- uLiteral(cb, 0); -//-- uInstr1(cb, PUSH, 4, TempReg, t2); -//-- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_RDTSC)); -//-- uFlagsRWU(cb, FlagsEmpty, FlagsEmpty, FlagsEmpty); -//-- uInstr1(cb, POP, 4, TempReg, t3); -//-- uInstr2(cb, PUT, 4, TempReg, t3, ArchReg, R_EDX); -//-- uInstr1(cb, POP, 4, TempReg, t3); -//-- uInstr2(cb, PUT, 4, TempReg, t3, ArchReg, R_EAX); -//-- uInstr0(cb, CALLM_E, 0); - DIP("rdtsc\n"); - break; + case 0x31: { /* RDTSC */ + IRTemp val = newTemp(Ity_I64); + IRExpr** args = mkIRExprVec_0(); + IRDirty* d = unsafeIRDirty_1_N ( + val, + 0/*regparms*/, + "x86g_dirtyhelper_RDTSC", + &x86g_dirtyhelper_RDTSC, + args + ); + /* execute the dirty call, dumping the result in val. */ + stmt( IRStmt_Dirty(d) ); + putIReg(4, R_EDX, unop(Iop_64HIto32, mkexpr(val))); + putIReg(4, R_EAX, unop(Iop_64to32, mkexpr(val))); + DIP("rdtsc\n"); + break; + } /* =-=-=-=-=-=-=-=-=- PUSH/POP Sreg =-=-=-=-=-=-=-=-=-= */