From ea276103f871fe8d7f3a5b082b186352e77500b4 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Tue, 23 Aug 2005 23:16:51 +0000 Subject: [PATCH] Implement RDTSC (amd64). git-svn-id: svn://svn.valgrind.org/vex/trunk@1346 --- VEX/priv/guest-amd64/gdefs.h | 2 ++ VEX/priv/guest-amd64/ghelpers.c | 15 ++++++++++++ VEX/priv/guest-amd64/toIR.c | 43 ++++++++++++--------------------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/VEX/priv/guest-amd64/gdefs.h b/VEX/priv/guest-amd64/gdefs.h index 8f6814d579..2ac553c6d9 100644 --- a/VEX/priv/guest-amd64/gdefs.h +++ b/VEX/priv/guest-amd64/gdefs.h @@ -145,6 +145,8 @@ extern void amd64g_storeF80le ( ULong/*addr*/, ULong/*data*/ ); extern void amd64g_dirtyhelper_CPUID ( VexGuestAMD64State* st ); +extern ULong amd64g_dirtyhelper_RDTSC ( void ); + //extern void amd64g_dirtyhelper_CPUID_sse0 ( VexGuestAMD64State* ); //extern void amd64g_dirtyhelper_CPUID_sse1 ( VexGuestAMD64State* ); //extern void amd64g_dirtyhelper_CPUID_sse2 ( VexGuestAMD64State* ); diff --git a/VEX/priv/guest-amd64/ghelpers.c b/VEX/priv/guest-amd64/ghelpers.c index 7958bb72ec..ee8688b4c4 100644 --- a/VEX/priv/guest-amd64/ghelpers.c +++ b/VEX/priv/guest-amd64/ghelpers.c @@ -1676,6 +1676,21 @@ ULong amd64g_calculate_RCR ( ULong arg, } +/* CALLED FROM GENERATED CODE */ +/* DIRTY HELPER (non-referentially-transparent) */ +/* Horrible hack. On non-amd64 platforms, return 1. */ +ULong amd64g_dirtyhelper_RDTSC ( void ) +{ +# if defined(__x86_64__) + UInt eax, edx; + __asm__ __volatile__("rdtsc" : "=a" (eax), "=d" (edx)); + return (((ULong)edx) << 32) | ((ULong)eax); +# else + return 1ULL; +# endif +} + + /*---------------------------------------------------------------*/ /*--- Helpers for MMX/SSE/SSE2. ---*/ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index 327d60effa..0a27bef089 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -13084,35 +13084,24 @@ DisResult disInstr_AMD64_WRK ( break; /* =-=-=-=-=-=-=-=-=- RDTSC -=-=-=-=-=-=-=-=-=-=-= */ - - case 0x31: /* RDTSC */ - if (haveF2orF3(pfx)) goto decode_failure; - if (0) vex_printf("vex amd64->IR: kludged rdtsc\n"); - putIRegRAX(4, mkU32(1)); - putIRegRDX(4, 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); + case 0x31: { /* RDTSC */ + IRTemp val = newTemp(Ity_I64); + IRExpr** args = mkIRExprVec_0(); + IRDirty* d = unsafeIRDirty_1_N ( + val, + 0/*regparms*/, + "amd64g_dirtyhelper_RDTSC", + &amd64g_dirtyhelper_RDTSC, + args + ); + if (have66orF2orF3(pfx)) goto decode_failure; + /* execute the dirty call, dumping the result in val. */ + stmt( IRStmt_Dirty(d) ); + putIRegRDX(4, unop(Iop_64HIto32, mkexpr(val))); + putIRegRAX(4, unop(Iop_64to32, mkexpr(val))); DIP("rdtsc\n"); break; + } //.. /* =-=-=-=-=-=-=-=-=- PUSH/POP Sreg =-=-=-=-=-=-=-=-=-= */ //.. -- 2.47.3