mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-26 11:48:36 +01:00
Fix vmtvc on ARM, fixing issues with our prefix check. Add some logging.
Also improve vcmp on ARM.
This commit is contained in:
1 parent
a028f07951
commit
58db79672f
5 files changed
+57
-13
No files matched your search
@@ -1016,11 +1016,10 @@ namespace MIPSComp
|
||||
gpr.MapReg(rt, MAP_NOINIT | MAP_DIRTY);
|
||||
VMOV(gpr.R(rt), fpr.V(imm));
|
||||
} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc
|
||||
DISABLE;
|
||||
// In case we have a saved prefix.
|
||||
//FlushPrefixV();
|
||||
//gpr.BindToRegister(rt, false, true);
|
||||
//MOV(32, gpr.R(rt), M(¤tMIPS->vfpuCtrl[imm - 128]));
|
||||
FlushPrefixV();
|
||||
gpr.MapReg(rt, MAP_NOINIT | MAP_DIRTY);
|
||||
LDR(gpr.R(rt), CTXREG, offsetof(MIPSState, vfpuCtrl) + 4 * (imm - 128));
|
||||
} else {
|
||||
//ERROR - maybe need to make this value too an "interlock" value?
|
||||
ERROR_LOG(CPU, "mfv - invalid register %i", imm);
|
||||
@@ -1357,10 +1356,8 @@ namespace MIPSComp
|
||||
|
||||
// Some, we just fall back to the interpreter.
|
||||
switch (cond) {
|
||||
case VC_EN: // c = my_isnan(s[i]); break;
|
||||
case VC_EI: // c = my_isinf(s[i]); break;
|
||||
case VC_ES: // c = my_isnan(s[i]) || my_isinf(s[i]); break; // Tekken Dark Resurrection
|
||||
case VC_NN: // c = !my_isnan(s[i]); break;
|
||||
case VC_NI: // c = !my_isinf(s[i]); break;
|
||||
case VC_NS: // c = !my_isnan(s[i]) && !my_isinf(s[i]); break;
|
||||
DISABLE;
|
||||
@@ -1387,6 +1384,20 @@ namespace MIPSComp
|
||||
ORR(R0, R0, 1 << n);
|
||||
break;
|
||||
|
||||
case VC_EN: // c = my_isnan(s[i]); break; // Tekken 6
|
||||
// Should we involve T? Where I found this used, it compared a register with itself so should be fine.
|
||||
fpr.MapInInV(sregs[i], tregs[i]);
|
||||
VCMP(fpr.V(sregs[i]), fpr.V(tregs[i]));
|
||||
flag = CC_VS; // overflow = unordered : http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204j/Chdhcfbc.html
|
||||
break;
|
||||
|
||||
case VC_NN: // c = !my_isnan(s[i]); break;
|
||||
// Should we involve T? Where I found this used, it compared a register with itself so should be fine.
|
||||
fpr.MapInInV(sregs[i], tregs[i]);
|
||||
VCMP(fpr.V(sregs[i]), fpr.V(tregs[i]));
|
||||
flag = CC_VC; // !overflow = !unordered : http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204j/Chdhcfbc.html
|
||||
break;
|
||||
|
||||
case VC_EQ: // c = s[i] == t[i]
|
||||
fpr.MapInInV(sregs[i], tregs[i]);
|
||||
VCMP(fpr.V(sregs[i]), fpr.V(tregs[i]));
|
||||
|
||||
@@ -168,10 +168,8 @@ void Jit::CompileDelaySlot(int flags)
|
||||
_MSR(true, false, R8); // Restore flags register
|
||||
}
|
||||
|
||||
void Jit::Compile(u32 em_address)
|
||||
{
|
||||
if (GetSpaceLeft() < 0x10000 || blocks.IsFull())
|
||||
{
|
||||
void Jit::Compile(u32 em_address) {
|
||||
if (GetSpaceLeft() < 0x10000 || blocks.IsFull()) {
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
@@ -182,8 +180,11 @@ void Jit::Compile(u32 em_address)
|
||||
|
||||
// Drat. The VFPU hit an uneaten prefix at the end of a block.
|
||||
if (js.startDefaultPrefix && js.MayHavePrefix()) {
|
||||
WARN_LOG(JIT, "Uneaten prefix at end of block: %08x", js.compilerPC - 4);
|
||||
WARN_LOG(JIT, "An uneaten prefix at end of block: %08x", js.compilerPC - 4);
|
||||
js.LogPrefix();
|
||||
|
||||
js.startDefaultPrefix = false;
|
||||
|
||||
// Our assumptions are all wrong so it's clean-slate time.
|
||||
ClearCache();
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
struct JitBlock;
|
||||
|
||||
|
||||
#if defined(PPC)
|
||||
#include "../PPC/PpcJit.h"
|
||||
#elif defined(ARM)
|
||||
|
||||
@@ -85,11 +85,13 @@ namespace MIPSComp {
|
||||
PrefixUnknown();
|
||||
}
|
||||
}
|
||||
|
||||
void PrefixUnknown() {
|
||||
prefixSFlag = PREFIX_UNKNOWN;
|
||||
prefixTFlag = PREFIX_UNKNOWN;
|
||||
prefixDFlag = PREFIX_UNKNOWN;
|
||||
}
|
||||
|
||||
bool MayHavePrefix() const {
|
||||
if (HasUnknownPrefix()) {
|
||||
return true;
|
||||
@@ -100,15 +102,18 @@ namespace MIPSComp {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasUnknownPrefix() const {
|
||||
if (!(prefixSFlag & PREFIX_KNOWN) || !(prefixTFlag & PREFIX_KNOWN) || !(prefixDFlag & PREFIX_KNOWN)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasNoPrefix() const {
|
||||
return (prefixDFlag & PREFIX_KNOWN) && (prefixSFlag & PREFIX_KNOWN) && (prefixTFlag & PREFIX_KNOWN) && (prefixS == 0xE4 && prefixT == 0xE4 && prefixD == 0);
|
||||
}
|
||||
|
||||
void EatPrefix() {
|
||||
if ((prefixSFlag & PREFIX_KNOWN) == 0 || prefixS != 0xE4) {
|
||||
prefixSFlag = PREFIX_KNOWN_DIRTY;
|
||||
@@ -123,13 +128,41 @@ namespace MIPSComp {
|
||||
prefixD = 0x0;
|
||||
}
|
||||
}
|
||||
|
||||
u8 VfpuWriteMask() const {
|
||||
_assert_(prefixDFlag & JitState::PREFIX_KNOWN);
|
||||
return (prefixD >> 8) & 0xF;
|
||||
}
|
||||
|
||||
bool VfpuWriteMask(int i) const {
|
||||
_assert_(prefixDFlag & JitState::PREFIX_KNOWN);
|
||||
return (prefixD >> (8 + i)) & 1;
|
||||
}
|
||||
|
||||
void LogPrefix() {
|
||||
LogSTPrefix("S", prefixS, prefixSFlag);
|
||||
LogSTPrefix("T", prefixT, prefixTFlag);
|
||||
LogDPrefix();
|
||||
}
|
||||
|
||||
private:
|
||||
void LogSTPrefix(const char *name, int p, int pflag) {
|
||||
if ((prefixSFlag & PREFIX_KNOWN) == 0) {
|
||||
ERROR_LOG(JIT, "%s: unknown (%08x %i)", name, p, pflag);
|
||||
} else if (prefixS != 0xE4) {
|
||||
ERROR_LOG(JIT, "%s: %08x flag: %i", name, p, pflag);
|
||||
} else {
|
||||
WARN_LOG(JIT, "%s: %08x flag: %i", name, p, pflag);
|
||||
}
|
||||
}
|
||||
void LogDPrefix() {
|
||||
if ((prefixDFlag & PREFIX_KNOWN) == 0) {
|
||||
ERROR_LOG(JIT, "D: unknown (%08x %i)", prefixD, prefixDFlag);
|
||||
} else if (prefixD != 0) {
|
||||
ERROR_LOG(JIT, "D: (%08x %i)", prefixD, prefixDFlag);
|
||||
} else {
|
||||
WARN_LOG(JIT, "D: %08x flag: %i", prefixD, prefixDFlag);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1560,7 +1560,7 @@ void Jit::Comp_Mftv(MIPSOpcode op) {
|
||||
fpr.StoreFromRegisterV(imm);
|
||||
gpr.BindToRegister(rt, false, true);
|
||||
MOV(32, gpr.R(rt), fpr.V(imm));
|
||||
} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc
|
||||
} else if (imm < 128 + VFPU_CTRL_MAX) { //mfvc
|
||||
// In case we have a saved prefix.
|
||||
FlushPrefixV();
|
||||
gpr.BindToRegister(rt, false, true);
|
||||
|
||||
Reference in new issue
Block a user