Index: pcsx2/x86/newVif.h =================================================================== --- pcsx2/x86/newVif.h (revision 3672) +++ pcsx2/x86/newVif.h (working copy) @@ -60,13 +60,14 @@ // struct __aligned16 nVifBlock { u8 num; // [00] Num Field - u8 upkType; // [01] Unpack Type [usn*1:mask*1:upk*4] + u8 upkType; // [01] Unpack Type [alignment*2;usn*1:mask*1:upk*4] u8 mode; // [02] Mode Field u8 scl; // [03] Start Cycle u8 cl; // [04] CL Field u8 wl; // [05] WL Field u32 mask; // [06] Mask Field - u8 padding[2];// [10] through [11] + u8 alignment; // [10] Alignment (32 bit words from 128 bit boundary), only valid for v3/4-32 + u8 padding[1];// [11] uptr startPtr; // [12] Start Ptr of RecGen Code } __packed; // 16 bytes Index: pcsx2/x86/newVif_Dynarec.cpp =================================================================== --- pcsx2/x86/newVif_Dynarec.cpp (revision 3672) +++ pcsx2/x86/newVif_Dynarec.cpp (working copy) @@ -140,6 +140,7 @@ void VifUnpackSSE_Dynarec::CompileRoutine() { const int upkNum = v.vif->cmd & 0xf; + u32 alignment = vB.alignment; const u8& vift = nVifT[upkNum]; const int cycleSize = isFill ? vB.cl : vB.wl; const int blockSize = isFill ? vB.wl : vB.cl; @@ -158,7 +159,7 @@ ShiftDisplacementWindow( dstIndirect, ecx ); if (vCL < cycleSize) { - xUnpack(upkNum); + xUnpack(upkNum, alignment); xMovDest(); dstIndirect += 16; @@ -175,7 +176,7 @@ else if (isFill) { //DevCon.WriteLn("filling mode!"); VifUnpackSSE_Dynarec fill( VifUnpackSSE_Dynarec::FillingWrite( *this ) ); - fill.xUnpack(upkNum); + fill.xUnpack(upkNum, alignment); fill.xMovDest(); dstIndirect += 16; @@ -244,6 +245,7 @@ _vBlock.scl = v.vif->cl; _vBlock.cl = cycle_cl; _vBlock.wl = cycle_wl; + _vBlock.alignment = (v.vif->cmd & 0xf) == 0xc ? ((uptr)data & 12) >> 2 : 3; // Zero out the mask parameter if it's unused -- games leave random junk // values here which cause false recblock cache misses. Index: pcsx2/x86/newVif_UnpackSSE.cpp =================================================================== --- pcsx2/x86/newVif_UnpackSSE.cpp (revision 3672) +++ pcsx2/x86/newVif_UnpackSSE.cpp (working copy) @@ -165,8 +165,11 @@ xPSHUF.D (destReg, destReg, 0x44); //v1v0v1v0 } -void VifUnpackSSE_Base::xUPK_V3_32() const { - xMOV128 (destReg, ptr32[srcIndirect]); +void VifUnpackSSE_Base::xUPK_V3_32(u32 alignment) const { + if (alignment) + xMOV128 (destReg, ptr128[srcIndirect]); + else + xMOVAPS (destReg, ptr128[srcIndirect]); } void VifUnpackSSE_Base::xUPK_V3_16() const { @@ -196,8 +199,11 @@ } } -void VifUnpackSSE_Base::xUPK_V4_32() const { - xMOV128 (destReg, ptr32[srcIndirect]); +void VifUnpackSSE_Base::xUPK_V4_32(u32 alignment) const { + if (alignment) + xMOV128 (destReg, ptr128[srcIndirect]); + else + xMOVAPS (destReg, ptr128[srcIndirect]); } void VifUnpackSSE_Base::xUPK_V4_16() const { @@ -245,7 +251,7 @@ xPSRL.D (destReg, 24); // single AND... } -void VifUnpackSSE_Base::xUnpack( int upknum ) const +void VifUnpackSSE_Base::xUnpack( int upknum, u32 &alignment ) const { switch( upknum ) { @@ -257,11 +263,11 @@ case 5: xUPK_V2_16(); break; case 6: xUPK_V2_8(); break; - case 8: xUPK_V3_32(); break; + case 8: xUPK_V3_32(alignment & 3); alignment += 3; break; case 9: xUPK_V3_16(); break; case 10: xUPK_V3_8(); break; - case 12: xUPK_V4_32(); break; + case 12: xUPK_V4_32(alignment); break; case 13: xUPK_V4_16(); break; case 14: xUPK_V4_8(); break; case 15: xUPK_V4_5(); break; @@ -300,6 +306,7 @@ int usnpart = usn*2*16; int maskpart = mask*16; + u32 alignment = 3; VifUnpackSSE_Simple vpugen( !!usn, !!mask, curCycle ); @@ -310,7 +317,7 @@ if( nVifT[i] == 0 ) continue; ucall = (nVifCall)xGetAlignedCallTarget(); - vpugen.xUnpack(i); + vpugen.xUnpack(i, alignment); vpugen.xMovDest(); xRET(); Index: pcsx2/x86/newVif_UnpackSSE.h =================================================================== --- pcsx2/x86/newVif_UnpackSSE.h (revision 3672) +++ pcsx2/x86/newVif_UnpackSSE.h (working copy) @@ -46,7 +46,7 @@ VifUnpackSSE_Base(); virtual ~VifUnpackSSE_Base() throw() {} - virtual void xUnpack( int upktype ) const; + virtual void xUnpack( int upktype, u32 &alignment ) const; virtual bool IsUnmaskedOp() const=0; virtual void xMovDest() const; @@ -65,11 +65,11 @@ virtual void xUPK_V2_16() const; virtual void xUPK_V2_8() const; - virtual void xUPK_V3_32() const; + virtual void xUPK_V3_32(u32 alignment) const; virtual void xUPK_V3_16() const; virtual void xUPK_V3_8() const; - virtual void xUPK_V4_32() const; + virtual void xUPK_V4_32(u32 alignment) const; virtual void xUPK_V4_16() const; virtual void xUPK_V4_8() const; virtual void xUPK_V4_5() const;