From: Julian Seward Date: Sat, 22 Oct 2005 02:01:16 +0000 (+0000) Subject: Minor altivec changes: X-Git-Tag: svn/VALGRIND_3_1_1^2~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=24615b921cfd1aadf03c1149eef6937738934bfe;p=thirdparty%2Fvalgrind.git Minor altivec changes: - vsplt{b,h,w}: guarantee to always produce in-range shifts - lvs{l,r}: mask second arg to helper so assertion in helper doesn't fire. Also pass in offset to dest rather than reg #. git-svn-id: svn://svn.valgrind.org/vex/trunk@1422 --- diff --git a/VEX/priv/guest-ppc32/gdefs.h b/VEX/priv/guest-ppc32/gdefs.h index db854cc0c6..ce7df23211 100644 --- a/VEX/priv/guest-ppc32/gdefs.h +++ b/VEX/priv/guest-ppc32/gdefs.h @@ -135,7 +135,7 @@ extern ULong ppc32g_dirtyhelper_MFTB ( void ); extern void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst, UInt vD_idx, UInt sh, - UInt dirn ); + UInt shift_right ); #endif /* ndef __LIBVEX_GUEST_PPC32_DEFS_H */ diff --git a/VEX/priv/guest-ppc32/ghelpers.c b/VEX/priv/guest-ppc32/ghelpers.c index 2558a46746..d74739d49e 100644 --- a/VEX/priv/guest-ppc32/ghelpers.c +++ b/VEX/priv/guest-ppc32/ghelpers.c @@ -102,7 +102,7 @@ ULong ppc32g_dirtyhelper_MFTB ( void ) /* CALLED FROM GENERATED CODE */ /* DIRTY HELPER (reads guest state, writes guest mem) */ void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst, - UInt vD_idx, UInt sh, UInt dirn ) + UInt vD_off, UInt sh, UInt shift_right ) { static UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, @@ -112,15 +112,15 @@ void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst, U128* pU128_src; U128* pU128_dst; - vassert( vD_idx <= 31 ); - vassert( sh <= 15 ); - vassert( dirn <= 1 ); - if (dirn == 1) /* shift right */ + vassert( vD_off <= sizeof(VexGuestPPC32State)-8 ); + vassert( sh <= 15 ); + vassert( shift_right <= 1 ); + if (shift_right) sh = 16-sh; /* else shift left */ pU128_src = (U128*)&ref[sh]; - pU128_dst = &gst->guest_VR0 + (vD_idx*sizeof(gst->guest_VR0)); + pU128_dst = (U128*)( ((UChar*)gst) + vD_off ); (*pU128_dst)[0] = (*pU128_src)[0]; (*pU128_dst)[1] = (*pU128_src)[1]; diff --git a/VEX/priv/guest-ppc32/toIR.c b/VEX/priv/guest-ppc32/toIR.c index f0a93e45a8..0732193bb9 100644 --- a/VEX/priv/guest-ppc32/toIR.c +++ b/VEX/priv/guest-ppc32/toIR.c @@ -4966,7 +4966,11 @@ static Bool dis_av_load ( UInt theInstr ) switch (opc2) { case 0x006: { // lvsl (Load Vector for Shift Left, AV p123) - IRExpr** args = mkIRExprVec_3(mkU32(vD_addr), mkexpr(EA), mkU32(0)); + UInt vD_off = vectorGuestRegOffset(vD_addr); + IRExpr** args = mkIRExprVec_3( + mkU32(vD_off), + binop(Iop_And32, mkexpr(EA), mkU32(0xF)), + mkU32(0)/*left*/ ); IRDirty* d = unsafeIRDirty_0_N ( 0/*regparms*/, "ppc32g_dirtyhelper_LVS", @@ -4977,7 +4981,7 @@ static Bool dis_av_load ( UInt theInstr ) d->needsBBP = True; d->nFxState = 1; d->fxState[0].fx = Ifx_Write; - d->fxState[0].offset = vectorGuestRegOffset(vD_addr); + d->fxState[0].offset = vD_off; d->fxState[0].size = sizeof(U128); /* execute the dirty call, side-effecting guest state */ @@ -4985,7 +4989,11 @@ static Bool dis_av_load ( UInt theInstr ) break; } case 0x026: { // lvsr (Load Vector for Shift Right, AV p125) - IRExpr** args = mkIRExprVec_3(mkU32(vD_addr), mkexpr(EA), mkU32(1)); + UInt vD_off = vectorGuestRegOffset(vD_addr); + IRExpr** args = mkIRExprVec_3( + mkU32(vD_off), + binop(Iop_And32, mkexpr(EA), mkU32(0xF)), + mkU32(1)/*right*/ ); IRDirty* d = unsafeIRDirty_0_N ( 0/*regparms*/, "ppc32g_dirtyhelper_LVS", @@ -4996,7 +5004,7 @@ static Bool dis_av_load ( UInt theInstr ) d->needsBBP = True; d->nFxState = 1; d->fxState[0].fx = Ifx_Write; - d->fxState[0].offset = vectorGuestRegOffset(vD_addr); + d->fxState[0].offset = vD_off; d->fxState[0].size = sizeof(U128); /* execute the dirty call, side-effecting guest state */ @@ -6050,7 +6058,7 @@ static Bool dis_av_permute ( UInt theInstr ) /* Splat */ case 0x20C: { // vspltb (Splat Byte, AV p245) /* vD = Dup8x16( vB[UIMM_5] ) */ - UChar sh_uimm = (15-UIMM_5)*8; + UChar sh_uimm = (15 - (UIMM_5 & 15)) * 8; DIP("vspltb v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5); putVReg( vD_addr, unop(Iop_Dup8x16, unop(Iop_32to8, unop(Iop_V128to32, @@ -6058,7 +6066,7 @@ static Bool dis_av_permute ( UInt theInstr ) break; } case 0x24C: { // vsplth (Splat Half Word, AV p246) - UChar sh_uimm = (7-UIMM_5)*16; + UChar sh_uimm = (7 - (UIMM_5 & 7)) * 16; DIP("vsplth v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5); putVReg( vD_addr, unop(Iop_Dup16x8, unop(Iop_32to16, unop(Iop_V128to32, @@ -6067,7 +6075,7 @@ static Bool dis_av_permute ( UInt theInstr ) } case 0x28C: { // vspltw (Splat Word, AV p250) /* vD = Dup32x4( vB[UIMM_5] ) */ - UChar sh_uimm = (3-UIMM_5)*32; + UChar sh_uimm = (3 - (UIMM_5 & 3)) * 32; DIP("vspltw v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5); putVReg( vD_addr, unop(Iop_Dup32x4, unop(Iop_V128to32,