From 77cec36ad4ff3f94f966b4731092d6e9f832e713 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Wed, 20 Aug 2008 23:25:48 +0000 Subject: [PATCH] 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 --- .../Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp | 13 +++++++++++-- Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp | 9 +++++++++ Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.h | 3 +++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp index 3dd8774bb4..e359f89c11 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp @@ -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(); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp index 7c152c6bd9..51894cf93d 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp @@ -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 diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.h index 7a7800c5c1..1fb0f1de18 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.h @@ -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 \ No newline at end of file