mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Correct divide by zero HI/LO values a bit.
Interpreter is now correct, but it's probably not all that important to get right in jit.
This commit is contained in:
parent
4ac773e8b4
commit
a05ae2a0a6
5 changed files with 25 additions and 19 deletions
|
@ -760,9 +760,9 @@ namespace MIPSComp
|
|||
if (gpr.IsImm(rt) && (gpr.GetImm(rt) & (gpr.GetImm(rt) - 1)) == 0) {
|
||||
u32 denominator = gpr.GetImm(rt);
|
||||
if (denominator == 0) {
|
||||
// TODO: Is this correct?
|
||||
gpr.SetImm(MIPS_REG_LO, 0);
|
||||
gpr.SetImm(MIPS_REG_HI, 0);
|
||||
gpr.MapDirtyIn(MIPS_REG_HI, rs);
|
||||
gpr.SetImm(MIPS_REG_LO, -1);
|
||||
MOV(gpr.R(MIPS_REG_HI), gpr.R(rs));
|
||||
} else {
|
||||
gpr.MapDirtyDirtyIn(MIPS_REG_LO, MIPS_REG_HI, rs);
|
||||
// Remainder is just an AND, neat.
|
||||
|
|
|
@ -636,8 +636,8 @@ void Arm64Jit::Comp_MulDivType(MIPSOpcode op) {
|
|||
if (gpr.IsImm(rt) && (gpr.GetImm(rt) & (gpr.GetImm(rt) - 1)) == 0) {
|
||||
u32 denominator = gpr.GetImm(rt);
|
||||
if (denominator == 0) {
|
||||
// TODO: Is this correct?
|
||||
gpr.SetImm(MIPS_REG_LO, 0);
|
||||
// TODO: This isn't exactly right.
|
||||
gpr.SetImm(MIPS_REG_LO, -1);
|
||||
} else {
|
||||
gpr.MapDirtyIn(MIPS_REG_LO, rs);
|
||||
// Remainder is just an AND, neat.
|
||||
|
|
|
@ -294,6 +294,7 @@ void IRFrontend::Comp_Allegrex2(MIPSOpcode op) {
|
|||
CONDITIONAL_DISABLE;
|
||||
MIPSGPReg rt = _RT;
|
||||
MIPSGPReg rd = _RD;
|
||||
|
||||
// Don't change $zr.
|
||||
if (rd == 0)
|
||||
return;
|
||||
|
|
|
@ -660,11 +660,13 @@ namespace MIPSInt
|
|||
s32 b = (s32)R(rt);
|
||||
if (a == (s32)0x80000000 && b == -1) {
|
||||
LO = 0x80000000;
|
||||
HI = -1;
|
||||
} else if (b != 0) {
|
||||
LO = (u32)(a / b);
|
||||
HI = (u32)(a % b);
|
||||
} else {
|
||||
LO = HI = 0; // Not sure what the right thing to do is?
|
||||
LO = a < 0 ? 1 : -1;
|
||||
HI = a;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -672,12 +674,12 @@ namespace MIPSInt
|
|||
{
|
||||
u32 a = R(rs);
|
||||
u32 b = R(rt);
|
||||
if (b != 0)
|
||||
{
|
||||
if (b != 0) {
|
||||
LO = (a/b);
|
||||
HI = (a%b);
|
||||
} else {
|
||||
LO = HI = 0;
|
||||
LO = a <= 0xFFFF ? 0xFFFF : -1;
|
||||
HI = a;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1002,6 +1002,9 @@ namespace MIPSComp
|
|||
// For CMP.
|
||||
gpr.KillImmediate(rs, true, false);
|
||||
gpr.KillImmediate(rt, true, false);
|
||||
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
|
||||
CMP(32, gpr.R(rt), Imm32(0));
|
||||
FixupBranch divZero = J_CC(CC_E);
|
||||
|
||||
|
@ -1010,14 +1013,13 @@ namespace MIPSComp
|
|||
FixupBranch notOverflow = J_CC(CC_NE);
|
||||
CMP(32, gpr.R(rt), Imm32((u32) -1));
|
||||
FixupBranch notOverflow2 = J_CC(CC_NE);
|
||||
// TODO: Should HI be set to anything?
|
||||
MOV(32, gpr.R(MIPS_REG_LO), Imm32(0x80000000));
|
||||
MOV(32, gpr.R(MIPS_REG_HI), Imm32(-1));
|
||||
FixupBranch skip2 = J();
|
||||
|
||||
SetJumpTarget(notOverflow);
|
||||
SetJumpTarget(notOverflow2);
|
||||
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
CDQ();
|
||||
IDIV(32, gpr.R(rt));
|
||||
MOV(32, gpr.R(MIPS_REG_HI), R(EDX));
|
||||
|
@ -1025,9 +1027,9 @@ namespace MIPSComp
|
|||
FixupBranch skip = J();
|
||||
|
||||
SetJumpTarget(divZero);
|
||||
// TODO: Is this the right way to handle a divide by zero?
|
||||
MOV(32, gpr.R(MIPS_REG_HI), Imm32(0));
|
||||
MOV(32, gpr.R(MIPS_REG_LO), Imm32(0));
|
||||
// TODO: This isn't exactly right.
|
||||
MOV(32, gpr.R(MIPS_REG_HI), R(EAX));
|
||||
MOV(32, gpr.R(MIPS_REG_LO), Imm32(-1));
|
||||
|
||||
SetJumpTarget(skip);
|
||||
SetJumpTarget(skip2);
|
||||
|
@ -1041,20 +1043,21 @@ namespace MIPSComp
|
|||
gpr.KillImmediate(MIPS_REG_HI, false, true);
|
||||
gpr.KillImmediate(MIPS_REG_LO, false, true);
|
||||
gpr.KillImmediate(rt, true, false);
|
||||
CMP(32, gpr.R(rt), Imm32(0));
|
||||
FixupBranch divZero = J_CC(CC_E);
|
||||
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
MOV(32, R(EDX), Imm32(0));
|
||||
|
||||
CMP(32, gpr.R(rt), Imm32(0));
|
||||
FixupBranch divZero = J_CC(CC_E);
|
||||
|
||||
DIV(32, gpr.R(rt));
|
||||
MOV(32, gpr.R(MIPS_REG_HI), R(EDX));
|
||||
MOV(32, gpr.R(MIPS_REG_LO), R(EAX));
|
||||
FixupBranch skip = J();
|
||||
|
||||
SetJumpTarget(divZero);
|
||||
// TODO: Is this the right way to handle a divide by zero?
|
||||
MOV(32, gpr.R(MIPS_REG_HI), Imm32(0));
|
||||
MOV(32, gpr.R(MIPS_REG_LO), Imm32(0));
|
||||
MOV(32, gpr.R(MIPS_REG_HI), R(EAX));
|
||||
MOV(32, gpr.R(MIPS_REG_LO), Imm32(-1));
|
||||
|
||||
SetJumpTarget(skip);
|
||||
gpr.UnlockAllX();
|
||||
|
|
Loading…
Add table
Reference in a new issue