Force the result of single precision arithmetic to have single precision only, also in jit. That is, another attempt at fixing the FPU bug in Zelda.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@251 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-08-20 23:25:48 +00:00
parent adafeaa8b4
commit 77cec36ad4
3 changed files with 23 additions and 2 deletions

View File

@ -24,6 +24,7 @@
#include "Jit.h"
#include "JitCache.h"
#include "JitRegCache.h"
#include "Jit_Util.h"
#define INSTRUCTION_START
// #define INSTRUCTION_START Default(inst); return;
@ -70,9 +71,9 @@ namespace Jit64
MOVSD(fpr.RX(d), Gen::R(XMM0));
}
if (dupe) {
ForceSinglePrecisionS(fpr.RX(d));
MOVDDUP(fpr.RX(d), fpr.R(d));
}
//fpr.SetDirty(fpr.RX(d));
fpr.UnlockAll();
}
@ -106,6 +107,9 @@ namespace Jit64
if (inst.Rc) {
Default(inst); return;
}
bool single_precision = inst.OPCD == 59;
int a = inst.FA;
int b = inst.FB;
int c = inst.FC;
@ -137,7 +141,12 @@ namespace Jit64
fpr.LoadToX64(d, false);
//YES it is necessary to dupe the result :(
//TODO : analysis - does the top reg get used? If so, dupe, if not, don't.
MOVDDUP(fpr.RX(d), Gen::R(XMM0));
if (single_precision) {
ForceSinglePrecisionS(XMM0);
MOVDDUP(fpr.RX(d), R(XMM0));
} else {
MOVSD(fpr.RX(d), R(XMM0));
}
fpr.UnlockAll();
}

View File

@ -127,4 +127,13 @@ void WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address)
#endif
}
void ForceSinglePrecisionS(X64Reg xmm) {
CVTSD2SS(xmm, R(xmm));
CVTSS2SD(xmm, R(xmm));
}
void ForceSinglePrecisionP(X64Reg xmm) {
CVTPD2PS(xmm, R(xmm));
CVTPS2PD(xmm, R(xmm));
}
} // namespace

View File

@ -30,4 +30,7 @@ void SafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSi
void WriteToConstRamAddress(int accessSize, const Gen::OpArg& arg, u32 address);
void WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address);
void ForceSinglePrecisionS(X64Reg xmm);
void ForceSinglePrecisionP(X64Reg xmm);
} // namespace