Fix vmtvc on ARM, fixing issues with our prefix check. Add some logging.

Also improve vcmp on ARM.
This commit is contained in:
Henrik Rydgard committed 2013-11-08 19:59:11 +01:00
1 parent a028f07951
commit 58db79672f
5 files changed
+57 -13

No files matched your search

+17 -6
View File
@@ -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(&currentMIPS->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]));
+6 -5
View File
@@ -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();
-1
View File
@@ -21,7 +21,6 @@
struct JitBlock;
#if defined(PPC)
#include "../PPC/PpcJit.h"
#elif defined(ARM)
+33
View File
@@ -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);
}
}
};
}
+1 -1
View File
@@ -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);