Android project - R5900.cpp => Fixed game delay error in nextIopEventDeta variable of _cpuEventTest_Shared()

This commit is contained in:
k2154
2025-08-14 01:12:19 +09:00
parent 88a29b09bc
commit 27c88458f3
20 changed files with 201 additions and 175 deletions
+3 -1
View File
@@ -286,7 +286,9 @@ namespace PageFaultHandler
void HostSys::FlushInstructionCache(void* address, u32 size)
{
__builtin___clear_cache(reinterpret_cast<char*>(address), reinterpret_cast<char*>(address) + size);
char* start = static_cast<char*>(address);
char* end = start + size;
__builtin___clear_cache(start, end);
}
[[maybe_unused]] static bool IsStoreInstruction(const void* ptr)
+30 -14
View File
@@ -501,27 +501,16 @@ void armBind(a64::Label* p_label)
}
}
u32 armEmitJmpPtr(void* code, const void* dst, bool flush_icache)
void armEmitJmpPtr(void* code, const void* dst, bool flush_icache)
{
const s64 displacement = GetPCDisplacement(code, dst);
bool use_blr = !vixl::IsInt26(displacement);
if (use_blr)
{
armAsm->Mov(RXVIXLSCRATCH, reinterpret_cast<uintptr_t>(dst));
armAsm->Br(RXVIXLSCRATCH);
}
else
{
u32 new_code = a64::B | a64::Assembler::ImmUncondBranch(displacement);
std::memcpy(code, &new_code, sizeof(new_code));
}
u32 new_code = a64::B | a64::Assembler::ImmUncondBranch(displacement);
std::memcpy(code, &new_code, sizeof(new_code));
if (flush_icache) {
HostSys::FlushInstructionCache(code, a64::kInstructionSize);
}
return a64::kInstructionSize;
}
a64::Register armLoadPtr(const void* addr)
@@ -670,6 +659,12 @@ void armLoadsw(const a64::Register& regRt, a64::MemOperand offset)
armAsm->Ldrsw(regRt, offset);
}
a64::Register armLoadsw(a64::MemOperand offset)
{
armAsm->Ldrsw(EEX, offset);
return EEX;
}
void armLoad(const a64::VRegister& regRt, a64::MemOperand offset)
{
armAsm->Ldr(regRt, offset);
@@ -790,6 +785,17 @@ void armAddsh(const a64::Register& p_reg, const void* p_mop, a64::Operand p_valu
armAsm->Strh(p_reg, memop);
}
void armSub(a64::MemOperand p_mop, const a64::Register& p_value, bool p_flagUpdate)
{
armLoadsw(EEX, p_mop);
if(p_flagUpdate) {
armAsm->Subs(EEX, EEX, p_value);
} else {
armAsm->Sub(EEX, EEX, p_value);
}
armStore(p_mop, EEX);
}
void armSub(a64::MemOperand p_mop, a64::Operand p_value, bool p_flagUpdate)
{
armLoadsw(EEX, p_mop);
@@ -1053,3 +1059,13 @@ void armShuffle(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int
////
armShuffleTblx(dstreg, srcreg, shuffle_0, shuffle_1, shuffle_2, shuffle_3, p_is_tbx);
}
int find_bit_pos(uint32_t p_hex_value)
{
for (int i = 0; i < 32; ++i) {
if ((p_hex_value >> i) & 1) {
return i;
}
}
return 0;
}
+9 -1
View File
@@ -58,6 +58,8 @@ namespace a64 = vixl::aarch64;
// fastmem
#define RFASTMEMBASE a64::x25
#define RSTATE_x26 a64::x26
// CPU(iR5900), PSX(iR3000A), FPU(iFPU, iFPUd)
#define RSTATE_CPU a64::x27
#define RSTATE_PSX a64::x28
@@ -67,6 +69,8 @@ namespace a64 = vixl::aarch64;
#define RSTATE_MVU a64::x28
#define PTR_MVU(field) a64::MemOperand(RSTATE_MVU, offsetof(vuRegistersPack, field))
// iopMem->Main
#define RSTATE_x29 a64::x29
static inline s64 GetPCDisplacement(const void* current, const void* target)
{
@@ -173,7 +177,7 @@ private:
//////////////////////////////////////////////////////////////////////////
void armBind(a64::Label* p_label);
u32 armEmitJmpPtr(void* code, const void* dst, bool flush_icache=true);
void armEmitJmpPtr(void* code, const void* dst, bool flush_icache=true);
a64::Register armLoadPtr(const void* addr);
a64::Register armLoadPtr64(const void* addr);
@@ -199,6 +203,7 @@ void armLoad(const a64::Register& regRt, a64::MemOperand offset);
void armLoadh(const a64::Register& regRt, a64::MemOperand offset);
void armLoadsh(const a64::Register& regRt, a64::MemOperand offset);
void armLoadsw(const a64::Register& regRt, a64::MemOperand offset);
a64::Register armLoadsw(a64::MemOperand offset);
void armLoad(const a64::VRegister& regRt, a64::MemOperand offset);
a64::Register armLoad(a64::MemOperand offset);
a64::Register armLoad64(a64::MemOperand offset);
@@ -217,6 +222,7 @@ void armAdd(const a64::Register& p_reg, const void* p_mop, a64::Operand p_value)
void armAddh(const a64::Register& p_reg, const void* p_mop, a64::Operand p_value, bool p_flagUpdate=false);
void armAddsh(const a64::Register& p_reg, const void* p_mop, a64::Operand p_value, bool p_flagUpdate=false);
void armSub(a64::MemOperand p_mop, const a64::Register& p_value, bool p_flagUpdate=false);
void armSub(a64::MemOperand p_mop, a64::Operand p_value, bool p_flagUpdate=false);
void armSub(const a64::Register& p_reg, a64::MemOperand p_mop, a64::Operand p_value, bool p_flagUpdate=false);
void armSub(const void* p_mop, a64::Operand p_value);
@@ -248,3 +254,5 @@ void armSHUFPS(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int p
void armPSHUFD(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex);
void armShuffleTblx(const a64::VRegister& p_dst, const a64::VRegister& p_src, int p_a, int p_b, int p_c, int p_d, bool p_is_tbx);
void armShuffle(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex, bool p_is_tbx);
int find_bit_pos(uint32_t p_hex_value);
+5
View File
@@ -136,8 +136,13 @@ __fi void PSX_INT( IopEventId n, s32 ecycle )
psxRegs.eCycle[n] = ecycle;
psxSetNextBranchDelta(ecycle);
#if defined(ANDROID)
const s32 iopDelta = (psxRegs.iopNextEventCycle - psxRegs.cycle) << 3; // cycle * 8
#else
const float mutiplier = static_cast<float>(PS2CLK) / static_cast<float>(PSXCLK);
const s32 iopDelta = (psxRegs.iopNextEventCycle - psxRegs.cycle) * mutiplier;
#endif
if (psxRegs.iopCycleEE < iopDelta)
{
+21 -16
View File
@@ -433,23 +433,28 @@ __fi void _cpuEventTest_Shared()
CpuVU0->ExecuteBlock();
CpuVU1->ExecuteBlock();
// ---- Schedule Next Event Test --------------
const float mutiplier = static_cast<float>(PS2CLK) / static_cast<float>(PSXCLK);
const int nextIopEventDeta = ((psxRegs.iopNextEventCycle - psxRegs.cycle) * mutiplier);
// 8 or more cycles behind and there's an event scheduled
if (EEsCycle >= nextIopEventDeta)
{
// EE's running way ahead of the IOP still, so we should branch quickly to give the
// IOP extra timeslices in short order.
// ---- Schedule Next Event Test --------------
#if defined(ANDROID)
const s32 nextIopEventDeta = (psxRegs.iopNextEventCycle - psxRegs.cycle);
#else
const float mutiplier = static_cast<float>(PS2CLK) / static_cast<float>(PSXCLK);
const s32 nextIopEventDeta = ((psxRegs.iopNextEventCycle - psxRegs.cycle) * mutiplier);
#endif
cpuSetNextEventDelta(48);
//Console.Warning( "EE ahead of the IOP -- Rapid Event! %d", EEsCycle );
}
else
{
// Otherwise IOP is caught up/not doing anything so we can wait for the next event.
cpuSetNextEventDelta(((psxRegs.iopNextEventCycle - psxRegs.cycle) * mutiplier) - EEsCycle);
}
// 8 or more cycles behind and there's an event scheduled
if (EEsCycle >= nextIopEventDeta)
{
// EE's running way ahead of the IOP still, so we should branch quickly to give the
// IOP extra timeslices in short order.
cpuSetNextEventDelta(48);
//Console.Warning( "EE ahead of the IOP -- Rapid Event! %d", EEsCycle );
}
else
{
// Otherwise IOP is caught up/not doing anything so we can wait for the next event.
cpuSetNextEventDelta(nextIopEventDeta - EEsCycle);
}
// Apply vsync and other counter nextCycles
cpuSetNextEvent(nextStartCounter, nextDeltaCounter);
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-3.0
#include "arm64/Vif_UnpackNEON.h"
#include "arm64/AsmHelpers.h"
#include "MTVU.h"
#include "common/Assertions.h"
@@ -6,7 +6,7 @@
#include "Common.h"
#include "Vif_Dma.h"
#include "Vif_Dynarec.h"
#include "arm64/AsmHelpers.h"
#include "common/arm64/AsmHelpers.h"
#define xmmCol0 vixl::aarch64::q2
#define xmmCol1 vixl::aarch64::q3
+2 -2
View File
@@ -337,7 +337,7 @@ void recMTC0()
switch (_Rd_)
{
case 12:
_eeMoveGPRtoR(a64::XRegister(RAX), _Rt_);
_eeMoveGPRtoR(RAX, _Rt_);
iFlushCall(FLUSH_INTERPRETER);
// xMOV(eax, ptr32[&cpuRegs.cycle]);
// xADD(eax, scaleblockcycles_clear());
@@ -348,7 +348,7 @@ void recMTC0()
break;
case 16:
_eeMoveGPRtoR(a64::XRegister(RAX), _Rt_);
_eeMoveGPRtoR(RAX, _Rt_);
iFlushCall(FLUSH_INTERPRETER);
// xFastCall((void*)WriteCP0Config);
armEmitCall(reinterpret_cast<const void*>(WriteCP0Config));
+6 -4
View File
@@ -238,6 +238,8 @@ static const void* _DynGen_EnterRecompiledCode()
armBeginStackFrame();
#endif
armMoveAddressToReg(RSTATE_x29, iopMem->Main);
// xJMP((void*)iopDispatcherReg);
armEmitJmp(iopDispatcherReg);
@@ -1240,7 +1242,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
// xADD(eax, edx);
armAsm->Add(EAX, EAX, EDX);
// xCMP(eax, ptr32[&psxRegs.iopNextEventCycle]);
armLoad(EEX, PTR_CPU(psxRegs.iopNextEventCycle));
armLoadsw(EEX, PTR_CPU(psxRegs.iopNextEventCycle));
armAsm->Cmp(EAX, EEX);
// xCMOVNS(eax, ptr32[&psxRegs.iopNextEventCycle]);
armAsm->Csel(EAX, EEX, EAX, a64::Condition::pl);
@@ -1260,7 +1262,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
if (newpc != 0xffffffff)
{
// xCMP(ptr32[&psxRegs.pc], newpc);
armAsm->Cmp(armLoad(PTR_CPU(psxRegs.pc)), newpc);
armAsm->Cmp(armLoadsw(PTR_CPU(psxRegs.pc)), newpc);
// xJNE(iopDispatcherReg);
armEmitCondBranch(a64::Condition::ne, iopDispatcherReg);
}
@@ -1279,7 +1281,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
// check if an event is pending
// xSUB(ebx, ptr32[&psxRegs.iopNextEventCycle]);
armAsm->Subs(EBX, EBX, armLoad(PTR_CPU(psxRegs.iopNextEventCycle)));
armAsm->Subs(EBX, EBX, armLoadsw(PTR_CPU(psxRegs.iopNextEventCycle)));
// xForwardJS<u8> nointerruptpending;
a64::Label nointerruptpending;
armAsm->B(&nointerruptpending, a64::Condition::mi);
@@ -1290,7 +1292,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
if (newpc != 0xffffffff)
{
// xCMP(ptr32[&psxRegs.pc], newpc);
armAsm->Cmp(armLoad(PTR_CPU(psxRegs.pc)), newpc);
armAsm->Cmp(armLoadsw(PTR_CPU(psxRegs.pc)), newpc);
// xJNE(iopDispatcherReg);
armEmitCondBranch(a64::Condition::ne, iopDispatcherReg);
}
+2 -4
View File
@@ -1362,9 +1362,8 @@ static void rpsxLoad(int size, bool sign)
// xTEST(arg1regd, 0x10000000);
// xForwardJZ8 is_ram_read;
armAsm->Tst(EAX, 0x10000000);
a64::Label is_ram_read;
armAsm->B(&is_ram_read, a64::Condition::eq);
armAsm->Tbz(EAX, 28, &is_ram_read); // 28 = find_bit_pos(0x10000000)
switch (size)
{
@@ -1404,8 +1403,7 @@ static void rpsxLoad(int size, bool sign)
armAsm->And(EAX, EAX, 0x1fffff);
// auto addr = xComplexAddress(rax, iopMem->Main, arg1reg);
armMoveAddressToReg(RXVIXLSCRATCH, iopMem->Main);
auto addr = a64::MemOperand(RXVIXLSCRATCH, RAX);
const auto addr = a64::MemOperand(RSTATE_x29, RAX);
switch (size)
{
case 8:
+1 -2
View File
@@ -107,8 +107,7 @@ alignas(16) extern GPR_reg64 g_cpuConstRegs[32];
extern u32 g_cpuHasConstReg, g_cpuFlushedConstReg;
// finds where the GPR is stored and moves lower 32 bits to EAX
void _eeMoveGPRtoR(const a64::WRegister& to, int fromgpr, bool allow_preload = true);
void _eeMoveGPRtoR(const a64::XRegister& to, int fromgpr, bool allow_preload = true);
void _eeMoveGPRtoR(const a64::Register& to, int fromgpr, bool allow_preload = true);
void _eeMoveGPRtoM(uptr to, int fromgpr); // 32-bit only
void _eeFlushAllDirty();
+2 -2
View File
@@ -152,7 +152,7 @@ void recMTSAB()
}
else
{
_eeMoveGPRtoR(a64::WRegister(EAX), _Rs_);
_eeMoveGPRtoR(EAX, _Rs_);
// xAND(eax, 0xF);
armAsm->And(EAX, EAX, 0xF);
// xXOR(eax, _Imm_ & 0xf);
@@ -171,7 +171,7 @@ void recMTSAH()
}
else
{
_eeMoveGPRtoR(a64::WRegister(EAX), _Rs_);
_eeMoveGPRtoR(EAX, _Rs_);
// xAND(eax, 0x7);
armAsm->And(EAX, EAX, 0x7);
// xXOR(eax, _Imm_ & 0x7);
+41 -54
View File
@@ -234,54 +234,26 @@ void _eeFlushAllDirty()
_flushConstRegs(false);
}
void _eeMoveGPRtoR(const a64::WRegister& to, int fromgpr, bool allow_preload)
void _eeMoveGPRtoR(const a64::Register& to, int fromgpr, bool allow_preload)
{
if (fromgpr == 0) {
// xXOR(to, to);
armAsm->Eor(to, to, to);
if(to.IsW()) {
// xXOR(to, to);
armAsm->Eor(to, to, to);
} else {
// xXOR(xRegister32(to), xRegister32(to));
auto reg32 = a64::WRegister(to);
armAsm->Eor(reg32, reg32, reg32);
}
}
else if (GPR_IS_CONST1(fromgpr)) {
if(to.IsW()) {
// xMOV(to, g_cpuConstRegs[fromgpr].UL[0]);
armAsm->Mov(to, g_cpuConstRegs[fromgpr].UL[0]);
}
else
{
int x86reg = _checkX86reg(X86TYPE_GPR, fromgpr, MODE_READ);
int xmmreg = _checkXMMreg(XMMTYPE_GPRREG, fromgpr, MODE_READ);
if (allow_preload && x86reg < 0 && xmmreg < 0)
{
if (EEINST_XMMUSEDTEST(fromgpr))
xmmreg = _allocGPRtoXMMreg(fromgpr, MODE_READ);
else if (EEINST_USEDTEST(fromgpr))
x86reg = _allocX86reg(X86TYPE_GPR, fromgpr, MODE_READ);
}
if (x86reg >= 0) {
// xMOV(to, xRegister32(x86reg));
armAsm->Mov(to, a64::WRegister(x86reg));
}
else if (xmmreg >= 0) {
// xMOVD(to, xRegisterSSE(xmmreg));
armAsm->Fmov(to, a64::QRegister(xmmreg).S());
}
else {
// xMOV(to, ptr[&cpuRegs.GPR.r[fromgpr].UL[0]]);
armLoad(to, PTR_CPU(cpuRegs.GPR.r[fromgpr].UL[0]));
}
}
}
void _eeMoveGPRtoR(const a64::XRegister& to, int fromgpr, bool allow_preload)
{
if (fromgpr == 0) {
// xXOR(xRegister32(to), xRegister32(to));
auto reg32 = a64::WRegister(to);
armAsm->Eor(reg32, reg32, reg32);
}
else if (GPR_IS_CONST1(fromgpr)) {
armAsm->Mov(to, g_cpuConstRegs[fromgpr].UL[0]);
} else {
// xMOV64(to, g_cpuConstRegs[fromgpr].UD[0]);
armAsm->Mov(to, g_cpuConstRegs[fromgpr].UD[0]);
armAsm->Mov(to, g_cpuConstRegs[fromgpr].UD[0]);
}
}
else
{
@@ -297,16 +269,31 @@ void _eeMoveGPRtoR(const a64::XRegister& to, int fromgpr, bool allow_preload)
}
if (x86reg >= 0) {
if(to.IsW()) {
// xMOV(to, xRegister32(x86reg));
armAsm->Mov(to, a64::WRegister(x86reg));
} else {
// xMOV(to, xRegister64(x86reg));
armAsm->Mov(to, a64::XRegister(x86reg));
armAsm->Mov(to, a64::XRegister(x86reg));
}
}
else if (xmmreg >= 0) {
if(to.IsW()) {
// xMOVD(to, xRegisterSSE(xmmreg));
armAsm->Fmov(to, a64::QRegister(xmmreg).V1D());
armAsm->Fmov(to, a64::QRegister(xmmreg).S());
} else {
// xMOVD(to, xRegisterSSE(xmmreg));
armAsm->Fmov(to, a64::QRegister(xmmreg).D());
}
}
else {
if(to.IsW()) {
// xMOV(to, ptr[&cpuRegs.GPR.r[fromgpr].UL[0]]);
armLoad(to, PTR_CPU(cpuRegs.GPR.r[fromgpr].UL[0]));
} else {
// xMOV(to, ptr32[&cpuRegs.GPR.r[fromgpr].UD[0]]);
armLoad(to, PTR_CPU(cpuRegs.GPR.r[fromgpr].UD[0]));
armLoad(to, PTR_CPU(cpuRegs.GPR.r[fromgpr].UD[0]));
}
}
}
}
@@ -490,13 +477,13 @@ static const void* _DynGen_EnterRecompiledCode()
static constexpr u32 stack_size = 32 + 8;
#else
// Stack still needs to be aligned
// static constexpr u32 stack_size = 16;
static constexpr u32 stack_size = 16;
#endif
// We never return through this function, instead we fastjmp() out.
// So we don't need to worry about preserving callee-saved registers, but we do need to align the stack.
// xSUB(rsp, stack_size);
// armAsm->Sub(a64::sp, a64::sp, stack_size);
armAsm->Sub(a64::sp, a64::sp, stack_size);
#endif
// From memory to registry
@@ -652,15 +639,15 @@ static void recResetRaw()
EE::Profiler.Reset();
// recVTLB => iR5900LoadStore
vtlb_DynGenDispatchers();
// xSetPtr(SysMemory::GetEERec());
armSetAsmPtr(recPtr, recPtrEnd - recPtr, nullptr);
armStartBlock();
_DynGen_Dispatchers();
// recVTLB => iR5900LoadStore
vtlb_DynGenDispatchers();
// recPtr = xGetPtr();
recPtr = armEndBlock();
@@ -1460,7 +1447,7 @@ static void iBranchTest(u32 newpc)
// xADD(ptr32[&cpuRegs.cycle], scaleblockcycles());
armAdd(PTR_CPU(cpuRegs.cycle), scaleblockcycles());
// xCMP(eax, ptr32[&cpuRegs.cycle]);
armLoad(EEX, PTR_CPU(cpuRegs.cycle));
armLoadsw(EEX, PTR_CPU(cpuRegs.cycle));
armAsm->Cmp(EAX, EEX);
// xCMOVS(eax, ptr32[&cpuRegs.cycle]);
armAsm->Csel(EAX, EEX, EAX, a64::Condition::mi);
@@ -1477,7 +1464,7 @@ static void iBranchTest(u32 newpc)
// xMOV(ptr[&cpuRegs.cycle], eax); // update cycles
armAdd(EAX, PTR_CPU(cpuRegs.cycle), scaleblockcycles());
// xSUB(eax, ptr[&cpuRegs.nextEventCycle]);
armAsm->Subs(EAX, EAX, armLoad(PTR_CPU(cpuRegs.nextEventCycle)));
armAsm->Subs(EAX, EAX, armLoadsw(PTR_CPU(cpuRegs.nextEventCycle)));
a64::Label labelSigned;
armAsm->B(&labelSigned, a64::Condition::pl);
@@ -1675,7 +1662,7 @@ void recMemcheck(u32 op, u32 bits, bool store)
iFlushCall(FLUSH_EVERYTHING | FLUSH_PC);
// compute accessed address
_eeMoveGPRtoR(a64::WRegister(EAX), (op >> 21) & 0x1F);
_eeMoveGPRtoR(EAX, (op >> 21) & 0x1F);
if (static_cast<s16>(op) != 0) {
// xADD(ecx, static_cast<s16>(op));
armAsm->Add(EAX, EAX, static_cast<s16>(op));
@@ -2877,7 +2864,7 @@ StartRecomp:
// case can result in very short blocks which should not issue branch tests for
// performance reasons.
const int numinsts = (pc - startpc) / 4;
const int numinsts = (pc - startpc) >> 2; // (pc - startpc) / 4
if (numinsts > 6)
SetBranchImm(pc);
else
@@ -81,7 +81,7 @@ static void recLoadQuad(u32 bits, bool sign)
// Load ECX with the source memory address that we're reading from.
_freeX86reg(ECX);
// _eeMoveGPRtoR(arg1reg, _Rs_);
_eeMoveGPRtoR(a64::XRegister(RCX), _Rs_);
_eeMoveGPRtoR(RCX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -123,7 +123,7 @@ static void recLoad(u32 bits, bool sign)
// Load arg1 with the source memory address that we're reading from.
_freeX86reg(ECX);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -177,7 +177,7 @@ static void recStore(u32 bits)
{
// TODO(Stenzek): Preload Rs when it's live. Turn into LEA.
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -287,7 +287,8 @@ void recLWL()
const a64::WRegister temp(_allocX86reg(X86TYPE_TEMP, 0, MODE_CALLEESAVED));
_eeMoveGPRtoR(arg1regd, _Rs_);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -364,7 +365,7 @@ void recLWR()
const a64::WRegister temp(_allocX86reg(X86TYPE_TEMP, 0, MODE_CALLEESAVED));
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -459,7 +460,7 @@ void recSWL()
// _freeX86reg(arg2regd);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -506,7 +507,7 @@ void recSWL()
// xADD(ecx, 24);
armAsm->Add(ECX, ECX, 24);
// _eeMoveGPRtoR(eax, _Rt_, false);
_eeMoveGPRtoR(a64::WRegister(EAX), _Rt_, false);
_eeMoveGPRtoR(EAX, _Rt_, false);
// xSHR(eax, cl);
armAsm->Lsr(EAX, EAX, ECX);
// xOR(arg2regd, eax);
@@ -514,7 +515,7 @@ void recSWL()
}
// _eeMoveGPRtoR(arg1regd, _Rs_, false);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_, false);
_eeMoveGPRtoR(ECX, _Rs_, false);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -528,7 +529,7 @@ void recSWL()
// skip.SetTarget();
armBind(&skip);
// _eeMoveGPRtoR(arg2regd, _Rt_, false);
_eeMoveGPRtoR(a64::WRegister(EDX), _Rt_, false);
_eeMoveGPRtoR(EDX, _Rt_, false);
// end.SetTarget();
armBind(&end);
@@ -565,7 +566,7 @@ void recSWR()
// _freeX86reg(arg2regd);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -610,7 +611,7 @@ void recSWR()
// xMOV(ecx, temp);
armAsm->Mov(ECX, temp);
// _eeMoveGPRtoR(eax, _Rt_, false);
_eeMoveGPRtoR(a64::WRegister(EAX), _Rt_, false);
_eeMoveGPRtoR(EAX, _Rt_, false);
// xSHL(eax, cl);
armAsm->Lsl(EAX, EAX, ECX);
// xOR(arg2regd, eax);
@@ -618,7 +619,7 @@ void recSWR()
}
// _eeMoveGPRtoR(arg1regd, _Rs_, false);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_, false);
_eeMoveGPRtoR(ECX, _Rs_, false);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -632,7 +633,7 @@ void recSWR()
// skip.SetTarget();
armBind(&skip);
// _eeMoveGPRtoR(arg2regd, _Rt_, false);
_eeMoveGPRtoR(a64::WRegister(EDX), _Rt_, false);
_eeMoveGPRtoR(EDX, _Rt_, false);
// end.SetTarget();
armBind(&end);
@@ -708,7 +709,7 @@ static void ldlrhelper_const(int maskamt, const SHIFTV maskshift, int amt, const
/// Masks rt with (0xffffffffffffffff maskshift maskamt), merges with (value shift amt), leaves result in value
//static void ldlrhelper(const xRegister32& maskamt, const xImpl_Group2& maskshift, const xRegister32& amt, const xImpl_Group2& shift, const xRegister64& value, const xRegister64& rt)
static void ldlrhelper(const a64::WRegister& maskamt, const SHIFTV maskshift, const a64::WRegister& amt, const SHIFTV shift, const a64::XRegister& value, const a64::XRegister& rt)
static void ldlrhelper(const a64::Register& maskamt, const SHIFTV maskshift, const a64::Register& amt, const SHIFTV shift, const a64::Register& value, const a64::Register& rt)
{
pxAssert(rt.GetCode() != ECX.GetCode() && amt.GetCode() != ECX.GetCode() && value.GetCode() != ECX.GetCode());
@@ -794,7 +795,7 @@ void recLDL()
// _freeX86reg(arg1regd);
_freeX86reg(ECX);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -847,7 +848,7 @@ void recLDL()
armAsm->Sub(EDX, EDX, temp1);
// ldlrhelper(temp1, xSHR, edx, xSHL, rax, treg);
ldlrhelper(temp1, SHIFTV::xSHR, a64::WRegister(EDX), SHIFTV::xSHL, a64::XRegister(RAX), treg);
ldlrhelper(temp1, SHIFTV::xSHR, EDX, SHIFTV::xSHL, RAX, treg);
// skip.SetTarget();
armBind(&skip);
}
@@ -902,7 +903,7 @@ void recLDR()
// _freeX86reg(arg1regd);
_freeX86reg(ECX);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -951,7 +952,7 @@ void recLDR()
armAsm->Sub(EDX, EDX, temp1);
// ldlrhelper(edx, xSHL, temp1, xSHR, rax, treg);
ldlrhelper(a64::WRegister(EDX), SHIFTV::xSHL, temp1, SHIFTV::xSHR, a64::XRegister(RAX), treg);
ldlrhelper(EDX, SHIFTV::xSHL, temp1, SHIFTV::xSHR, RAX, treg);
// skip.SetTarget();
armBind(&skip);
}
@@ -1014,7 +1015,7 @@ static void sdlrhelper_const(int maskamt, const SHIFTV maskshift, int amt, const
/// Masks value with (0xffffffffffffffff maskshift maskamt), merges with (rt shift amt), saves to dummyValue
//static void sdlrhelper(const xRegister32& maskamt, const xImpl_Group2& maskshift, const xRegister32& amt, const xImpl_Group2& shift, const xRegister64& value, const xRegister64& rt)
static void sdlrhelper(const a64::WRegister& maskamt, const SHIFTV maskshift, const a64::WRegister& amt, const SHIFTV shift, const a64::XRegister& value, const a64::XRegister& rt)
static void sdlrhelper(const a64::Register& maskamt, const SHIFTV maskshift, const a64::Register& amt, const SHIFTV shift, const a64::Register& value, const a64::Register& rt)
{
pxAssert(rt.GetCode() != ECX.GetCode() && amt.GetCode() != ECX.GetCode() && value.GetCode() != ECX.GetCode());
@@ -1083,12 +1084,13 @@ void recSDL()
if (shift == 64)
{
// _eeMoveGPRtoR(arg2reg, _Rt_);
_eeMoveGPRtoR(a64::XRegister(RDX), _Rt_);
_eeMoveGPRtoR(RDX, _Rt_);
}
else
{
vtlb_DynGenReadNonQuad_Const(64, false, false, aligned, RETURN_READ_IN_RAX);
_eeMoveGPRtoR(arg2reg, _Rt_);
// _eeMoveGPRtoR(arg2reg, _Rt_);
_eeMoveGPRtoR(RDX, _Rt_);
// sdlrhelper_const(shift, xSHL, 64 - shift, xSHR, rax, arg2reg);
sdlrhelper_const(shift, SHIFTV::xSHL, 64 - shift, SHIFTV::xSHR, a64::XRegister(RAX), a64::XRegister(RDX));
}
@@ -1103,7 +1105,7 @@ void recSDL()
// _freeX86reg(arg1regd);
_freeX86reg(ECX);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -1116,7 +1118,7 @@ void recSDL()
const a64::WRegister temp1(_allocX86reg(X86TYPE_TEMP, 0, MODE_CALLEESAVED));
const a64::XRegister temp2(_allocX86reg(X86TYPE_TEMP, 0, MODE_CALLEESAVED));
// _eeMoveGPRtoR(arg2reg, _Rt_);
_eeMoveGPRtoR(a64::XRegister(RDX), _Rt_);
_eeMoveGPRtoR(RDX, _Rt_);
// xMOV(temp1, arg1regd);
armAsm->Mov(temp1, ECX);
@@ -1150,10 +1152,10 @@ void recSDL()
armAsm->Sub(EDX, EDX, temp1);
// sdlrhelper(temp1, xSHL, edx, xSHR, rax, temp2);
sdlrhelper(temp1, SHIFTV::xSHL, a64::WRegister(EDX), SHIFTV::xSHR, a64::XRegister(RAX), temp2);
sdlrhelper(temp1, SHIFTV::xSHL, EDX, SHIFTV::xSHR, RAX, temp2);
// _eeMoveGPRtoR(arg1regd, _Rs_, false);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_, false);
_eeMoveGPRtoR(ECX, _Rs_, false);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -1197,13 +1199,13 @@ void recSDR()
if (shift == 0)
{
// _eeMoveGPRtoR(arg2reg, _Rt_);
_eeMoveGPRtoR(a64::XRegister(RDX), _Rt_);
_eeMoveGPRtoR(RDX, _Rt_);
}
else
{
vtlb_DynGenReadNonQuad_Const(64, false, false, aligned, RETURN_READ_IN_RAX);
// _eeMoveGPRtoR(arg2reg, _Rt_);
_eeMoveGPRtoR(a64::XRegister(RDX), _Rt_);
_eeMoveGPRtoR(RDX, _Rt_);
// sdlrhelper_const(64 - shift, xSHR, shift, xSHL, rax, arg2reg);
sdlrhelper_const(64 - shift, SHIFTV::xSHR, shift, SHIFTV::xSHL, a64::XRegister(RAX), a64::XRegister(RDX));
}
@@ -1217,7 +1219,7 @@ void recSDR()
// Load ECX with the source memory address that we're reading from.
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -1230,7 +1232,7 @@ void recSDR()
const a64::WRegister temp1(_allocX86reg(X86TYPE_TEMP, 0, MODE_CALLEESAVED));
const a64::XRegister temp2(_allocX86reg(X86TYPE_TEMP, 0, MODE_CALLEESAVED));
// _eeMoveGPRtoR(arg2reg, _Rt_);
_eeMoveGPRtoR(a64::XRegister(RDX), _Rt_);
_eeMoveGPRtoR(RDX, _Rt_);
// xMOV(temp1, arg1regd);
armAsm->Mov(temp1, ECX);
@@ -1259,10 +1261,10 @@ void recSDR()
armAsm->Sub(EDX, EDX, temp1);
// sdlrhelper(edx, xSHR, temp1, xSHL, rax, temp2);
sdlrhelper(a64::WRegister(EDX), SHIFTV::xSHR, temp1, SHIFTV::xSHL, a64::XRegister(RAX), temp2);
sdlrhelper(EDX, SHIFTV::xSHR, temp1, SHIFTV::xSHL, RAX, temp2);
// _eeMoveGPRtoR(arg1regd, _Rs_, false);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_, false);
_eeMoveGPRtoR(ECX, _Rs_, false);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -1313,7 +1315,7 @@ void recLWC1()
// _freeX86reg(arg1regd);
_freeX86reg(ECX);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -1344,7 +1346,7 @@ void recSWC1()
// _freeX86reg(arg1regd);
_freeX86reg(ECX);
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -430,7 +430,7 @@ static void recDIVsuper(int info, bool sign, bool upper, int process)
armAsm->Mov(EAX, g_cpuConstRegs[_Rs_].UL[0]);
}
else {
_eeMoveGPRtoR(a64::XRegister(RAX), _Rs_);
_eeMoveGPRtoR(RAX, _Rs_);
}
// u8* end1;
+30 -26
View File
@@ -259,7 +259,8 @@ namespace vtlb_private
}
} // namespace vtlb_private
static constexpr u32 INDIRECT_DISPATCHER_SIZE = 96;
static bool hasBeenCalled = false;
static constexpr u32 INDIRECT_DISPATCHER_SIZE = 64;
static constexpr u32 INDIRECT_DISPATCHERS_SIZE = 2 * 5 * 2 * INDIRECT_DISPATCHER_SIZE;
alignas(__pagesize) static u8 m_IndirectDispatchers[__pagesize];
@@ -394,35 +395,38 @@ static void DynGen_IndirectTlbDispatcher(int mode, int bits, bool sign)
void vtlb_DynGenDispatchers()
{
static bool hasBeenCalled = false;
if (hasBeenCalled)
return;
hasBeenCalled = true;
HostSys::MemProtect(m_IndirectDispatchers, __pagesize, PageAccess_ReadWrite());
// clear the buffer to 0xcc (easier debugging).
std::memset(m_IndirectDispatchers, 0xcc, __pagesize);
int mode, bits, sign;
for (mode = 0; mode < 2; ++mode)
u8* code_start = armEndBlock();
////
if (!hasBeenCalled)
{
for (bits = 0; bits < 5; ++bits)
{
for (sign = 0; sign < (!mode && bits < 3 ? 2 : 1); ++sign)
{
armSetAsmPtr(GetIndirectDispatcherPtr(mode, bits, !!sign), INDIRECT_DISPATCHERS_SIZE, nullptr);
armStartBlock();
////
DynGen_IndirectTlbDispatcher(mode, bits, !!sign);
////
armEndBlock();
hasBeenCalled = true;
HostSys::MemProtect(m_IndirectDispatchers, __pagesize, PageAccess_ReadWrite());
// clear the buffer to 0xcc (easier debugging).
std::memset(m_IndirectDispatchers, 0xcc, __pagesize);
int mode, bits, sign;
for (mode = 0; mode < 2; ++mode) {
for (bits = 0; bits < 5; ++bits) {
for (sign = 0; sign < (!mode && bits < 3 ? 2 : 1); ++sign) {
armSetAsmPtr(GetIndirectDispatcherPtr(mode, bits, !!sign), INDIRECT_DISPATCHERS_SIZE, nullptr);
armStartBlock();
////
DynGen_IndirectTlbDispatcher(mode, bits, !!sign);
////
armEndBlock();
}
}
}
HostSys::MemProtect(m_IndirectDispatchers, __pagesize, PageAccess_ExecOnly());
}
HostSys::MemProtect(m_IndirectDispatchers, __pagesize, PageAccess_ExecOnly());
Perf::any.Register(m_IndirectDispatchers, __pagesize, "TLB Dispatcher");
//// copy code
memcpy(code_start, m_IndirectDispatchers, INDIRECT_DISPATCHERS_SIZE);
////
armSetAsmPtr(code_start, INDIRECT_DISPATCHERS_SIZE, nullptr);
armStartBlock();
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -798,7 +802,7 @@ void vtlb_DynGenWrite(u32 sz, bool xmm, int addr_reg, int value_reg)
const u8* codeStart = armGetCurrentCodePointer();
// const xAddressReg vaddr_reg(addr_reg);
a64::MemOperand mop = a64::MemOperand(RFASTMEMBASE, a64::XRegister(addr_reg));
const a64::MemOperand mop = a64::MemOperand(RFASTMEMBASE, a64::XRegister(addr_reg));
if (!xmm)
{
@@ -915,7 +919,7 @@ void vtlb_DynGenWrite_Const(u32 bits, bool xmm, u32 addr_const, int value_reg)
if (!vmv.isHandler(addr_const))
{
auto ppf = vmv.assumePtr(addr_const);
a64::MemOperand mop = armMemOperandPtr((void*)ppf);
const a64::MemOperand mop = armMemOperandPtr((void*)ppf);
if (!xmm)
{
switch (bits)
@@ -517,7 +517,7 @@ void normBranch(mV, microFlagCycles& mFC)
// xLoadFarAddr(rax, &mVUpBlock->pStateEnd);
armMoveAddressToReg(RAX, &mVUpBlock->pStateEnd);
// xCALL((void*)mVU.copyPLState);
armEmitCall(reinterpret_cast<void*>(mVU.copyPLState));
armEmitCall(mVU.copyPLState);
mVUsetupBranch(mVU, mFC);
mVUendProgram(mVU, &mFC, 3);
@@ -656,7 +656,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
// xLoadFarAddr(rax, &mVUpBlock->pStateEnd);
armMoveAddressToReg(RAX, &mVUpBlock->pStateEnd);
// xCALL((void*)mVU.copyPLState);
armEmitCall(reinterpret_cast<void*>(mVU.copyPLState));
armEmitCall(mVU.copyPLState);
mVUendProgram(mVU, &mFC, 3);
// xCMP(ptr16[&mVU.branch], 0);
@@ -749,13 +749,11 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc)
else
{
// s32* ajmp = xJcc32((JccComparisonType)JMPcc);
u8* ajmp = armGetCurrentCodePointer();
////////////////////////////////////////////////////////////
a64::Label labelJump;
armAsm->B(&labelJump, a64::InvertCondition(JMPcc));
ajmp = armGetCurrentCodePointer();
armAsm->Nop();
s32* ajmp = (s32*)armGetCurrentCodePointer()-1;
armBind(&labelJump);
////////////////////////////////////////////////////////////
@@ -517,7 +517,7 @@ void mVUtestCycles(microVU& mVU, microFlagCycles& mFC)
// xLoadFarAddr(rax, &mVUpBlock->pState);
armMoveAddressToReg(RAX, &mVUpBlock->pState);
// xCALL((void*)mVU.copyPLState);
armEmitCall(reinterpret_cast<void*>(mVU.copyPLState));
armEmitCall(mVU.copyPLState);
if (EmuConfig.Gamefixes.VUSyncHack || EmuConfig.Gamefixes.FullVU0SyncHack) {
// xMOV(ptr32[&mVU.regs().nextBlockCycles], mVUcycles);
+2 -1
View File
@@ -522,7 +522,8 @@ public:
}
// Wait flush
usleep(2000);
std::thread t([]() {});
t.detach();
}
void flushCallerSavedRegisters(bool clearNeeded = false)
+6 -6
View File
@@ -563,7 +563,7 @@ static void recCTC2()
case REG_VPU_STAT:
break; // Read Only Regs
case REG_R:
_eeMoveGPRtoR(a64::WRegister(EAX), _Rt_);
_eeMoveGPRtoR(EAX, _Rt_);
// xAND(eax, 0x7FFFFF);
armAsm->And(EAX, EAX, 0x7FFFFF);
// xOR(eax, 0x3f800000);
@@ -575,7 +575,7 @@ static void recCTC2()
{
if (_Rt_)
{
_eeMoveGPRtoR(a64::WRegister(EAX), _Rt_);
_eeMoveGPRtoR(EAX, _Rt_);
// xAND(eax, 0xFC0);
armAsm->And(EAX, EAX, 0xFC0);
// xAND(ptr32[&vu0Regs.VI[REG_STATUS_FLAG].UL], 0x3F);
@@ -609,7 +609,7 @@ static void recCTC2()
armAsm->Mov(EAX, 1);
// xFastCall((void*)vu1Finish);
armEmitCall(reinterpret_cast<const void*>(vu1Finish));
_eeMoveGPRtoR(a64::WRegister(EAX), _Rt_);
_eeMoveGPRtoR(EAX, _Rt_);
iFlushCall(FLUSH_NONE);
// xFastCall((void*)vu1ExecMicro);
armEmitCall(reinterpret_cast<const void*>(vu1ExecMicro));
@@ -708,7 +708,7 @@ static void recCTC2()
}
else
{
_eeMoveGPRtoR(a64::WRegister(EAX), _Rt_);
_eeMoveGPRtoR(EAX, _Rt_);
// xMOV(ptr16[&vu0Regs.VI[_Rd_].US[0]], ax);
}
}
@@ -960,7 +960,7 @@ void recLQC2()
else
{
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);
@@ -1003,7 +1003,7 @@ void recSQC2()
else
{
// _eeMoveGPRtoR(arg1regd, _Rs_);
_eeMoveGPRtoR(a64::WRegister(ECX), _Rs_);
_eeMoveGPRtoR(ECX, _Rs_);
if (_Imm_ != 0) {
// xADD(arg1regd, _Imm_);
armAsm->Add(ECX, ECX, _Imm_);