From: Julian Seward Date: Tue, 6 Sep 2005 10:25:46 +0000 (+0000) Subject: Implement mftb{,u}. X-Git-Tag: svn/VALGRIND_3_1_1^2~120 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=45814697eb265054f1bb49eec59821935385b0e3;p=thirdparty%2Fvalgrind.git Implement mftb{,u}. git-svn-id: svn://svn.valgrind.org/vex/trunk@1371 --- diff --git a/VEX/priv/guest-ppc32/gdefs.h b/VEX/priv/guest-ppc32/gdefs.h index 6ee087a101..22725e39d3 100644 --- a/VEX/priv/guest-ppc32/gdefs.h +++ b/VEX/priv/guest-ppc32/gdefs.h @@ -101,14 +101,6 @@ typedef } PPC32CmpF64Result; - -/*---------------------------------------------------------*/ -/*--- ppc32 guest helpers ---*/ -/*---------------------------------------------------------*/ - -/* --- CLEAN HELPERS --- */ - - /* Enumeration for xer_ca/ov calculation helper functions */ @@ -129,6 +121,19 @@ enum { }; +/*---------------------------------------------------------*/ +/*--- ppc32 guest helpers ---*/ +/*---------------------------------------------------------*/ + +/* --- CLEAN HELPERS --- */ + +/* none, right now */ + +/* --- DIRTY HELPERS --- */ + +extern ULong ppc32g_dirtyhelper_MFTB ( void ); + + #endif /* ndef __LIBVEX_GUEST_PPC32_DEFS_H */ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/guest-ppc32/ghelpers.c b/VEX/priv/guest-ppc32/ghelpers.c index 8794cb176e..d5b97eb313 100644 --- a/VEX/priv/guest-ppc32/ghelpers.c +++ b/VEX/priv/guest-ppc32/ghelpers.c @@ -68,6 +68,38 @@ */ +/*---------------------------------------------------------------*/ +/*--- Misc integer helpers. ---*/ +/*---------------------------------------------------------------*/ + +/* CALLED FROM GENERATED CODE */ +/* DIRTY HELPER (non-referentially-transparent) */ +/* Horrible hack. On non-ppc32 platforms, return 1. */ +/* Reads a complete, consistent 64-bit TB value. */ +ULong ppc32g_dirtyhelper_MFTB ( void ) +{ +# if defined(__powerpc__) + ULong res; + UInt lo, hi1, hi2; + while (1) { + __asm__ __volatile__ ("\n" + "\tmftbu %0\n" + "\tmftb %1\n" + "\tmftbu %2\n" + : "=r" (hi1), "=r" (lo), "=r" (hi2) + ); + if (hi1 == hi2) break; + } + res = ((ULong)hi1) << 32; + res |= (ULong)lo; + return res; +# else + return 1ULL; +# endif +} + + +/* Helper-function specialiser. */ IRExpr* guest_ppc32_spechelper ( HChar* function_name, IRExpr** args ) diff --git a/VEX/priv/guest-ppc32/toIR.c b/VEX/priv/guest-ppc32/toIR.c index 18809fdf37..e3b2c7bc97 100644 --- a/VEX/priv/guest-ppc32/toIR.c +++ b/VEX/priv/guest-ppc32/toIR.c @@ -3446,7 +3446,7 @@ static Bool dis_proc_ctl ( UInt theInstr ) /* XFX-Form */ UChar Rs_addr = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */ UInt SPR = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ -//uu UInt TBR = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ + UInt TBR = (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */ UChar b20 = toUChar((theInstr >> 11) & 0x1); /* theInstr[11] */ UInt CRM = (theInstr >> 12) & 0xFF; /* theInstr[12:19] */ UChar b11 = toUChar((theInstr >> 11) & 0x1); /* theInstr[20] */ @@ -3459,6 +3459,9 @@ static Bool dis_proc_ctl ( UInt theInstr ) IRTemp Rs = newTemp(Ity_I32); //uu IRTemp tmp = newTemp(Ity_I32); + /* Reorder TBR field as per PPC32 p475 */ + TBR = ((TBR & 31) << 5) | ((TBR >> 5) & 31); + assign( Rs, getIReg(Rs_addr) ); if (opc1 != 0x1F || b0 != 0) { @@ -3569,12 +3572,34 @@ static Bool dis_proc_ctl ( UInt theInstr ) } break; -//zz case 0x173: // mftb (Move from Time Base, PPC32 p475) -//zz vassert(0); -//zz -//zz DIP("mftb r%d,0x%x\n", Rd_addr, TBR); -//zz return False; - + case 0x173: { // mftb (Move from Time Base, PPC32 p475) + IRTemp val = newTemp(Ity_I64); + IRExpr** args = mkIRExprVec_0(); + IRDirty* d = unsafeIRDirty_1_N ( + val, + 0/*regparms*/, + "ppc32g_dirtyhelper_MFTB", + &ppc32g_dirtyhelper_MFTB, + args + ); + /* execute the dirty call, dumping the result in val. */ + stmt( IRStmt_Dirty(d) ); + + switch (TBR) { + case 269: + putIReg( Rd_addr, unop(Iop_64HIto32, mkexpr(val)) ); + DIP("mftbu r%d", Rd_addr); + break; + case 268: + putIReg( Rd_addr, unop(Iop_64to32, mkexpr(val)) ); + DIP("mftb r%d", Rd_addr); + break; + default: + return False; /* illegal instruction */ + } + break; + } + case 0x090: // mtcrf (Move to Condition Register Fields, PPC32 p477) if (b11 != 0 || b20 != 0) { vex_printf("dis_proc_ctl(PPC32)(mtcrf,b11|b20)\n");