]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Support for vex-directed instruction-cache invalidation, needed for
authorJulian Seward <jseward@acm.org>
Tue, 15 Mar 2005 16:54:13 +0000 (16:54 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 15 Mar 2005 16:54:13 +0000 (16:54 +0000)
PowerPC icbi instruction support.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1037

VEX/priv/guest-ppc32/ghelpers.c
VEX/priv/guest-ppc32/toIR.c
VEX/priv/host-ppc32/hdefs.c
VEX/priv/ir/irdefs.c
VEX/pub/libvex_guest_ppc32.h
VEX/pub/libvex_ir.h
VEX/pub/libvex_trc_values.h

index a40f30baf437b0856bbdc7d4a8d906f099a6436e..a16b809b830af37ffeb4c8f7af17c19d8bf69943 100644 (file)
@@ -280,6 +280,8 @@ void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state )
    vex_state->guest_XER = 0;
 
    vex_state->guest_EMWARN = 0;
+   vex_state->guest_TISTART = 0;
+   vex_state->guest_TILEN   = 0;
 }
 
 
index 96e7b6efb18b2b481424854f6405645825dcf3d8..659a9aac6c236c27ca1b0b937ea6afb638a8d958 100644 (file)
@@ -154,7 +154,8 @@ static IRBB* irbb;
 
 #define OFFB_XER        offsetof(VexGuestPPC32State,guest_XER)
 
-
+#define OFFB_TISTART    offsetof(VexGuestPPC32State,guest_TISTART)
+#define OFFB_TILEN      offsetof(VexGuestPPC32State,guest_TILEN)
 
 
 /*------------------------------------------------------------*/
@@ -2986,7 +2987,7 @@ static Bool dis_proc_ctl ( UInt theInstr )
 }
 
 
-static Bool dis_cache_manage ( UInt theInstr )
+static Bool dis_cache_manage ( UInt theInstr, DisResult* whatNext )
 {
    /* X-Form */
    UChar opc1    = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */
@@ -3009,7 +3010,7 @@ static Bool dis_cache_manage ( UInt theInstr )
       
    case 0x056: // dcbf (Data Cache Block Flush, PPC32 p382)
       DIP("dcbf r%d,r%d\n", Ra_addr, Rb_addr);
-      if (1) vex_printf("vex ppc32->IR: kludged dcbf\n");
+      if (0) vex_printf("vex ppc32->IR: kludged dcbf\n");
       break;
       
    case 0x036: // dcbst (Data Cache Block Store, PPC32 p384)
@@ -3032,10 +3033,35 @@ static Bool dis_cache_manage ( UInt theInstr )
       if (1) vex_printf("vex ppc32->IR: kludged dcbz\n");
       break;
 
-   case 0x3D6: // icbi (Instruction Cache Block Invalidate, PPC32 p431)
+   case 0x3D6: { 
+      // icbi (Instruction Cache Block Invalidate, PPC32 p431)
+      /* Invalidate all translations containing code from the cache
+         block at (rA|0) + rB.  Since we don't know what the cache
+         line size is, let's assume 256 -- no real I1 cache would ever
+         have a line size that large, so that's safe. */
+      IRTemp addr = newTemp(Ity_I32);
+      UInt   assumed_line_size = 256;
       DIP("icbi r%d,r%d\n", Ra_addr, Rb_addr);
-      if (1) vex_printf("vex ppc32->IR: kludged icbi\n");
+
+      assign( addr,
+              binop( Iop_Add32, 
+                     getIReg(Rb_addr), 
+                     Ra_addr==0 ? mkU32(0) : getIReg(Ra_addr)) );
+
+      /* Round addr down to the start of the containing block. */
+      stmt( IRStmt_Put(
+               OFFB_TISTART,
+               binop( Iop_And32, 
+                      mkexpr(addr), 
+                      mkU32( ~(assumed_line_size-1) ))) );
+
+      stmt( IRStmt_Put(OFFB_TILEN, mkU32(assumed_line_size) ) );
+
+      irbb->jumpkind = Ijk_TInval;
+      irbb->next     = mkU32(guest_cia_curr_instr + 4);
+      *whatNext      = Dis_StopHere;
       break;
+   }
 
    default:
       vex_printf("dis_cache_manage(PPC32)(opc2)\n");
@@ -3321,7 +3347,7 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
       case 0x2F6: case 0x056: case 0x036: // dcba, dcbf,   dcbst
       case 0x116: case 0x0F6: case 0x3F6: // dcbt, dcbtst, dcbz
       case 0x3D6:                         // icbi
-         if (dis_cache_manage( theInstr )) goto decode_success;
+         if (dis_cache_manage( theInstr, &whatNext )) goto decode_success;
          goto decode_failure;
 
       /* External Control Instructions */
index aa081be23febae69b5b6b08247f2134eb86aa7d1..27e7249a66e37e5e9e808800ffa73123ac40244a 100644 (file)
@@ -2307,6 +2307,7 @@ Int emit_PPC32Instr ( UChar* buf, Int nbuf, PPC32Instr* i )
       case Ijk_EmWarn:    magic_num = VEX_TRC_JMP_EMWARN;    break;
       case Ijk_MapFail:   magic_num = VEX_TRC_JMP_MAPFAIL;   break;
       case Ijk_NoDecode:  magic_num = VEX_TRC_JMP_NODECODE;  break;
+      case Ijk_TInval:    magic_num = VEX_TRC_JMP_TINVAL;    break;
       case Ijk_Ret:
       case Ijk_Call:
       case Ijk_Boring:
index a30076e1d50257ec0f44f874633198ab8a218d4b..45f5975907b4c5be3e1200ce9bd467e1b8902f03 100644 (file)
@@ -569,6 +569,7 @@ void ppIRJumpKind ( IRJumpKind kind )
       case Ijk_EmWarn:    vex_printf("EmWarn"); break;
       case Ijk_NoDecode:  vex_printf("NoDecode"); break;
       case Ijk_MapFail:   vex_printf("MapFail"); break;
+      case Ijk_TInval:    vex_printf("Invalidate"); break;
       default:            vpanic("ppIRJumpKind");
    }
 }
index e46fc03529e454806478216c5b133304ff6c73ae..395c39faa9546490c1ab50120a0929c6d6fd51f3 100644 (file)
@@ -133,6 +133,10 @@ typedef
       /* Emulation warnings */
       /* 420 */ UInt guest_EMWARN;
 
+      /* For icbi: record start and length of area to invalidate */
+      /* 424 */ UInt guest_TISTART;
+      /* 428 */ UInt guest_TILEN;
+
       /* Padding to make it have an 8-aligned size */
       /* UInt  padding; */
    }
index 53e34b5fdfa903b72f198db49c427cba5da68a67..dd4a9def47730333e540de68ac96f8605e5c0b63 100644 (file)
@@ -704,6 +704,13 @@ inline static Bool isAtom ( IRExpr* e ) {
 
 /* This describes hints which can be passed to the dispatcher at guest
    control-flow transfer points.
+
+   Re Ijk_Invalidate: typically the guest state will have two
+   pseudo-registers, guest_TISTART and guest_TILEN, which
+   specify the start and length of the region to be invalidated.
+   It is the responsibility of the relevant toIR.c to ensure that
+   these are filled in with suitable values before issuing a jump
+   of kind Ijk_TInval.
 */
 typedef
    enum { 
@@ -715,7 +722,8 @@ typedef
       Ijk_Yield,          /* client is yielding to thread scheduler */
       Ijk_EmWarn,         /* report emulation warning before continuing */
       Ijk_NoDecode,       /* next instruction cannot be decoded */
-      Ijk_MapFail         /* Vex-provided address translation failed */
+      Ijk_MapFail,        /* Vex-provided address translation failed */
+      Ijk_TInval          /* Invalidate translations before continuing. */
    }
    IRJumpKind;
 
index f928071c17386a8c724c9375c8186789531d077b..dc09e64e3b20595951871c97356d88e838ea99eb 100644 (file)
@@ -44,6 +44,9 @@
    This file may get included in assembly code, so do not put
    C-specific constructs in it.
 */
+
+#define VEX_TRC_JMP_TINVAL     13  /* invalidate translations before
+                                      continuing */
 #define VEX_TRC_JMP_EMWARN     17  /* deliver emulation warning before
                                       continuing */
 #define VEX_TRC_JMP_SYSCALL    19  /* do a system call before continuing */