Support for vex-directed instruction-cache invalidation, needed for

PowerPC icbi instruction support.


git-svn-id: svn://svn.valgrind.org/vex/trunk@1037
This commit is contained in:
Julian Seward
2005-03-15 16:54:13 +00:00
parent c263e72fec
commit fd8e23dc66
7 changed files with 52 additions and 7 deletions

View 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;
}

View 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 */

View 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:

View 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");
}
}

View 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; */
}

View 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;

View 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 */