|
From: <sv...@va...> - 2005-10-22 02:01:35
|
Author: sewardj
Date: 2005-10-22 03:01:16 +0100 (Sat, 22 Oct 2005)
New Revision: 1422
Log:
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 #.
Modified:
trunk/priv/guest-ppc32/gdefs.h
trunk/priv/guest-ppc32/ghelpers.c
trunk/priv/guest-ppc32/toIR.c
Modified: trunk/priv/guest-ppc32/gdefs.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-ppc32/gdefs.h 2005-10-20 11:56:00 UTC (rev 1421)
+++ trunk/priv/guest-ppc32/gdefs.h 2005-10-22 02:01:16 UTC (rev 1422)
@@ -135,7 +135,7 @@
=20
extern void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst,
UInt vD_idx, UInt sh,
- UInt dirn );
+ UInt shift_right );
=20
#endif /* ndef __LIBVEX_GUEST_PPC32_DEFS_H */
=20
Modified: trunk/priv/guest-ppc32/ghelpers.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-ppc32/ghelpers.c 2005-10-20 11:56:00 UTC (rev 1421)
+++ trunk/priv/guest-ppc32/ghelpers.c 2005-10-22 02:01:16 UTC (rev 1422)
@@ -102,7 +102,7 @@
/* 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] =3D { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -112,15 +112,15 @@
U128* pU128_src;
U128* pU128_dst;
=20
- vassert( vD_idx <=3D 31 );
- vassert( sh <=3D 15 );
- vassert( dirn <=3D 1 );
- if (dirn =3D=3D 1) /* shift right */
+ vassert( vD_off <=3D sizeof(VexGuestPPC32State)-8 );
+ vassert( sh <=3D 15 );
+ vassert( shift_right <=3D 1 );
+ if (shift_right)
sh =3D 16-sh;
/* else shift left */
=20
pU128_src =3D (U128*)&ref[sh];
- pU128_dst =3D &gst->guest_VR0 + (vD_idx*sizeof(gst->guest_VR0));
+ pU128_dst =3D (U128*)( ((UChar*)gst) + vD_off );
=20
(*pU128_dst)[0] =3D (*pU128_src)[0];
(*pU128_dst)[1] =3D (*pU128_src)[1];
Modified: trunk/priv/guest-ppc32/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-ppc32/toIR.c 2005-10-20 11:56:00 UTC (rev 1421)
+++ trunk/priv/guest-ppc32/toIR.c 2005-10-22 02:01:16 UTC (rev 1422)
@@ -4966,7 +4966,11 @@
switch (opc2) {
=20
case 0x006: { // lvsl (Load Vector for Shift Left, AV p123)
- IRExpr** args =3D mkIRExprVec_3(mkU32(vD_addr), mkexpr(EA), mkU32(=
0));
+ UInt vD_off =3D vectorGuestRegOffset(vD_addr);
+ IRExpr** args =3D mkIRExprVec_3(
+ mkU32(vD_off),=20
+ binop(Iop_And32, mkexpr(EA), mkU32(0xF)),
+ mkU32(0)/*left*/ );
IRDirty* d =3D unsafeIRDirty_0_N (
0/*regparms*/,=20
"ppc32g_dirtyhelper_LVS",
@@ -4977,7 +4981,7 @@
d->needsBBP =3D True;
d->nFxState =3D 1;
d->fxState[0].fx =3D Ifx_Write;
- d->fxState[0].offset =3D vectorGuestRegOffset(vD_addr);
+ d->fxState[0].offset =3D vD_off;
d->fxState[0].size =3D sizeof(U128);
=20
/* execute the dirty call, side-effecting guest state */
@@ -4985,7 +4989,11 @@
break;
}
case 0x026: { // lvsr (Load Vector for Shift Right, AV p125)
- IRExpr** args =3D mkIRExprVec_3(mkU32(vD_addr), mkexpr(EA), mkU32(=
1));
+ UInt vD_off =3D vectorGuestRegOffset(vD_addr);
+ IRExpr** args =3D mkIRExprVec_3(
+ mkU32(vD_off),=20
+ binop(Iop_And32, mkexpr(EA), mkU32(0xF)),
+ mkU32(1)/*right*/ );
IRDirty* d =3D unsafeIRDirty_0_N (
0/*regparms*/,=20
"ppc32g_dirtyhelper_LVS",
@@ -4996,7 +5004,7 @@
d->needsBBP =3D True;
d->nFxState =3D 1;
d->fxState[0].fx =3D Ifx_Write;
- d->fxState[0].offset =3D vectorGuestRegOffset(vD_addr);
+ d->fxState[0].offset =3D vD_off;
d->fxState[0].size =3D sizeof(U128);
=20
/* execute the dirty call, side-effecting guest state */
@@ -6050,7 +6058,7 @@
/* Splat */
case 0x20C: { // vspltb (Splat Byte, AV p245)
/* vD =3D Dup8x16( vB[UIMM_5] ) */
- UChar sh_uimm =3D (15-UIMM_5)*8;
+ UChar sh_uimm =3D (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,=20
@@ -6058,7 +6066,7 @@
break;
}
case 0x24C: { // vsplth (Splat Half Word, AV p246)
- UChar sh_uimm =3D (7-UIMM_5)*16;
+ UChar sh_uimm =3D (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,=20
@@ -6067,7 +6075,7 @@
}
case 0x28C: { // vspltw (Splat Word, AV p250)
/* vD =3D Dup32x4( vB[UIMM_5] ) */
- UChar sh_uimm =3D (3-UIMM_5)*32;
+ UChar sh_uimm =3D (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,
|