mirror of
https://github.com/izzy2lost/PCSX2_ARM64.git
synced 2026-06-19 10:16:23 -07:00
Android project - R5900.cpp => Fixed game delay error in nextIopEventDeta variable of _cpuEventTest_Shared()
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -522,7 +522,8 @@ public:
|
||||
}
|
||||
|
||||
// Wait flush
|
||||
usleep(2000);
|
||||
std::thread t([]() {});
|
||||
t.detach();
|
||||
}
|
||||
|
||||
void flushCallerSavedRegisters(bool clearNeeded = false)
|
||||
|
||||
@@ -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_);
|
||||
|
||||
Reference in New Issue
Block a user