From b9ffe5dcd10b8e9ddf792f7c124a5a9c5bfe3f14 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Thu, 22 May 2008 22:48:50 +0000 Subject: [PATCH] Fix for Donald Duck crash, some changes by gabest adding more SSE4 functionality --- pcsx2/Hw.c | 5 + pcsx2/Memory.c | 196 +--------- pcsx2/Memory.h | 2 + pcsx2/windows/VCprojects/pcsx2_2005.vcproj | 335 ++---------------- pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 305 +--------------- .../windows/VCprojects/vsprops/common.vsprops | 28 ++ .../windows/VCprojects/vsprops/debug.vsprops | 18 + .../VCprojects/vsprops/devbuild.vsprops | 11 + .../VCprojects/vsprops/release.vsprops | 27 ++ .../VCprojects/vsprops/virtualmem.vsprops | 11 + pcsx2/windows/WinMain.c | 12 +- pcsx2/x86/iCOP2.c | 8 +- pcsx2/x86/iCore.cpp | 19 +- pcsx2/x86/iFPU.c | 2 + pcsx2/x86/iVUmicro.c | 73 ++-- pcsx2/x86/ix86/ix86.h | 3 +- pcsx2/x86/ix86/ix86_sse.c | 9 + 17 files changed, 218 insertions(+), 846 deletions(-) create mode 100644 pcsx2/windows/VCprojects/vsprops/common.vsprops create mode 100644 pcsx2/windows/VCprojects/vsprops/debug.vsprops create mode 100644 pcsx2/windows/VCprojects/vsprops/devbuild.vsprops create mode 100644 pcsx2/windows/VCprojects/vsprops/release.vsprops create mode 100644 pcsx2/windows/VCprojects/vsprops/virtualmem.vsprops diff --git a/pcsx2/Hw.c b/pcsx2/Hw.c index 475b14a..2d1e101 100644 --- a/pcsx2/Hw.c +++ b/pcsx2/Hw.c @@ -1057,12 +1057,17 @@ void hwWrite32(u32 mem, u32 value) { #ifdef HW_LOG HW_LOG("INTC_MASK Write 32bit %x\n", value); #endif +/* for (i=0; i<16; i++) { // reverse on 1 if (value & (1<ContextRecord->ExtendedRegisters; - - assert( pexdata->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION); - - XmmExtendedRegOffset = 160; - - for(i = 0; i < sizeof(pexdata->ContextRecord->ExtendedRegisters)/4; ++i, ++p ) { - if( p[0] == s_testmem[0] && p[1] == s_testmem[1] && p[2] == s_testmem[2] && p[3] == s_testmem[3] ) { - XmmExtendedRegOffset = i*4; - break; - } - } - - pexdata->ContextRecord->Eip += 7; - - return EXCEPTION_CONTINUE_EXECUTION; -} - -#if _MSC_VER < 1400 -#define VC_HANDLER _except_handler3 -#else -#define VC_HANDLER _except_handler4 -#endif - -//C's default exception handler -EXCEPTION_DISPOSITION VC_HANDLER( - struct _EXCEPTION_RECORD *ExceptionRecord, - void * EstablisherFrame, - struct _CONTEXT *ContextRecord, - void * DispatcherContext - ); - -char cpp_handler_instructions[5]; -BOOL saved_handler_instructions = FALSE; - -//Exception handler that replaces C's default handler. -EXCEPTION_DISPOSITION SysPageFaultExceptionFilter( - struct _EXCEPTION_RECORD *ExceptionRecord, - void * EstablisherFrame, - struct _CONTEXT *ContextRecord, - void * DispatcherContext - ); - -#pragma pack(1) -typedef struct _jmp_instr -{ - unsigned char jmp; - DWORD offset; -} jmp_instr; -#pragma pack() - -BOOL WriteMemory(void * loc, void * buffer, int size) -{ - DWORD o2; - HANDLE hProcess = GetCurrentProcess(); - - //change the protection of pages containing range of memory - //[loc, loc+size] to READ WRITE - DWORD old_protection; - - BOOL ret; - ret = VirtualProtectEx(hProcess, loc, size, - PAGE_READWRITE, &old_protection); - if(ret == FALSE) - return FALSE; - - ret = WriteProcessMemory(hProcess, loc, buffer, size, NULL); - - //restore old protection - VirtualProtectEx(hProcess, loc, size, old_protection, &o2); - - return (ret == TRUE); -} - -BOOL ReadMemory(void *loc, void *buffer, DWORD size) -{ - HANDLE hProcess = GetCurrentProcess(); - DWORD bytes_read = 0; - BOOL ret; - ret = ReadProcessMemory(hProcess, loc, buffer, size, &bytes_read); - return (ret == TRUE && bytes_read == size); -} - -BOOL install_my_handler() -{ - void * my_hdlr = SysPageFaultExceptionFilter; - void * cpp_hdlr = VC_HANDLER; - - jmp_instr jmp_my_hdlr; - jmp_my_hdlr.jmp = 0xE9; - - //We actually calculate the offset from __CxxFrameHandler+5 - //as the jmp instruction is 5 byte length. - jmp_my_hdlr.offset = (char*)(my_hdlr) - - ((char*)(cpp_hdlr) + 5); - - if(!saved_handler_instructions) - { - if(!ReadMemory(cpp_hdlr, cpp_handler_instructions, - sizeof(cpp_handler_instructions))) - return FALSE; - saved_handler_instructions = TRUE; - } - - return WriteMemory(cpp_hdlr, &jmp_my_hdlr, sizeof(jmp_my_hdlr)); -} - -BOOL restore_cpp_handler() -{ - if(!saved_handler_instructions) - return FALSE; - else - { - void *loc = VC_HANDLER; - return WriteMemory(loc, cpp_handler_instructions, - sizeof(cpp_handler_instructions)); - } -} - int memInit() { int i; @@ -345,24 +219,6 @@ int memInit() { if (psxInit() == -1) goto eCleanupAndExit; - // figure out xmm reg offset -// __asm movups xmm0, s_testmem -// __try { -// u8* p = 0; -// __asm { -// mov eax, dword ptr [p] -// } -// } -// __except( FindXmmOffsetException( GetExceptionInformation() ) ) { -// } - -//#ifdef WIN32_FILE_MAPPING - if( !install_my_handler() ) { - SysPrintf("Failed to install custom exception handler!\n"); - return -1; - } -//#endif - return 0; eCleanupAndExit: @@ -408,9 +264,6 @@ void memShutdown() VirtualAlloc(PS2MEM_BASE, 0x40000000, MEM_RESERVE, PAGE_NOACCESS); } -#define GET_REGVALUE(code) *((u32*)&pexdata->ContextRecord->Eax + (((code)>>11)&7)) -#define GET_XMMVALUE(xmm) ((u64*)((u8*)pexdata->ContextRecord->ExtendedRegisters + XmmExtendedRegOffset + ((xmm)<<4))) - //NOTE: A lot of the code reading depends on the registers being less than 8 // MOV8 88/8A // MOV16 6689 @@ -420,7 +273,7 @@ void memShutdown() // SSEMtoR128 280f // SSERtoM128 290f -#define SKIP_WRITE(pexdata) { \ +#define SKIP_WRITE() { \ switch(code&0xff) { \ case 0x88: \ if( !(code&0x8000) ) goto DefaultHandler; \ @@ -445,7 +298,7 @@ void memShutdown() } \ } \ -#define SKIP_READ(pexdata) { \ +#define SKIP_READ() { \ switch(code&0xff) { \ case 0x8A: \ if( !(code&0x8000) ) goto DefaultHandler; \ @@ -473,13 +326,11 @@ void memShutdown() } \ } \ -EXCEPTION_DISPOSITION SysPageFaultExceptionFilter( - struct _EXCEPTION_RECORD *ExceptionRecord, - void * EstablisherFrame, - struct _CONTEXT *ContextRecord, - void * DispatcherContext - ) +int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps) { + struct _EXCEPTION_RECORD* ExceptionRecord = eps->ExceptionRecord; + struct _CONTEXT* ContextRecord = eps->ContextRecord; + u32 addr; C_ASSERT(sizeof(ContextRecord->Eax) == 4); @@ -487,12 +338,7 @@ EXCEPTION_DISPOSITION SysPageFaultExceptionFilter( // If the exception is not a page fault, exit. if (ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) { - // call old handler - EXCEPTION_DISPOSITION d; - restore_cpp_handler(); - d = VC_HANDLER(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext); - install_my_handler(); - return d; + return EXCEPTION_CONTINUE_SEARCH; } // get bad virtual address @@ -526,13 +372,13 @@ EXCEPTION_DISPOSITION SysPageFaultExceptionFilter( pmap->aVFNs[0] = addr&~0xfff; if( SysMapUserPhysicalPages((void*)(addr&~0xfff), 1, pmap->aPFNs, 0) ) - return ExceptionContinueExecution; + return EXCEPTION_CONTINUE_EXECUTION; // try allocing the virtual mem pnewaddr = VirtualAlloc((void*)(addr&~0xffff), 0x10000, MEM_RESERVE|MEM_PHYSICAL, PAGE_READWRITE); if( SysMapUserPhysicalPages((void*)(addr&~0xfff), 1, pmap->aPFNs, 0) ) - return ExceptionContinueExecution; + return EXCEPTION_CONTINUE_EXECUTION; SysPrintf("Fatal error, virtual page 0x%x cannot be found %d (p:%x,v:%x)\n", addr-(u32)PS2MEM_BASE, GetLastError(), pmap->aPFNs[0], pmap->aVFNs[0]); @@ -548,39 +394,30 @@ EXCEPTION_DISPOSITION SysPageFaultExceptionFilter( s_psVuMem.aVFNs[1] = addr&~0xfff; SysMapUserPhysicalPages((void*)addr, 1, s_psVuMem.aPFNs, 1); - return ExceptionContinueExecution;//EXCEPTION_CONTINUE_EXECUTION; + return EXCEPTION_CONTINUE_EXECUTION; } } - - { - // call old handler - EXCEPTION_DISPOSITION d; #ifdef VM_HACK + { u32 code = *(u32*)ExceptionRecord->ExceptionAddress; u32 rd = 0; if( ExceptionRecord->ExceptionInformation[0] ) { - //SKIP_WRITE(ptrs); + //SKIP_WRITE(); // shouldn't be writing } else { SysPrintf("vmhack "); - SKIP_READ(ptrs); + SKIP_READ(); //((u32*)&ContextRecord->Eax)[rd] = 0; - return ExceptionContinueExecution; + return EXCEPTION_CONTINUE_EXECUTION; // TODO: verify this!!! } - + } DefaultHandler: #endif - restore_cpp_handler(); - d = VC_HANDLER(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext); - install_my_handler(); - return d; - } - // continue execution - return EXCEPTION_CONTINUE_EXECUTION; + return EXCEPTION_CONTINUE_SEARCH; } #else // linux implementation @@ -3328,3 +3165,4 @@ void memSetUserMode() { #endif } + diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index 9d9ffa2..199d14e 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -231,6 +231,8 @@ int recMemConstWrite32(u32 mem, int mmreg); int recMemConstWrite64(u32 mem, int mmreg); int recMemConstWrite128(u32 mem, int xmmreg); +extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps); + #else #define _eeReadConstMem8 0&& diff --git a/pcsx2/windows/VCprojects/pcsx2_2005.vcproj b/pcsx2/windows/VCprojects/pcsx2_2005.vcproj index 012f926..a7e4bce 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2005.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2005.vcproj @@ -5,6 +5,7 @@ Name="pcsx2" ProjectGUID="{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}" RootNamespace="pcsx2" + TargetFrameworkVersion="131072" > - - - - - - - - - - - - - - - - - - - - @@ -967,8 +752,6 @@ > @@ -1171,90 +954,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -1690,6 +1397,10 @@ RelativePath="..\ps2_silver.bmp" > + + @@ -1700,5 +1411,9 @@ + diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index fbbdadb..d5ecea8 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -1,7 +1,7 @@ - - - - - - - - - - - - - - - @@ -963,8 +752,6 @@ > @@ -1167,90 +954,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/pcsx2/windows/VCprojects/vsprops/debug.vsprops b/pcsx2/windows/VCprojects/vsprops/debug.vsprops new file mode 100644 index 0000000..af6f81c --- /dev/null +++ b/pcsx2/windows/VCprojects/vsprops/debug.vsprops @@ -0,0 +1,18 @@ + + + + + diff --git a/pcsx2/windows/VCprojects/vsprops/devbuild.vsprops b/pcsx2/windows/VCprojects/vsprops/devbuild.vsprops new file mode 100644 index 0000000..5713920 --- /dev/null +++ b/pcsx2/windows/VCprojects/vsprops/devbuild.vsprops @@ -0,0 +1,11 @@ + + + + diff --git a/pcsx2/windows/VCprojects/vsprops/release.vsprops b/pcsx2/windows/VCprojects/vsprops/release.vsprops new file mode 100644 index 0000000..bfc1fe4 --- /dev/null +++ b/pcsx2/windows/VCprojects/vsprops/release.vsprops @@ -0,0 +1,27 @@ + + + + + + diff --git a/pcsx2/windows/VCprojects/vsprops/virtualmem.vsprops b/pcsx2/windows/VCprojects/vsprops/virtualmem.vsprops new file mode 100644 index 0000000..76d0783 --- /dev/null +++ b/pcsx2/windows/VCprojects/vsprops/virtualmem.vsprops @@ -0,0 +1,11 @@ + + + + diff --git a/pcsx2/windows/WinMain.c b/pcsx2/windows/WinMain.c index 22a6fd8..c3a07f9 100644 --- a/pcsx2/windows/WinMain.c +++ b/pcsx2/windows/WinMain.c @@ -430,8 +430,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if( !SysLoggedSetLockPagesPrivilege( GetCurrentProcess(), TRUE ) ) return -1; - - lpMemReserved = VirtualAlloc(PS2MEM_BASE, 0x40000000, MEM_RESERVE, PAGE_NOACCESS); if( lpMemReserved == NULL || lpMemReserved!= PS2MEM_BASE ) { @@ -440,6 +438,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine MessageBox(NULL, str, "SysError", MB_OK); return -1; } + + __try + { + #endif gApp.hInstance = hInstance; @@ -544,6 +546,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine RunGui(); #ifdef PCSX2_VIRTUAL_MEM + + } + __except(SysPageFaultExceptionFilter(GetExceptionInformation())) + { + } + VirtualFree(PS2MEM_BASE, 0, MEM_RELEASE); #endif diff --git a/pcsx2/x86/iCOP2.c b/pcsx2/x86/iCOP2.c index 082c471..f0c7051 100644 --- a/pcsx2/x86/iCOP2.c +++ b/pcsx2/x86/iCOP2.c @@ -291,8 +291,8 @@ static void recCTC2() #ifdef __x86_64__ _callFunctionArg1((uptr)FreezeXMMRegs_, MEM_CONSTTAG, 1); #else - PUSH32I(1); - CALLFunc((uptr)FreezeXMMRegs_); + /*PUSH32I(1); + CALLFunc((uptr)FreezeXMMRegs_);*/ #endif CALLFunc((uptr)Cpu->ExecuteVU0Block); @@ -300,8 +300,8 @@ static void recCTC2() #ifdef __x86_64__ _callFunctionArg1((uptr)FreezeXMMRegs_, MEM_CONSTTAG, 0); #else - PUSH32I(0); - CALLFunc((uptr)FreezeXMMRegs_); + /*PUSH32I(0); + CALLFunc((uptr)FreezeXMMRegs_);*/ ADD32ItoR(ESP, 4); #endif x86SetJ8(j8Ptr[0]); diff --git a/pcsx2/x86/iCore.cpp b/pcsx2/x86/iCore.cpp index 53a90ea..eb42076 100644 --- a/pcsx2/x86/iCore.cpp +++ b/pcsx2/x86/iCore.cpp @@ -1276,26 +1276,16 @@ EEINSTWRITEBACK* _recCheckWriteBack(int cycle) return NULL; } -#ifdef _MSC_VER -extern "C" BOOL install_my_handler(); -typedef void (*TESTFNPTR)(); -#endif - extern "C" void cpudetectSSE3(void* pfnCallSSE3) { cpucaps.hasStreamingSIMD3Extensions = 1; #ifdef _MSC_VER __try { - //__asm call pfnCallSSE3; - ((TESTFNPTR)pfnCallSSE3)(); + ((void (*)())pfnCallSSE3)(); } __except(EXCEPTION_EXECUTE_HANDLER) { cpucaps.hasStreamingSIMD3Extensions = 0; -#ifdef PCSX2_VIRTUAL_MEM - // necessary since can potentially kill the custom handler - install_my_handler(); -#endif } #else // linux @@ -1322,15 +1312,10 @@ return; #ifdef _MSC_VER __try { - //__asm call pfnCallSSE4; - ((TESTFNPTR)pfnCallSSE4)(); + ((void (*)())pfnCallSSE4)(); } __except(EXCEPTION_EXECUTE_HANDLER) { cpucaps.hasStreamingSIMD4Extensions = 0; -#ifdef PCSX2_VIRTUAL_MEM - // necessary since can potentially kill the custom handler - install_my_handler(); -#endif } #else // linux diff --git a/pcsx2/x86/iFPU.c b/pcsx2/x86/iFPU.c index 43fd074..9eeadb9 100644 --- a/pcsx2/x86/iFPU.c +++ b/pcsx2/x86/iFPU.c @@ -842,6 +842,7 @@ int recNonCommutativeOp(int info, int regd, int op) SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Fs_]); recNonComOpXMM_to_XMM[op](t0reg, EEREC_T); SSE_MOVSS_XMM_to_XMM(regd, t0reg); + _freeXMMreg(t0reg); } else { SSE_MOVSS_M32_to_XMM(regd, (uptr)&fpuRegs.fpr[_Fs_]); @@ -855,6 +856,7 @@ int recNonCommutativeOp(int info, int regd, int op) SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_S); recNonComOpXMM_to_XMM[op](t0reg, EEREC_T); SSE_MOVSS_XMM_to_XMM(regd, t0reg); + _freeXMMreg(t0reg); } else if (regd == EEREC_S) { recNonComOpXMM_to_XMM[op](regd, EEREC_T); diff --git a/pcsx2/x86/iVUmicro.c b/pcsx2/x86/iVUmicro.c index 7e495f7..0d3b80c 100644 --- a/pcsx2/x86/iVUmicro.c +++ b/pcsx2/x86/iVUmicro.c @@ -133,41 +133,20 @@ static int SSEmovMask[ 16 ][ 4 ] = void VU_MERGE0(int dest, int src) { // 0000 } void VU_MERGE1(int dest, int src) { // 1000 - if( cpucaps.hasStreamingSIMD4Extensions ) - { - SSE4_INSERTPS_XMM_to_XMM(dest, src, _MM_MK_INSERTPS_NDX(3, 3, 0)); - } - else - { - SSE_MOVHLPS_XMM_to_XMM(src, dest); - SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc4); - } + SSE_MOVHLPS_XMM_to_XMM(src, dest); + SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc4); } void VU_MERGE2(int dest, int src) { // 0100 - if( cpucaps.hasStreamingSIMD4Extensions ) - { - SSE4_INSERTPS_XMM_to_XMM(dest, src, _MM_MK_INSERTPS_NDX(2, 2, 0)); - } - else - { - SSE_MOVHLPS_XMM_to_XMM(src, dest); - SSE_SHUFPS_XMM_to_XMM(dest, src, 0x64); - } + SSE_MOVHLPS_XMM_to_XMM(src, dest); + SSE_SHUFPS_XMM_to_XMM(dest, src, 0x64); } void VU_MERGE3(int dest, int src) { // 1100 SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); } void VU_MERGE4(int dest, int src) { // 0010s - if( cpucaps.hasStreamingSIMD4Extensions ) - { - SSE4_INSERTPS_XMM_to_XMM(dest, src, _MM_MK_INSERTPS_NDX(1, 1, 0)); - } - else - { - SSE_MOVSS_XMM_to_XMM(src, dest); - SSE_SHUFPS_XMM_to_XMM(src, dest, 0xe4); - SSE_MOVAPS_XMM_to_XMM(dest, src); - } + SSE_MOVSS_XMM_to_XMM(src, dest); + SSE_SHUFPS_XMM_to_XMM(src, dest, 0xe4); + SSE_MOVAPS_XMM_to_XMM(dest, src); } void VU_MERGE5(int dest, int src) { // 1010 SSE_SHUFPS_XMM_to_XMM(dest, src, 0xd8); @@ -220,7 +199,7 @@ static VUMERGEFN s_VuMerge[16] = { VU_MERGE4, VU_MERGE5, VU_MERGE6, VU_MERGE7, VU_MERGE8, VU_MERGE9, VU_MERGE10, VU_MERGE11, VU_MERGE12, VU_MERGE13, VU_MERGE14, VU_MERGE15 }; - +/* #define VU_MERGE_REGS(dest, src) { \ if( dest != src ) s_VuMerge[_X_Y_Z_W](dest, src); \ } \ @@ -228,6 +207,29 @@ static VUMERGEFN s_VuMerge[16] = { #define VU_MERGE_REGS_CUSTOM(dest, src, xyzw) { \ if( dest != src ) s_VuMerge[xyzw](dest, src); \ } \ +*/ +void VU_MERGE_REGS_CUSTOM(int dest, int src, int xyzw) +{ + xyzw &= 0xf; + + if(dest != src && xyzw != 0) + { + if(cpucaps.hasStreamingSIMD4Extensions) + { + xyzw = ((xyzw & 1) << 3) | ((xyzw & 2) << 1) | ((xyzw & 4) >> 1) | ((xyzw & 8) >> 3); + + SSE4_BLENDPS_XMM_to_XMM(dest, src, xyzw); + } + else + { + s_VuMerge[xyzw](dest, src); + } + } +} + +#define VU_MERGE_REGS(dest, src) { \ + VU_MERGE_REGS_CUSTOM(dest, src, _X_Y_Z_W); \ +} \ void _unpackVF_xyzw(int dstreg, int srcreg, int xyzw) { @@ -1042,6 +1044,8 @@ void CheckForOverflowSS_(int fdreg, int t0reg) // SSE_ANDPS_XMM_to_XMM(fdreg, t0reg); } + + void CheckForOverflow_(int fdreg, int t0reg, int keepxyzw) { // SSE_MAXPS_M128_to_XMM(fdreg, (u32)g_minvals); @@ -1050,8 +1054,8 @@ void CheckForOverflow_(int fdreg, int t0reg, int keepxyzw) SSE_XORPS_XMM_to_XMM(t0reg, t0reg); SSE_CMPORDPS_XMM_to_XMM(t0reg, fdreg); - if( g_VuNanHandling ) - SSE_ORPS_M128_to_XMM(t0reg, (uptr)s_overflowmask); + /*if( g_VuNanHandling ) + SSE_ORPS_M128_to_XMM(t0reg, (uptr)s_overflowmask);*/ // for partial masks, sometimes regs can be integers if( keepxyzw != 15 ) @@ -1073,13 +1077,14 @@ void CheckForOverflow(VURegs *VU, int info, int regd) } } -// if unordered replaces with 0x7f7fffff (note, loses sign) +// if unordered replaces with 0x7f7fffff void ClampUnordered(int regd, int t0reg, int dosign) { SSE_XORPS_XMM_to_XMM(t0reg, t0reg); SSE_CMPORDPS_XMM_to_XMM(t0reg, regd); + SSE_ORPS_M128_to_XMM(t0reg, (uptr)&const_clip[4]); SSE_ANDPS_XMM_to_XMM(regd, t0reg); - SSE_ANDNPS_M128_to_XMM(t0reg, (u32)g_maxvals); + SSE_ANDNPS_M128_to_XMM(t0reg, (uptr)g_maxvals); SSE_ORPS_XMM_to_XMM(regd, t0reg); } @@ -4553,7 +4558,7 @@ void recVUMI_FCOR( VURegs *VU, int info ) MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1)); //AND32ItoR( EAX, 0xffffff); XOR32RtoR(ftreg, ftreg); - OR32ItoR( EAX, (VU->code & 0xFFFFFF)|0xff000000 ); + OR32ItoR( EAX, VU->code | 0xff000000 ); ADD32ItoR(EAX, 1); // set to 1 if EAX is 0 diff --git a/pcsx2/x86/ix86/ix86.h b/pcsx2/x86/ix86/ix86.h index de8ecfd..b7a233c 100644 --- a/pcsx2/x86/ix86/ix86.h +++ b/pcsx2/x86/ix86/ix86.h @@ -1664,7 +1664,8 @@ void SSE3_MOVSHDUP_M128_to_XMM(x86SSERegType to, uptr from); void SSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); void SSE4_DPPS_M128_to_XMM(x86SSERegType to, uptr from, u8 imm8); void SSE4_INSERTPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); -void SSE4_EXTRACTPS_XMM_to_R32(x86SSERegType to, x86IntRegType from, u8 imm8); +void SSE4_EXTRACTPS_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8); +void SSE4_BLENDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); //********************* // SSE-X - uses both SSE,SSE2 code and tries to keep consistensies between the data diff --git a/pcsx2/x86/ix86/ix86_sse.c b/pcsx2/x86/ix86/ix86_sse.c index 99876f0..04ae911 100644 --- a/pcsx2/x86/ix86/ix86_sse.c +++ b/pcsx2/x86/ix86/ix86_sse.c @@ -1189,6 +1189,15 @@ void SSE4_EXTRACTPS_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8) write8(imm8); } +void SSE4_BLENDPS_XMM_to_XMM(x86IntRegType to, x86SSERegType from, u8 imm8) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x0C3A0F); + ModRM(3, to, from); + write8(imm8); +} + // SSE-X void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from ) {