]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Implement SSE2 'clflush'.
authorJulian Seward <jseward@acm.org>
Tue, 15 Nov 2005 11:16:30 +0000 (11:16 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 15 Nov 2005 11:16:30 +0000 (11:16 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@1460

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

index 7dc29b4adb6b79d896e270bcf82911c3b3355cae..fc943b7361847b6ad4f0c6cdbbcdaeef97c37ac8 100644 (file)
@@ -2222,8 +2222,7 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
 
    vex_state->guest_EMWARN = EmWarn_NONE;
 
-   /* These should not ever be either read or written, but we
-      initialise them anyway. */
+   /* SSE2 has a 'clflush' cache-line-invalidator which uses these. */
    vex_state->guest_TISTART = 0;
    vex_state->guest_TILEN   = 0;
 }
index a4dd7c68c354f6c86c87574537a8020c52ba12fd..9be59295b8761015f45dfbd40fb497cc34a567d2 100644 (file)
@@ -225,6 +225,8 @@ static IRBB* irbb;
 
 #define OFFB_EMWARN    offsetof(VexGuestX86State,guest_EMWARN)
 
+#define OFFB_TISTART   offsetof(VexGuestX86State,guest_TISTART)
+#define OFFB_TILEN     offsetof(VexGuestX86State,guest_TILEN)
 
 /*------------------------------------------------------------*/
 /*--- Helper bits and pieces for deconstructing the        ---*/
@@ -10339,7 +10341,6 @@ DisResult disInstr_X86_WRK (
       goto decode_success;
    }
 
-
 //--    /* FXSAVE/FXRSTOR m32 -- load/store the FPU/MMX/SSE state. */
 //--    if (insn[0] == 0x0F && insn[1] == 0xAE 
 //--        && (!epartIsReg(insn[2]))
@@ -10355,25 +10356,38 @@ DisResult disInstr_X86_WRK (
 //--                   TempReg, t1 );
 //--       DIP("fx%s %s\n", store ? "save" : "rstor", dis_buf );
 //--       goto decode_success;
-//--    }
-//-- 
-//--    /* CLFLUSH -- flush cache line */
-//--    if (insn[0] == 0x0F && insn[1] == 0xAE
-//--        && (!epartIsReg(insn[2]))
-//--        && (gregOfRM(insn[2]) == 7))
-//--    {
-//--       vg_assert(sz == 4);
-//--       pair = disAMode ( cb, sorb, eip+2, dis_buf );
-//--       t1   = LOW24(pair);
-//--       eip += 2+HI8(pair);
-//--       uInstr3(cb, SSE2a_MemRd, 0,  /* ignore sz for internal ops */
-//--                   Lit16, (((UShort)0x0F) << 8) | (UShort)0xAE,
-//--                   Lit16, (UShort)insn[2],
-//--                   TempReg, t1 );
-//--       DIP("clflush %s\n", dis_buf);
-//--       goto decode_success;
 //--    }
 
+   /* 0F AE /7 = CLFLUSH -- flush cache line */
+   if (sz == 4 && insn[0] == 0x0F && insn[1] == 0xAE
+       && !epartIsReg(insn[2]) && gregOfRM(insn[2]) == 7) {
+
+      /* This is something of a hack.  We need to know the size of the
+         cache line containing addr.  Since we don't (easily), assume
+         256 on the basis that no real cache would have a line that
+         big.  It's safe to invalidate more stuff than we need, just
+         inefficient. */
+      UInt lineszB = 256;
+
+      addr = disAMode ( &alen, sorb, delta+2, dis_buf );
+      delta += 2+alen;
+
+      /* Round addr down to the start of the containing block. */
+      stmt( IRStmt_Put(
+               OFFB_TISTART,
+               binop( Iop_And32, 
+                      mkexpr(addr), 
+                      mkU32( ~(lineszB-1) ))) );
+
+      stmt( IRStmt_Put(OFFB_TILEN, mkU32(lineszB) ) );
+
+      irbb->jumpkind = Ijk_TInval;
+      irbb->next     = mkU32(guest_EIP_bbstart+delta);
+      dres.whatNext  = Dis_StopHere;
+
+      DIP("clflush %s\n", dis_buf);
+      goto decode_success;
+   }
 
    /* ---------------------------------------------------- */
    /* --- end of the SSE2 decoder.                     --- */