diff --git a/Core/MIPS/ARM/ArmCompFPU.cpp b/Core/MIPS/ARM/ArmCompFPU.cpp index d57ec09000..1d1957e320 100644 --- a/Core/MIPS/ARM/ArmCompFPU.cpp +++ b/Core/MIPS/ARM/ArmCompFPU.cpp @@ -125,7 +125,7 @@ void Jit::Comp_FPULS(u32 op) SetCC(CC_AL); } #endif - fpr.ReleaseSpillLock(ft); + fpr.ReleaseSpillLocks(); break; case 57: //Memory::Write_U32(FI(ft), addr); break; //swc1 diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index dfc266c33b..5fc5ba4a7e 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -17,8 +17,9 @@ #include -#include "../../MemMap.h" -#include "../MIPSAnalyst.h" +#include "Core/MemMap.h" +#include "Core/MIPS/MIPS.h" +#include "Core/MIPS/MIPSAnalyst.h" #include "Common/CPUDetect.h" #include "Core/Config.h" #include "Core/Reporting.h" @@ -120,7 +121,7 @@ namespace MIPSComp // Prefix may say "z, z, z, z" but if this is a pair, we force to x. // TODO: But some ops seem to use const 0 instead? if (regnum >= n) { - ERROR_LOG_REPORT(CPU, "Invalid VFPU swizzle: %08x / %d", prefix, sz); + WARN_LOG(CPU, "Invalid VFPU swizzle: %08x: %d / %d", prefix, regnum, sz); regnum = 0; } @@ -561,6 +562,7 @@ namespace MIPSComp { CONDITIONAL_DISABLE; DISABLE; + // WARNING: No prefix support! if (js.MayHavePrefix()) { DISABLE; @@ -614,21 +616,21 @@ namespace MIPSComp for (int i = 0; i < n; i++) { if (!IsOverlapSafe(dregs[i], i, n, sregs, n, tregs)) { tempregs[i] = fpr.GetTempV(); - fpr.MapRegV(tempregs[i], MAP_DIRTY | MAP_NOINIT); } else { - fpr.SpillLockV(dregs[i]); - fpr.MapRegV(dregs[i], MAP_DIRTY); tempregs[i] = dregs[i]; } } for (int i = 0; i < n; i++) { + fpr.MapRegV(tempregs[i], MAP_NOINIT); + fpr.SpillLockV(tempregs[i]); fpr.MapInInV(sregs[i], tregs[i]); (this->*triop)(fpr.V(tempregs[i]), fpr.V(sregs[i]), fpr.V(tregs[i])); } for (int i = 0; i < n; i++) { if (dregs[i] != tempregs[i]) { + fpr.MapRegV(dregs[i], MAP_DIRTY | MAP_NOINIT); VMOV(fpr.V(dregs[i]), fpr.V(tempregs[i])); } } @@ -785,7 +787,7 @@ namespace MIPSComp //MOV(32, gpr.R(rt), M(¤tMIPS->vfpuCtrl[imm - 128])); } else { //ERROR - maybe need to make this value too an "interlock" value? - _dbg_assert_msg_(CPU,0,"mfv - invalid register"); + ERROR_LOG(CPU, "mfv - invalid register %i", imm); } } break; @@ -883,28 +885,28 @@ namespace MIPSComp } void Jit::Comp_VScl(u32 op) { + // Darn, still breaks Tekken 6. Bug could be elsewhere though. + fpr.FlushAll(); CONDITIONAL_DISABLE; - DISABLE; if (js.HasUnknownPrefix()) DISABLE; VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); - u8 sregs[4], dregs[4], scale; + u8 sregs[4], dregs[4], treg; GetVectorRegsPrefixS(sregs, sz, _VS); - // TODO: Prefixes seem strange... - GetVectorRegsPrefixT(&scale, V_Single, _VT); + GetVectorRegsPrefixT(&treg, V_Single, _VT); GetVectorRegsPrefixD(dregs, sz, _VD); // Move to S0 early, so we don't have to worry about overlap with scale. - fpr.LoadToRegV(S0, scale); + fpr.LoadToRegV(S0, treg); // For prefixes to work, we just have to ensure that none of the output registers spill // and that there's no overlap. MIPSReg tempregs[4]; for (int i = 0; i < n; ++i) { - if (sregs[i] == dregs[i] || IsOverlapSafe(dregs[i], i, n, sregs)) { + if (sregs[i] != dregs[i] && IsOverlapSafe(dregs[i], i, n, sregs)) { tempregs[i] = dregs[i]; } else { // Need to use temp regs @@ -914,20 +916,20 @@ namespace MIPSComp // The meat of the function! for (int i = 0; i < n; i++) { - fpr.MapDirtyInV(tempregs[i], sregs[i]); - fpr.SpillLockV(tempregs[i]); + fpr.MapDirtyInV(tempregs[i], sregs[i], false); VMUL(fpr.V(tempregs[i]), fpr.V(sregs[i]), S0); } for (int i = 0; i < n; i++) { // All must be mapped for prefixes to work. - fpr.MapRegV(dregs[i], MAP_DIRTY | MAP_NOINIT); if (tempregs[i] != dregs[i]) { + fpr.MapDirtyInV(dregs[i], sregs[i]); VMOV(fpr.V(dregs[i]), fpr.V(tempregs[i])); } } ApplyPrefixD(dregs, sz); + fpr.FlushAll(); fpr.ReleaseSpillLocks(); } @@ -1066,6 +1068,22 @@ namespace MIPSComp DISABLE; } + void Jit::Comp_Vcmp(u32 op) { + DISABLE; + } + + void Jit::Comp_Vcmov(u32 op) { + DISABLE; + } + + void Jit::Comp_Viim(u32 op) { + DISABLE; + } + + void Jit::Comp_Vfim(u32 op) { + DISABLE; + } + void Jit::Comp_Vcst(u32 op) { CONDITIONAL_DISABLE; diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index a68111deb5..c0dbc77720 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -216,6 +216,10 @@ public: void Comp_Vhoriz(u32 op); void Comp_VRot(u32 op); void Comp_VIdt(u32 op); + void Comp_Vcmp(u32 op); + void Comp_Vcmov(u32 op); + void Comp_Viim(u32 op); + void Comp_Vfim(u32 op); JitBlockCache *GetBlockCache() { return &blocks; } diff --git a/Core/MIPS/ARM/ArmRegCacheFPU.cpp b/Core/MIPS/ARM/ArmRegCacheFPU.cpp index 08881cf4b0..a42be9b8bc 100644 --- a/Core/MIPS/ARM/ArmRegCacheFPU.cpp +++ b/Core/MIPS/ARM/ArmRegCacheFPU.cpp @@ -46,7 +46,6 @@ void ArmRegCacheFPU::Start(MIPSAnalyst::AnalysisResults &stats) { static const ARMReg *GetMIPSAllocationOrder(int &count) { // We conservatively reserve both S0 and S1 as scratch for now. - // Will probably really only need one, if that. static const ARMReg allocationOrder[] = { S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15 }; @@ -357,7 +356,7 @@ ARMReg ArmRegCacheFPU::R(int mipsReg) { if (mr[mipsReg].loc == ML_ARMREG) { return (ARMReg)(mr[mipsReg].reg + S0); } else { - ERROR_LOG(JIT, "Reg %i not in arm reg. compilerPC = %08x", mipsReg, compilerPC_); + ERROR_LOG(JIT, "Reg %i not in arm reg. compilerPC = %08x : %s", mipsReg, compilerPC_, currentMIPS->DisasmAt(compilerPC_)); return INVALID_REG; // BAAAD } } diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 02f75117da..18986fe3f4 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -241,3 +241,8 @@ void MIPSState::SWI() { } +const char *MIPSState::DisasmAt(u32 compilerPC) { + static char temp[256]; + MIPSDisAsm(Memory::Read_Instruction(compilerPC), 0, temp); + return temp; +} \ No newline at end of file diff --git a/Core/MIPS/MIPS.h b/Core/MIPS/MIPS.h index 3c31564946..182308db97 100644 --- a/Core/MIPS/MIPS.h +++ b/Core/MIPS/MIPS.h @@ -136,6 +136,9 @@ public: void SingleStep(); int RunLoopUntil(u64 globalTicks); + + // for logging messages only. + const char *DisasmAt(u32 compilerPC); }; diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index eef8cf7711..1d722afe2c 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -500,7 +500,7 @@ const MIPSInstruction tableVFPU1[8] = const MIPSInstruction tableVFPU3[8] = //011011 xxx { - INSTR("vcmp",&Jit::Comp_Generic, Dis_Vcmp, Int_Vcmp, IS_VFPU|OUT_EAT_PREFIX), + INSTR("vcmp",&Jit::Comp_Vcmp, Dis_Vcmp, Int_Vcmp, IS_VFPU|OUT_EAT_PREFIX), {-2}, INSTR("vmin",&Jit::Comp_VecDo3, Dis_VectorSet3, Int_Vminmax, IS_VFPU|OUT_EAT_PREFIX), INSTR("vmax",&Jit::Comp_VecDo3, Dis_VectorSet3, Int_Vminmax, IS_VFPU|OUT_EAT_PREFIX), @@ -530,7 +530,7 @@ const MIPSInstruction tableVFPU4Jump[32] = //110100 xxxxx INSTR("vf2id", &Jit::Comp_Vf2i, Dis_Vf2i, Int_Vf2i, IS_VFPU|OUT_EAT_PREFIX), //20 INSTR("vi2f", &Jit::Comp_Vi2f, Dis_Vf2i, Int_Vi2f, IS_VFPU|OUT_EAT_PREFIX), - INSTR("vcmov", &Jit::Comp_Generic, Dis_Vcmov,Int_Vcmov,IS_VFPU|OUT_EAT_PREFIX), + INSTR("vcmov", &Jit::Comp_Vcmov, Dis_Vcmov,Int_Vcmov,IS_VFPU|OUT_EAT_PREFIX), {-2}, {-2}, @@ -619,8 +619,8 @@ MIPSInstruction tableVFPU5[8] = //110111 xxx INSTR("vpfxt",&Jit::Comp_VPFX, Dis_VPFXST, Int_VPFX, IS_VFPU), INSTR("vpfxd", &Jit::Comp_VPFX, Dis_VPFXD, Int_VPFX, IS_VFPU), INSTR("vpfxd", &Jit::Comp_VPFX, Dis_VPFXD, Int_VPFX, IS_VFPU), - INSTR("viim.s",&Jit::Comp_Generic, Dis_Viim,Int_Viim, IS_VFPU|OUT_EAT_PREFIX), - INSTR("vfim.s",&Jit::Comp_Generic, Dis_Viim,Int_Viim, IS_VFPU|OUT_EAT_PREFIX), + INSTR("viim.s",&Jit::Comp_Viim, Dis_Viim,Int_Viim, IS_VFPU|OUT_EAT_PREFIX), + INSTR("vfim.s",&Jit::Comp_Vfim, Dis_Viim,Int_Viim, IS_VFPU|OUT_EAT_PREFIX), }; const MIPSInstruction tableVFPU6[32] = //111100 xxx diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 78998b2148..a8413d0c25 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -32,8 +32,8 @@ // All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly. // Currently known non working ones should have DISABLE. -// #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocks(); Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocks(); Comp_Generic(op); return; } +// #define CONDITIONAL_DISABLE ; #define DISABLE { fpr.ReleaseSpillLocks(); Comp_Generic(op); return; } @@ -1193,6 +1193,22 @@ void Jit::Comp_Vhoriz(u32 op) { DISABLE; } +void Jit::Comp_Vcmp(u32 op) { + DISABLE; +} + +void Jit::Comp_Vcmov(u32 op) { + DISABLE; +} + +void Jit::Comp_Viim(u32 op) { + DISABLE; +} + +void Jit::Comp_Vfim(u32 op) { + DISABLE; +} + static float sincostemp[2]; void SinCos(float angle) { diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index f52d407c60..31650e83b3 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -223,6 +223,10 @@ public: void Comp_Vhoriz(u32 op); void Comp_VRot(u32 op); void Comp_VIdt(u32 op); + void Comp_Vcmp(u32 op); + void Comp_Vcmov(u32 op); + void Comp_Viim(u32 op); + void Comp_Vfim(u32 op); void Comp_DoNothing(u32 op);