diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index afe85e848..e2b06abde 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -592,12 +592,22 @@ namespace MIPSComp fpr.ReleaseSpillLocksAndDiscardTemps(); } + void Jit::Comp_Vhoriz(u32 op) { + DISABLE; + + switch ((op >> 16) & 31) { + case 6: // vfad + break; + case 7: // vavg + break; + } + } + void Jit::Comp_VHdp(u32 op) { // Similar to vdot DISABLE; } - void Jit::Comp_VecDo3(u32 op) { CONDITIONAL_DISABLE; @@ -1535,10 +1545,6 @@ namespace MIPSComp fpr.ReleaseSpillLocksAndDiscardTemps(); } - void Jit::Comp_Vhoriz(u32 op) { - DISABLE; - } - static float sincostemp[2]; void SinCos(float angle) { diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 58bc52f38..2922029a1 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -215,31 +215,29 @@ namespace MIPSInt switch (op >> 26) { case 53: //lvl.q/lvr.q - if (addr & 0x3) { - _dbg_assert_msg_(CPU, 0, "Misaligned lvX.q"); - } - if ((op&2) == 0) - { - // It's an LVL - float d[4]; - ReadVector(d, V_Quad, vt); - int offset = (addr >> 2) & 3; - for (int i = 0; i < offset + 1; i++) + if (addr & 0x3) { - d[3 - i] = Memory::Read_Float(addr - i * 4); + _dbg_assert_msg_(CPU, 0, "Misaligned lvX.q"); } - WriteVector(d, V_Quad, vt); - } - else - { - // It's an LVR float d[4]; ReadVector(d, V_Quad, vt); int offset = (addr >> 2) & 3; - for (int i = 0; i < (3 - offset) + 1; i++) + if ((op & 2) == 0) { - d[i] = Memory::Read_Float(addr + 4 * i); + // It's an LVL + for (int i = 0; i < offset + 1; i++) + { + d[3 - i] = Memory::Read_Float(addr - 4 * i); + } + } + else + { + // It's an LVR + for (int i = 0; i < (3 - offset) + 1; i++) + { + d[i] = Memory::Read_Float(addr + 4 * i); + } } WriteVector(d, V_Quad, vt); } @@ -254,33 +252,32 @@ namespace MIPSInt break; case 61: // svl.q/svr.q - if (addr & 0x3) { - _dbg_assert_msg_(CPU, 0, "Misaligned svX.q"); - } - if ((op&2) == 0) - { - // It's an SVL + if (addr & 0x3) + { + _dbg_assert_msg_(CPU, 0, "Misaligned svX.q"); + } float d[4]; ReadVector(d, V_Quad, vt); int offset = (addr >> 2) & 3; - for (int i = 0; i < offset + 1; i++) + if ((op&2) == 0) { - Memory::Write_Float(d[3 - i], addr - i * 4); + // It's an SVL + for (int i = 0; i < offset + 1; i++) + { + Memory::Write_Float(d[3 - i], addr - i * 4); + } } - } - else - { - // It's an SVR - float d[4]; - ReadVector(d, V_Quad, vt); - int offset = (addr >> 2) & 3; - for (int i = 0; i < (3 - offset) + 1; i++) + else { - Memory::Write_Float(d[i], addr + 4 * i); + // It's an SVR + for (int i = 0; i < (3 - offset) + 1; i++) + { + Memory::Write_Float(d[i], addr + 4 * i); + } } + break; } - break; case 62: //sv.q if (addr & 0xF) diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 352c37286..4832c8516 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -162,7 +162,7 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx ..... {VFPU6}, INSTR("sv", &Jit::Comp_SVQ, Dis_SVLRQ, Int_SVQ, IS_VFPU|VFPU_NO_PREFIX), //copU INSTR("sv.q", &Jit::Comp_SVQ, Dis_SVQ, Int_SVQ, IS_VFPU|VFPU_NO_PREFIX), - INSTR("vflush", &Jit::Comp_Generic, Dis_Vflush, Int_Vflush, IS_VFPU|VFPU_NO_PREFIX), + INSTR("vflush", &Jit::Comp_DoNothing, Dis_Vflush, Int_Vflush, IS_VFPU|VFPU_NO_PREFIX), }; const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxxxxx diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 93201d1fe..dc598ddec 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -272,6 +272,73 @@ void Jit::Comp_SVQ(u32 op) switch (op >> 26) { + case 53: //lvl.q/lvr.q + { + if (!g_Config.bFastMemory) { + DISABLE; + } + DISABLE; + + gpr.BindToRegister(rs, true, true); + gpr.FlushLockX(ECX); + u8 vregs[4]; + GetVectorRegs(vregs, V_Quad, vt); + MOV(32, R(EAX), gpr.R(rs)); + ADD(32, R(EAX), Imm32(imm)); +#ifdef _M_IX86 + AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK)); +#endif + MOV(32, R(ECX), R(EAX)); + SHR(32, R(EAX), Imm8(2)); + AND(32, R(EAX), Imm32(0x3)); + CMP(32, R(EAX), Imm32(0)); + FixupBranch next = J_CC(CC_NE); + + fpr.MapRegsV(vregs, V_Quad, MAP_DIRTY); + + // Offset = 0 + MOVSS(fpr.RX(vregs[3]), MRegSum(RBX, RAX)); + + FixupBranch skip0 = J(); + SetJumpTarget(next); + CMP(32, R(EAX), Imm32(1)); + next = J_CC(CC_NE); + + // Offset = 1 + MOVSS(fpr.RX(vregs[3]), MComplex(RBX, RAX, 1, 4)); + MOVSS(fpr.RX(vregs[2]), MComplex(RBX, RAX, 1, 0)); + + FixupBranch skip1 = J(); + SetJumpTarget(next); + CMP(32, R(EAX), Imm32(2)); + next = J_CC(CC_NE); + + // Offset = 2 + MOVSS(fpr.RX(vregs[3]), MComplex(RBX, RAX, 1, 8)); + MOVSS(fpr.RX(vregs[2]), MComplex(RBX, RAX, 1, 4)); + MOVSS(fpr.RX(vregs[1]), MComplex(RBX, RAX, 1, 0)); + + FixupBranch skip2 = J(); + SetJumpTarget(next); + CMP(32, R(EAX), Imm32(3)); + next = J_CC(CC_NE); + + // Offset = 3 + MOVSS(fpr.RX(vregs[3]), MComplex(RBX, RAX, 1, 12)); + MOVSS(fpr.RX(vregs[2]), MComplex(RBX, RAX, 1, 8)); + MOVSS(fpr.RX(vregs[1]), MComplex(RBX, RAX, 1, 4)); + MOVSS(fpr.RX(vregs[0]), MComplex(RBX, RAX, 1, 0)); + + SetJumpTarget(next); + SetJumpTarget(skip0); + SetJumpTarget(skip1); + SetJumpTarget(skip2); + + gpr.UnlockAll(); + fpr.ReleaseSpillLocks(); + } + break; + case 54: //lv.q { gpr.BindToRegister(rs, true, true); @@ -337,6 +404,8 @@ void Jit::Comp_SVQ(u32 op) } break; + + default: DISABLE; break; diff --git a/Core/MemMap.h b/Core/MemMap.h index 152ab7bba..71a2a2197 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -222,12 +222,20 @@ void Memset(const u32 _Address, const u8 _Data, const u32 _iLength); inline void Memcpy(const u32 to_address, const void *from_data, const u32 len) { - memcpy(GetPointer(to_address), from_data, len); + u8 *to = GetPointer(to_address); + if (to) { + memcpy(to, from_data, len); + } + // if not, GetPointer will log. } inline void Memcpy(void *to_data, const u32 from_address, const u32 len) { - memcpy(to_data, GetPointer(from_address), len); + const u8 *from = GetPointer(from_address); + if (from) { + memcpy(to_data, from, len); + } + // if not, GetPointer will log. } inline void MemcpyUnchecked(void *to_data, const u32 from_address, const u32 len)