/* 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,
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];
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",
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 */
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",
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 */
/* 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,
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,
}
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,