Android project - Modify the _eeMoveGPRtoM function

This commit is contained in:
k2154
2025-08-16 01:20:39 +09:00
parent 5e79fde6d1
commit 3ca937df00
9 changed files with 70 additions and 58 deletions
+2 -2
View File
@@ -28,7 +28,7 @@ static constexpr bool IsDebugBuild = false;
static constexpr unsigned int __pagesize = OVERRIDE_HOST_PAGE_SIZE;
static constexpr unsigned int __pagemask = __pagesize - 1;
static constexpr unsigned int __pageshift = std::bit_width(__pagemask);
#elif defined(_M_ARM64)
#elif defined(_M_ARM64) && !defined(ANDROID)
// Apple Silicon uses 16KB pages and 128 byte cache lines.
static constexpr unsigned int __pagesize = 0x4000;
static constexpr unsigned int __pageshift = 14;
@@ -41,7 +41,7 @@ static constexpr bool IsDebugBuild = false;
#endif
#if defined(OVERRIDE_HOST_CACHE_LINE_SIZE)
static constexpr unsigned int __cachelinesize = OVERRIDE_HOST_CACHE_LINE_SIZE;
#elif defined(_M_ARM64)
#elif defined(_M_ARM64) && !defined(ANDROID)
static constexpr unsigned int __cachelinesize = 128;
#else
static constexpr unsigned int __cachelinesize = 64;
+5 -5
View File
@@ -359,7 +359,7 @@ void recMTC0()
// xADD(ecx, scaleblockcycles_clear());
// xMOV(ptr32[&cpuRegs.cycle], ecx); // update cycles
armAdd(ECX, PTR_CPU(cpuRegs.cycle), scaleblockcycles_clear());
_eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[9], _Rt_);
_eeMoveGPRtoM(PTR_CPU(cpuRegs.CP0.r[9]), _Rt_);
// xMOV(ptr[&cpuRegs.lastCOP0Cycle], ecx);
armStore(PTR_CPU(cpuRegs.lastCOP0Cycle), ECX);
break;
@@ -376,7 +376,7 @@ void recMTC0()
armAdd(PTR_CPU(cpuRegs.cycle), scaleblockcycles_clear());
// xFastCall((void*)COP0_UpdatePCCR);
armEmitCall(reinterpret_cast<void*>(COP0_UpdatePCCR));
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_);
_eeMoveGPRtoM(PTR_CPU(cpuRegs.PERF.n.pccr), _Rt_);
// xFastCall((void*)COP0_DiagnosticPCCR);
armEmitCall(reinterpret_cast<void*>(COP0_DiagnosticPCCR));
}
@@ -386,7 +386,7 @@ void recMTC0()
// xADD(ecx, scaleblockcycles_clear());
// xMOV(ptr32[&cpuRegs.cycle], ecx); // update cycles
armAdd(ECX, PTR_CPU(cpuRegs.cycle), scaleblockcycles_clear());
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr0, _Rt_);
_eeMoveGPRtoM(PTR_CPU(cpuRegs.PERF.n.pcr0), _Rt_);
// xMOV(ptr[&cpuRegs.lastPERFCycle[0]], ecx);
armStore(PTR_CPU(cpuRegs.lastPERFCycle[0]), ECX);
}
@@ -396,7 +396,7 @@ void recMTC0()
// xADD(ecx, scaleblockcycles_clear());
// xMOV(ptr32[&cpuRegs.cycle], ecx); // update cycles
armAdd(ECX, PTR_CPU(cpuRegs.cycle), scaleblockcycles_clear());
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr1, _Rt_);
_eeMoveGPRtoM(PTR_CPU(cpuRegs.PERF.n.pcr1), _Rt_);
// xMOV(ptr[&cpuRegs.lastPERFCycle[1]], ecx);
armStore(PTR_CPU(cpuRegs.lastPERFCycle[1]), ECX);
}
@@ -407,7 +407,7 @@ void recMTC0()
break;
default:
_eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[_Rd_], _Rt_);
_eeMoveGPRtoM(PTR_CPU(cpuRegs.CP0.r[_Rd_]), _Rt_);
break;
}
}
+1 -1
View File
@@ -108,7 +108,7 @@ extern u32 g_cpuHasConstReg, g_cpuFlushedConstReg;
// finds where the GPR is stored and moves lower 32 bits to EAX
void _eeMoveGPRtoR(const a64::Register& to, int fromgpr, bool allow_preload = true);
void _eeMoveGPRtoM(uptr to, int fromgpr); // 32-bit only
void _eeMoveGPRtoM(const a64::MemOperand& to, int fromgpr); // 32-bit only
void _eeFlushAllDirty();
void _eeOnWriteReg(int reg, int signext);
@@ -298,11 +298,11 @@ void _eeMoveGPRtoR(const a64::Register& to, int fromgpr, bool allow_preload)
}
}
void _eeMoveGPRtoM(uptr to, int fromgpr)
void _eeMoveGPRtoM(const a64::MemOperand& to, int fromgpr)
{
if (GPR_IS_CONST1(fromgpr)) {
// xMOV(ptr32[(u32 *) (to)], g_cpuConstRegs[fromgpr].UL[0]);
armStorePtr(g_cpuConstRegs[fromgpr].UL[0], (u32 *) (to));
armStorePtr(g_cpuConstRegs[fromgpr].UL[0], to);
}
else
{
@@ -320,19 +320,19 @@ void _eeMoveGPRtoM(uptr to, int fromgpr)
if (x86reg >= 0)
{
// xMOV(ptr32[(void*)(to)], xRegister32(x86reg));
armAsm->Str(a64::WRegister(x86reg), armMemOperandPtr((void*)(to)));
armAsm->Str( a64::WRegister(x86reg), to);
}
else if (xmmreg >= 0)
{
// xMOVSS(ptr32[(void*)(to)], xRegisterSSE(xmmreg));
armAsm->Str(a64::QRegister(xmmreg).S(), armMemOperandPtr((void*)(to)));
armAsm->Str(a64::QRegister(xmmreg).S(), to);
}
else
{
// xMOV(eax, ptr32[&cpuRegs.GPR.r[fromgpr].UL[0]]);
armLoad(EAX, PTR_CPU(cpuRegs.GPR.r[fromgpr].UL[0]));
// xMOV(ptr32[(void*)(to)], eax);
armAsm->Str(EAX, armMemOperandPtr((void*)(to)));
armAsm->Str(EAX, to);
}
}
}
@@ -932,7 +932,7 @@ void SetBranchReg(u32 reg)
}
else
{
_eeMoveGPRtoM((uptr)&cpuRegs.pc, reg);
_eeMoveGPRtoM(PTR_CPU(cpuRegs.pc), reg);
}
}
}
@@ -168,7 +168,7 @@ void recJALR()
}
else
{
_eeMoveGPRtoM((uptr)&cpuRegs.pc, _Rs_);
_eeMoveGPRtoM(PTR_CPU(cpuRegs.pc), _Rs_);
}
}
+4 -1
View File
@@ -211,6 +211,8 @@ public:
}
return thisBlock;
}
typedef u32 (*mVUCall)(u32, void*, void*);
__ri microBlock* search(microVU& mVU, microRegInfo* pState)
{
if (pState->needExactMatch) // Needs Detailed Search (Exact Match of Pipeline State)
@@ -218,7 +220,8 @@ public:
microBlockLink* prevI = nullptr;
for (microBlockLink* linkI = fBlockList; linkI != nullptr; prevI = linkI, linkI = linkI->next)
{
if (mVU.compareState(pState, &linkI->block.pState) == 0)
// if (mVU.compareState(pState, &linkI->block.pState) == 0)
if (((mVUCall(mVU.compareStateF)(0, pState, &linkI->block.pState)) == 0))
{
if (linkI != fBlockList)
{
+17 -21
View File
@@ -310,62 +310,58 @@ static void mVUGenerateCopyPipelineState(mV)
static void mVUGenerateCompareState(mV)
{
mVU.compareStateF = armStartBlock();
{
// xMOVAPS (xmm0, ptr32[arg1reg]);
armAsm->Ldr(xmm0, a64::MemOperand(RAX));
armAsm->Ldr(xmm0, a64::MemOperand(RCX));
// xPCMP.EQD(xmm0, ptr32[arg2reg]);
armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RCX).V4S());
armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RDX).V4S());
// xMOVAPS (xmm1, ptr32[arg1reg + 0x10]);
armAsm->Ldr(xmm1, a64::MemOperand(RAX, 0x10));
armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x10));
// xPCMP.EQD(xmm1, ptr32[arg2reg + 0x10]);
armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RCX, 0x10).V4S());
armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x10).V4S());
// xPAND (xmm0, xmm1);
armAsm->And(xmm0.V16B(), xmm0.V16B(), xmm1.V16B());
// xMOVMSKPS(eax, xmm0);
armMOVMSKPS(EDX, xmm0);
armMOVMSKPS(EAX, xmm0);
// xXOR (eax, 0xf);
armAsm->Eor(EDX, EDX, 0xf);
armAsm->Eor(EAX, EAX, 0xf);
// xForwardJNZ8 exitPoint;
a64::Label exitPoint;
armAsm->Cbnz(EDX, &exitPoint);
armAsm->Cbnz(EAX, &exitPoint);
// xMOVAPS (xmm0, ptr32[arg1reg + 0x20]);
armAsm->Ldr(xmm0, a64::MemOperand(RAX, 0x20));
armAsm->Ldr(xmm0, a64::MemOperand(RCX, 0x20));
// xPCMP.EQD(xmm0, ptr32[arg2reg + 0x20]);
armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RCX, 0x20).V4S());
armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RDX, 0x20).V4S());
// xMOVAPS (xmm1, ptr32[arg1reg + 0x30]);
armAsm->Ldr(xmm1, a64::MemOperand(RAX, 0x30));
armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x30));
// xPCMP.EQD(xmm1, ptr32[arg2reg + 0x30]);
armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RCX, 0x30).V4S());
armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x30).V4S());
// xPAND (xmm0, xmm1);
armAsm->And(xmm0.V16B(), xmm0.V16B(), xmm1.V16B());
// xMOVAPS (xmm1, ptr32[arg1reg + 0x40]);
armAsm->Ldr(xmm1, a64::MemOperand(RAX, 0x40));
armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x40));
// xPCMP.EQD(xmm1, ptr32[arg2reg + 0x40]);
armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RCX, 0x40).V4S());
armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x40).V4S());
// xMOVAPS (xmm2, ptr32[arg1reg + 0x50]);
armAsm->Ldr(xmm2, a64::MemOperand(RAX, 0x50));
armAsm->Ldr(xmm2, a64::MemOperand(RCX, 0x50));
// xPCMP.EQD(xmm2, ptr32[arg2reg + 0x50]);
armAsm->Cmeq(xmm2.V4S(), xmm2.V4S(), armLoadPtrM(RCX, 0x50).V4S());
armAsm->Cmeq(xmm2.V4S(), xmm2.V4S(), armLoadPtrM(RDX, 0x50).V4S());
// xPAND (xmm1, xmm2);
armAsm->And(xmm1.V16B(), xmm1.V16B(), xmm2.V16B());
// xPAND (xmm0, xmm1);
armAsm->And(xmm0.V16B(), xmm0.V16B(), xmm1.V16B());
// xMOVMSKPS(eax, xmm0);
armMOVMSKPS(EDX, xmm0);
armMOVMSKPS(EAX, xmm0);
// xXOR(eax, 0xf);
armAsm->Eor(EDX, EDX, 0xf);
armAsm->Eor(EAX, EAX, 0xf);
// exitPoint.SetTarget();
armBind(&exitPoint);
// Result
armAsm->Mov(EAX, EDX);
}
// xRET();
+22 -20
View File
@@ -5,7 +5,7 @@
extern void _vu0WaitMicro();
extern void _vu0FinishMicro();
static VURegs& vu0Regs = g_cpuRegistersPack.vuRegs[0];
//static VURegs& vu0Regs = g_cpuRegistersPack.vuRegs[0];
//------------------------------------------------------------------
// Macro VU - Helper Macros / Functions
@@ -72,7 +72,7 @@ void setupMacroOp(int mode, const char* opName)
// load denormalized status flag
// ideally we'd keep this in a register, but 32-bit...
// xMOV(gprF0, ptr32[&vuRegs->VI[REG_STATUS_FLAG].UL]);
armAsm->Ldr(gprF0, armMemOperandPtr(&g_cpuRegistersPack.vuRegs->VI[REG_STATUS_FLAG].UL));
armAsm->Ldr(gprF0, PTR_CPU(vuRegs[g_cpuRegistersPack.vuRegs->idx].VI[REG_STATUS_FLAG].UL));
}
}
}
@@ -101,7 +101,7 @@ void endMacroOp(int mode)
// backup denormalized flags for the next instruction
// this is fine, because we'll normalize them again before this reg is accessed
// xMOV(ptr32[&vuRegs->VI[REG_STATUS_FLAG].UL], gprF0);
armAsm->Str(gprF0, armMemOperandPtr(&g_cpuRegistersPack.vuRegs->VI[REG_STATUS_FLAG].UL));
armAsm->Str(gprF0, PTR_CPU(vuRegs[g_cpuRegistersPack.vuRegs->idx].VI[REG_STATUS_FLAG].UL));
}
}
@@ -489,13 +489,13 @@ static void recCFC2()
}
const int regt = _allocX86reg(X86TYPE_GPR, _Rt_, MODE_WRITE);
auto regT = a64::XRegister(regt);
pxAssert(!GPR_IS_CONST1(_Rt_));
if (_Rd_ == 0) // why would you read vi00?
{
// xXOR(xRegister32(regt), xRegister32(regt));
a64::Register reg32 = a64::WRegister(regt);
armAsm->Eor(reg32, reg32, reg32);
armAsm->Eor(regT.W(), regT.W(), regT.W());
}
else if (_Rd_ == REG_I)
{
@@ -503,38 +503,38 @@ static void recCFC2()
if (xmmreg >= 0)
{
// xMOVD(xRegister32(regt), xRegisterSSE(xmmreg));
armAsm->Fmov(a64::WRegister(regt), a64::QRegister(xmmreg).S());
armAsm->Fmov(regT.W(), a64::QRegister(xmmreg).S());
// xMOVSX(xRegister64(regt), xRegister32(regt));
armAsm->Sxtw(a64::XRegister(regt), a64::WRegister(regt));
armAsm->Sxtw(regT.X(), regT.W());
}
else
{
// xMOVSX(xRegister64(regt), ptr32[&vu0Regs.VI[_Rd_].UL]);
armAsm->Ldrsw(a64::XRegister(regt), PTR_CPU(vuRegs[0].VI[_Rd_].UL));
armAsm->Ldrsw(regT.X(), PTR_CPU(vuRegs[0].VI[_Rd_].UL));
}
}
else if (_Rd_ == REG_R)
{
// xMOVSX(xRegister64(regt), ptr32[&vu0Regs.VI[REG_R].UL]);
armAsm->Ldrsw(a64::XRegister(regt), PTR_CPU(vuRegs[0].VI[REG_R].UL));
armAsm->Ldrsw(regT.X(), PTR_CPU(vuRegs[0].VI[REG_R].UL));
// xAND(xRegister64(regt), 0x7FFFFF);
armAsm->And(a64::XRegister(regt), a64::XRegister(regt), 0x7FFFFF);
armAsm->And(regT.X(), regT.X(), 0x7FFFFF);
}
else if (_Rd_ >= REG_STATUS_FLAG) // FixMe: Should R-Reg have upper 9 bits 0?
{
// xMOVSX(xRegister64(regt), ptr32[&vu0Regs.VI[_Rd_].UL]);
armAsm->Ldrsw(a64::XRegister(regt), PTR_CPU(vuRegs[0].VI[_Rd_].UL));
armAsm->Ldrsw(regT.X(), PTR_CPU(vuRegs[0].VI[_Rd_].UL));
}
else
{
const int vireg = _allocIfUsedVItoX86(_Rd_, MODE_READ);
if (vireg >= 0) {
// xMOVZX(xRegister32(regt), xRegister16(vireg));
armAsm->Uxth(a64::WRegister(regt), a64::WRegister(vireg));
armAsm->Uxth(regT.W(), a64::WRegister(vireg));
}
else {
// xMOVZX(xRegister32(regt), ptr16[&vu0Regs.VI[_Rd_].UL]);
armAsm->Ldrh(a64::WRegister(regt), PTR_CPU(vuRegs[0].VI[_Rd_].UL));
armAsm->Ldrh(regT.W(), PTR_CPU(vuRegs[0].VI[_Rd_].UL));
}
}
}
@@ -589,17 +589,18 @@ static void recCTC2()
}
const int xmmtemp = _allocTempXMMreg(XMMT_INT);
auto regQ = a64::QRegister(xmmtemp);
//Need to update the sticky flags for microVU
// mVUallocSFLAGd(&vu0Regs.VI[REG_STATUS_FLAG].UL);
mVUallocSFLAGd(PTR_CPU(vuRegs[0].VI[REG_STATUS_FLAG].UL));
// xMOVDZX(xRegisterSSE(xmmtemp), eax); // TODO(Stenzek): This can be a broadcast.
armAsm->Fmov(a64::QRegister(xmmtemp).S(), EAX);
armAsm->Fmov(regQ.S(), EAX);
// xSHUF.PS(xRegisterSSE(xmmtemp), xRegisterSSE(xmmtemp), 0);
armSHUFPS(a64::QRegister(xmmtemp), a64::QRegister(xmmtemp), 0);
armSHUFPS(regQ, regQ, 0);
// Make sure the values are everywhere the need to be
// xMOVAPS(ptr128[&vu0Regs.micro_statusflags], xRegisterSSE(xmmtemp));
armAsm->Str(a64::QRegister(xmmtemp).Q(), PTR_CPU(vuRegs[0].micro_statusflags));
armAsm->Str(regQ.Q(), PTR_CPU(vuRegs[0].micro_statusflags));
_freeXMMreg(xmmtemp);
break;
}
@@ -624,16 +625,17 @@ static void recCTC2()
}
const int flagreg = _allocX86reg(X86TYPE_TEMP, 0, MODE_CALLEESAVED);
_eeMoveGPRtoR(a64::WRegister(flagreg), _Rt_);
auto regFlag = a64::WRegister(flagreg);
_eeMoveGPRtoR(regFlag, _Rt_);
iFlushCall(FLUSH_FREE_VU0);
TEST_FBRST_RESET(flagreg, vu0ResetRegs, 0);
TEST_FBRST_RESET(flagreg, vu1ResetRegs, 1);
// xAND(xRegister32(flagreg), 0x0C0C);
armAsm->And(a64::WRegister(flagreg), a64::WRegister(flagreg), 0x0C0C);
armAsm->And(regFlag, regFlag, 0x0C0C);
// xMOV(ptr32[&vu0Regs.VI[REG_FBRST].UL], xRegister32(flagreg));
armAsm->Str(a64::WRegister(flagreg), PTR_CPU(vuRegs[0].VI[REG_FBRST].UL));
armAsm->Str(regFlag, PTR_CPU(vuRegs[0].VI[REG_FBRST].UL));
_freeX86reg(flagreg);
}
break;
@@ -754,7 +756,7 @@ static void recCTC2()
}
else
{
_eeMoveGPRtoM((uptr)&vu0Regs.VI[_Rd_].UL, _Rt_);
_eeMoveGPRtoM(PTR_CPU(vuRegs[0].VI[_Rd_].UL), _Rt_);
}
}
break;
+12 -1
View File
@@ -62,7 +62,7 @@ void mVUloadReg(const xmm& reg, const a64::MemOperand& ptr, int xyzw)
void mVUloadIreg(const xmm& reg, int xyzw, VURegs* vuRegs)
{
// xMOVSSZX(reg, ptr32[&vuRegs->VI[REG_I].UL]);
armAsm->Ldr(reg, armMemOperandPtr(&vuRegs->VI[REG_I].UL));
armAsm->Ldr(reg, PTR_CPU(vuRegs[g_cpuRegistersPack.vuRegs->idx].VI[REG_I].UL));
if (!_XYZWss(xyzw)) {
// xSHUF.PS(reg, reg, 0);
armSHUFPS(reg, reg, 0);
@@ -402,6 +402,17 @@ __fi void mVUaddrFix(mV, const a64::Register& gprReg)
// xAND(xRegister32(gprReg.Id), 0x3f); // ToDo: theres a potential problem if VU0 overrides VU1's VF0/VI0 regs!
armAsm->And(reg32, reg32, 0x3f);
// xADD(gprReg, (u128*)VU1.VF - (u128*)VU0.Mem);
// armAsm->Ldr(RAX, PTR_CPU(vuRegs[0].Mem));
// armAsm->Add(gprReg, gprReg, EEX);
// armAsm->Ldr(RCX, PTR_CPU(vuRegs[1].VF));
// armAsm->Sub(gprReg, gprReg, EEX);
// PTR_CPU(vuRegs[0].Mem);
// armAsm->Sub(REX, RCX, RAX);
// armAsm->Add(gprReg, gprReg, REX);
armAsm->Add(gprReg, gprReg, (u128*)VU1.VF - (u128*)VU0.Mem);
// jmpB.SetTarget();
armBind(&jmpB);