mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 15:49:25 +01:00
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:
parent
adafeaa8b4
commit
77cec36ad4
@ -24,6 +24,7 @@
|
|||||||
#include "Jit.h"
|
#include "Jit.h"
|
||||||
#include "JitCache.h"
|
#include "JitCache.h"
|
||||||
#include "JitRegCache.h"
|
#include "JitRegCache.h"
|
||||||
|
#include "Jit_Util.h"
|
||||||
|
|
||||||
#define INSTRUCTION_START
|
#define INSTRUCTION_START
|
||||||
// #define INSTRUCTION_START Default(inst); return;
|
// #define INSTRUCTION_START Default(inst); return;
|
||||||
@ -70,9 +71,9 @@ namespace Jit64
|
|||||||
MOVSD(fpr.RX(d), Gen::R(XMM0));
|
MOVSD(fpr.RX(d), Gen::R(XMM0));
|
||||||
}
|
}
|
||||||
if (dupe) {
|
if (dupe) {
|
||||||
|
ForceSinglePrecisionS(fpr.RX(d));
|
||||||
MOVDDUP(fpr.RX(d), fpr.R(d));
|
MOVDDUP(fpr.RX(d), fpr.R(d));
|
||||||
}
|
}
|
||||||
//fpr.SetDirty(fpr.RX(d));
|
|
||||||
fpr.UnlockAll();
|
fpr.UnlockAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,9 @@ namespace Jit64
|
|||||||
if (inst.Rc) {
|
if (inst.Rc) {
|
||||||
Default(inst); return;
|
Default(inst); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool single_precision = inst.OPCD == 59;
|
||||||
|
|
||||||
int a = inst.FA;
|
int a = inst.FA;
|
||||||
int b = inst.FB;
|
int b = inst.FB;
|
||||||
int c = inst.FC;
|
int c = inst.FC;
|
||||||
@ -137,7 +141,12 @@ namespace Jit64
|
|||||||
fpr.LoadToX64(d, false);
|
fpr.LoadToX64(d, false);
|
||||||
//YES it is necessary to dupe the result :(
|
//YES it is necessary to dupe the result :(
|
||||||
//TODO : analysis - does the top reg get used? If so, dupe, if not, don't.
|
//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();
|
fpr.UnlockAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,4 +127,13 @@ void WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address)
|
|||||||
#endif
|
#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
|
} // namespace
|
||||||
|
@ -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 WriteToConstRamAddress(int accessSize, const Gen::OpArg& arg, u32 address);
|
||||||
void WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address);
|
void WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address);
|
||||||
|
|
||||||
|
void ForceSinglePrecisionS(X64Reg xmm);
|
||||||
|
void ForceSinglePrecisionP(X64Reg xmm);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
Loading…
x
Reference in New Issue
Block a user