mirror of https://github.com/PCSX2/pcsx2.git
(Patch from firnis) R5900int: As per MIPS documentation, do not modify the destination register if an overflow exception occurs.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4932 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
ae5ee1376c
commit
2e276316c6
|
@ -24,7 +24,7 @@
|
||||||
#include "R5900Exceptions.h"
|
#include "R5900Exceptions.h"
|
||||||
|
|
||||||
|
|
||||||
static __fi s64 _add64_Overflow( s64 x, s64 y )
|
static __fi bool _add64_Overflow( s64 x, s64 y, s64 &ret )
|
||||||
{
|
{
|
||||||
const s64 result = x + y;
|
const s64 result = x + y;
|
||||||
|
|
||||||
|
@ -32,18 +32,21 @@ static __fi s64 _add64_Overflow( s64 x, s64 y )
|
||||||
// which apparently works, and generates compact/fast x86 code too (the
|
// which apparently works, and generates compact/fast x86 code too (the
|
||||||
// other method below is like 5-10 times slower).
|
// other method below is like 5-10 times slower).
|
||||||
|
|
||||||
if( ((~(x^y))&(x^result)) < 0 )
|
if( ((~(x^y))&(x^result)) < 0 ) {
|
||||||
cpuException(0x30, cpuRegs.branch); // fixme: is 0x30 right for overflow??
|
cpuException(0x30, cpuRegs.branch); // fixme: is 0x30 right for overflow??
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// the not-as-fast style!
|
// the not-as-fast style!
|
||||||
//if( ((x >= 0) && (y >= 0) && (result < 0)) ||
|
//if( ((x >= 0) && (y >= 0) && (result < 0)) ||
|
||||||
// ((x < 0) && (y < 0) && (result >= 0)) )
|
// ((x < 0) && (y < 0) && (result >= 0)) )
|
||||||
// cpuException(0x30, cpuRegs.branch);
|
// cpuException(0x30, cpuRegs.branch);
|
||||||
|
|
||||||
return result;
|
ret = result;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __fi s64 _add32_Overflow( s32 x, s32 y )
|
static __fi bool _add32_Overflow( s32 x, s32 y, s64 &ret )
|
||||||
{
|
{
|
||||||
GPR_reg64 result; result.SD[0] = (s64)x + y;
|
GPR_reg64 result; result.SD[0] = (s64)x + y;
|
||||||
|
|
||||||
|
@ -52,10 +55,14 @@ static __fi s64 _add32_Overflow( s32 x, s32 y )
|
||||||
// against bit 31 (leftmost of the lower word).
|
// against bit 31 (leftmost of the lower word).
|
||||||
|
|
||||||
// If bit32 != bit31 then we have an overflow.
|
// If bit32 != bit31 then we have an overflow.
|
||||||
if( (result.UL[0]>>31) != (result.UL[1] & 1) )
|
if( (result.UL[0]>>31) != (result.UL[1] & 1) ) {
|
||||||
cpuException(0x30, cpuRegs.branch);
|
cpuException(0x30, cpuRegs.branch);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return result.SD[0];
|
ret = result.SD[0];
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -266,8 +273,9 @@ void COP1_Unknown() { Console.Warning("Unknown FPU/COP1 opcode called"); }
|
||||||
// Rt = Rs + Im signed [exception on overflow]
|
// Rt = Rs + Im signed [exception on overflow]
|
||||||
void ADDI()
|
void ADDI()
|
||||||
{
|
{
|
||||||
s64 result = _add32_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], _Imm_ );
|
s64 result;
|
||||||
if (!_Rt_) return;
|
bool overflow = _add32_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], _Imm_, result );
|
||||||
|
if (overflow || !_Rt_) return;
|
||||||
cpuRegs.GPR.r[_Rt_].SD[0] = result;
|
cpuRegs.GPR.r[_Rt_].SD[0] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,8 +293,9 @@ void ADDIU()
|
||||||
// of at 32 bits.
|
// of at 32 bits.
|
||||||
void DADDI()
|
void DADDI()
|
||||||
{
|
{
|
||||||
s64 result = _add64_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], _Imm_ );
|
s64 result;
|
||||||
if (!_Rt_) return;
|
bool overflow = _add64_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], _Imm_, result );
|
||||||
|
if (overflow || !_Rt_) return;
|
||||||
cpuRegs.GPR.r[_Rt_].SD[0] = result;
|
cpuRegs.GPR.r[_Rt_].SD[0] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,31 +321,35 @@ void SLTIU() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[
|
||||||
// Rd = Rs + Rt (Exception on Integer Overflow)
|
// Rd = Rs + Rt (Exception on Integer Overflow)
|
||||||
void ADD()
|
void ADD()
|
||||||
{
|
{
|
||||||
s64 result = _add32_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], cpuRegs.GPR.r[_Rt_].SD[0] );
|
s64 result;
|
||||||
if (!_Rd_) return;
|
bool overflow = _add32_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], cpuRegs.GPR.r[_Rt_].SD[0], result );
|
||||||
|
if (overflow || !_Rd_) return;
|
||||||
cpuRegs.GPR.r[_Rd_].SD[0] = result;
|
cpuRegs.GPR.r[_Rd_].SD[0] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DADD()
|
void DADD()
|
||||||
{
|
{
|
||||||
s64 result = _add64_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], cpuRegs.GPR.r[_Rt_].SD[0] );
|
s64 result;
|
||||||
if (!_Rd_) return;
|
bool overflow = _add64_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], cpuRegs.GPR.r[_Rt_].SD[0], result );
|
||||||
|
if (overflow || !_Rd_) return;
|
||||||
cpuRegs.GPR.r[_Rd_].SD[0] = result;
|
cpuRegs.GPR.r[_Rd_].SD[0] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rd = Rs - Rt (Exception on Integer Overflow)
|
// Rd = Rs - Rt (Exception on Integer Overflow)
|
||||||
void SUB()
|
void SUB()
|
||||||
{
|
{
|
||||||
s64 result = _add32_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], -cpuRegs.GPR.r[_Rt_].SD[0] );
|
s64 result;
|
||||||
if (!_Rd_) return;
|
bool overflow = _add32_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], -cpuRegs.GPR.r[_Rt_].SD[0], result );
|
||||||
|
if (overflow || !_Rd_) return;
|
||||||
cpuRegs.GPR.r[_Rd_].SD[0] = result;
|
cpuRegs.GPR.r[_Rd_].SD[0] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rd = Rs - Rt (Exception on Integer Overflow)
|
// Rd = Rs - Rt (Exception on Integer Overflow)
|
||||||
void DSUB()
|
void DSUB()
|
||||||
{
|
{
|
||||||
s64 result = _add64_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], -cpuRegs.GPR.r[_Rt_].SD[0] );
|
s64 result;
|
||||||
if (!_Rd_) return;
|
bool overflow = _add64_Overflow( cpuRegs.GPR.r[_Rs_].SD[0], -cpuRegs.GPR.r[_Rt_].SD[0], result );
|
||||||
|
if (overflow || !_Rd_) return;
|
||||||
cpuRegs.GPR.r[_Rd_].SD[0] = result;
|
cpuRegs.GPR.r[_Rd_].SD[0] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue