mirror of https://github.com/PCSX2/pcsx2.git
tweaked FPU compare opcode clamping.
this fixes a bug with Digimon rumble arena 2. thanks to Nneeve for figuring out the problem. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@547 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e56eac1862
commit
7e065afb4d
|
@ -404,6 +404,16 @@ void fpuFloat2(int regd) { // +NaN -> +fMax, -NaN -> -fMax, +Inf -> +fMax, -Inf
|
|||
}
|
||||
}
|
||||
|
||||
__forceinline void fpuFloat3(int regd) {
|
||||
// This clamp function used in the recC_xx opcodes
|
||||
// Rule of Rose needs clamping or else it crashes (minss or maxss both fix the crash)
|
||||
// Digimon Rumble Arena 2 needs MAXSS clamping (if you only use minss, it spins on the intro-menus;
|
||||
// it also doesn't like preserving NaN sign with fpuFloat2, so the only way to make Digimon work
|
||||
// is by calling MAXSS first)
|
||||
SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
//SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]);
|
||||
}
|
||||
|
||||
void ClampValues(int regd) {
|
||||
fpuFloat(regd);
|
||||
}
|
||||
|
@ -698,30 +708,30 @@ void recC_EQ_xmm(int info)
|
|||
|
||||
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
|
||||
case PROCESS_EE_S:
|
||||
SSE_MINSS_M32_to_XMM(EEREC_S, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_S);
|
||||
t0reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
if (t0reg >= 0) {
|
||||
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]);
|
||||
SSE_MINSS_M32_to_XMM(t0reg, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(t0reg);
|
||||
SSE_UCOMISS_XMM_to_XMM(EEREC_S, t0reg);
|
||||
_freeXMMreg(t0reg);
|
||||
}
|
||||
else SSE_UCOMISS_M32_to_XMM(EEREC_S, (uptr)&fpuRegs.fpr[_Ft_]);
|
||||
break;
|
||||
case PROCESS_EE_T:
|
||||
SSE_MINSS_M32_to_XMM(EEREC_T, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_T);
|
||||
t0reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
if (t0reg >= 0) {
|
||||
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Fs_]);
|
||||
SSE_MINSS_M32_to_XMM(t0reg, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(t0reg);
|
||||
SSE_UCOMISS_XMM_to_XMM(t0reg, EEREC_T);
|
||||
_freeXMMreg(t0reg);
|
||||
}
|
||||
else SSE_UCOMISS_M32_to_XMM(EEREC_T, (uptr)&fpuRegs.fpr[_Fs_]);
|
||||
break;
|
||||
case (PROCESS_EE_S|PROCESS_EE_T):
|
||||
SSE_MINSS_M32_to_XMM(EEREC_S, (uptr)&g_maxvals[0]);
|
||||
SSE_MINSS_M32_to_XMM(EEREC_T, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_S);
|
||||
fpuFloat3(EEREC_T);
|
||||
SSE_UCOMISS_XMM_to_XMM(EEREC_S, EEREC_T);
|
||||
break;
|
||||
default:
|
||||
|
@ -768,22 +778,22 @@ void recC_LE_xmm(int info )
|
|||
|
||||
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
|
||||
case PROCESS_EE_S:
|
||||
SSE_MINSS_M32_to_XMM(EEREC_S, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_S);
|
||||
t0reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
if (t0reg >= 0) {
|
||||
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]);
|
||||
SSE_MINSS_M32_to_XMM(t0reg, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(t0reg);
|
||||
SSE_UCOMISS_XMM_to_XMM(EEREC_S, t0reg);
|
||||
_freeXMMreg(t0reg);
|
||||
}
|
||||
else SSE_UCOMISS_M32_to_XMM(EEREC_S, (uptr)&fpuRegs.fpr[_Ft_]);
|
||||
break;
|
||||
case PROCESS_EE_T:
|
||||
SSE_MINSS_M32_to_XMM(EEREC_T, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_T);
|
||||
t0reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
if (t0reg >= 0) {
|
||||
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Fs_]);
|
||||
SSE_MINSS_M32_to_XMM(t0reg, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(t0reg);
|
||||
SSE_UCOMISS_XMM_to_XMM(t0reg, EEREC_T);
|
||||
_freeXMMreg(t0reg);
|
||||
}
|
||||
|
@ -800,8 +810,8 @@ void recC_LE_xmm(int info )
|
|||
}
|
||||
break;
|
||||
case (PROCESS_EE_S|PROCESS_EE_T):
|
||||
SSE_MINSS_M32_to_XMM(EEREC_S, (uptr)&g_maxvals[0]);
|
||||
SSE_MINSS_M32_to_XMM(EEREC_T, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_S);
|
||||
fpuFloat3(EEREC_T);
|
||||
SSE_UCOMISS_XMM_to_XMM(EEREC_S, EEREC_T);
|
||||
break;
|
||||
default: // Untested and incorrect, but this case is never reached AFAIK (cottonvibes)
|
||||
|
@ -842,22 +852,22 @@ void recC_LT_xmm(int info)
|
|||
|
||||
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
|
||||
case PROCESS_EE_S:
|
||||
SSE_MINSS_M32_to_XMM(EEREC_S, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_S);
|
||||
t0reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
if (t0reg >= 0) {
|
||||
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]);
|
||||
SSE_MINSS_M32_to_XMM(t0reg, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(t0reg);
|
||||
SSE_UCOMISS_XMM_to_XMM(EEREC_S, t0reg);
|
||||
_freeXMMreg(t0reg);
|
||||
}
|
||||
else SSE_UCOMISS_M32_to_XMM(EEREC_S, (uptr)&fpuRegs.fpr[_Ft_]);
|
||||
break;
|
||||
case PROCESS_EE_T:
|
||||
SSE_MINSS_M32_to_XMM(EEREC_T, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_T);
|
||||
t0reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
if (t0reg >= 0) {
|
||||
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Fs_]);
|
||||
SSE_MINSS_M32_to_XMM(t0reg, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(t0reg);
|
||||
SSE_UCOMISS_XMM_to_XMM(t0reg, EEREC_T);
|
||||
_freeXMMreg(t0reg);
|
||||
}
|
||||
|
@ -874,11 +884,10 @@ void recC_LT_xmm(int info)
|
|||
}
|
||||
break;
|
||||
case (PROCESS_EE_S|PROCESS_EE_T):
|
||||
// Makes NaNs and +Infinity be +maximum; -Infinity stays
|
||||
// the same, but this is okay for a Compare operation.
|
||||
// Clamp NaNs
|
||||
// Note: This fixes a crash in Rule of Rose.
|
||||
SSE_MINSS_M32_to_XMM(EEREC_S, (uptr)&g_maxvals[0]);
|
||||
SSE_MINSS_M32_to_XMM(EEREC_T, (uptr)&g_maxvals[0]);
|
||||
fpuFloat3(EEREC_S);
|
||||
fpuFloat3(EEREC_T);
|
||||
SSE_UCOMISS_XMM_to_XMM(EEREC_S, EEREC_T);
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue