From 5e79fde6d1421d30cf403b39438fe3476ff4914c Mon Sep 17 00:00:00 2001 From: k2154 Date: Fri, 15 Aug 2025 05:31:56 +0900 Subject: [PATCH 01/12] Android project - mVU.regs().Mem => PTR_CPU(vuRegs[mVU.index].Mem) --- app/src/main/cpp/common/arm64/AsmHelpers.h | 1 + app/src/main/cpp/pcsx2/x86/microVU_Branch.inl | 12 +-- .../main/cpp/pcsx2/x86/microVU_Compile.inl | 6 +- .../main/cpp/pcsx2/x86/microVU_Execute.inl | 1 + app/src/main/cpp/pcsx2/x86/microVU_Lower.inl | 88 +++++++++++-------- app/src/main/cpp/pcsx2/x86/microVU_Misc.inl | 2 +- 6 files changed, 63 insertions(+), 47 deletions(-) diff --git a/app/src/main/cpp/common/arm64/AsmHelpers.h b/app/src/main/cpp/common/arm64/AsmHelpers.h index d027345..84a96a2 100644 --- a/app/src/main/cpp/common/arm64/AsmHelpers.h +++ b/app/src/main/cpp/common/arm64/AsmHelpers.h @@ -71,6 +71,7 @@ namespace a64 = vixl::aarch64; // iopMem->Main #define RSTATE_x29 a64::x29 +#define PTR_VU1(field) a64::MemOperand(RSTATE_x29, offsetof(VU_Thread, field)) static inline s64 GetPCDisplacement(const void* current, const void* target) { diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl b/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl index 109926e..10f44e6 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl @@ -456,7 +456,7 @@ void normBranch(mV, microFlagCycles& mFC) u32 tempPC = iPC; if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4)); - armAsm->Tst(armLoadPtr(&vu1Thread.vuFBRST), (isVU1 ? 0x400 : 0x4)); + armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); @@ -486,7 +486,7 @@ void normBranch(mV, microFlagCycles& mFC) u32 tempPC = iPC; if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8)); - armAsm->Tst(armLoadPtr(&vu1Thread.vuFBRST), (isVU1 ? 0x800 : 0x8)); + armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8)); @@ -557,7 +557,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc) u32 tempPC = iPC; if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8)); - armAsm->Tst(armLoadPtr(&vu1Thread.vuFBRST), (isVU1 ? 0x800 : 0x8)); + armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8)); @@ -609,7 +609,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc) u32 tempPC = iPC; if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4)); - armAsm->Tst(armLoadPtr(&vu1Thread.vuFBRST), (isVU1 ? 0x400 : 0x4)); + armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); @@ -800,7 +800,7 @@ void normJump(mV, microFlagCycles& mFC) if (THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4)); - armAsm->Tst(armLoadPtr(&vu1Thread.vuFBRST), (isVU1 ? 0x400 : 0x4)); + armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); @@ -833,7 +833,7 @@ void normJump(mV, microFlagCycles& mFC) if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8)); - armAsm->Tst(armLoadPtr(&vu1Thread.vuFBRST), (isVU1 ? 0x800 : 0x8)); + armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8)); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl b/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl index b9169c0..65cf31b 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl @@ -137,7 +137,7 @@ void doIbit(mV) if (EmuConfig.Gamefixes.IbitHack) { // xMOV(gprT1, ptr32[&curI]); - armAsm->Ldr(gprT1, armMemOperandPtr(&curI)); + armAsm->Ldr(gprT1, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xMOV(ptr32[&mVU.getVI(REG_I)], gprT1); armAsm->Str(gprT1, PTR_CPU(vuRegs[mVU.index].VI[REG_I])); } @@ -597,7 +597,7 @@ void mVUDoDBit(microVU& mVU, microFlagCycles* mFC) { if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4)); - armAsm->Tst(armLoadPtr(&vu1Thread.vuFBRST), (isVU1 ? 0x400 : 0x4)); + armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); @@ -624,7 +624,7 @@ void mVUDoTBit(microVU& mVU, microFlagCycles* mFC) { if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8)); - armAsm->Tst(armLoadPtr(&vu1Thread.vuFBRST), (isVU1 ? 0x800 : 0x8)); + armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8)); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl index 7684ad4..f52a2de 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl @@ -31,6 +31,7 @@ void mVUdispatcherAB(mV) // From memory to registry armMoveAddressToReg(RSTATE_MVU, &g_vuRegistersPack); armMoveAddressToReg(RSTATE_CPU, &g_cpuRegistersPack); + armMoveAddressToReg(RSTATE_x29, &vu1Thread); // = The caller has already put the needed parameters in ecx/edx: if (!isVU1) { diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl b/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl index a588592..6c7ede1 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl @@ -1032,7 +1032,7 @@ mVUop(mVU_IADDI) else { // xMOV(regT, ptr32[&curI]); - armAsm->Ldr(regT, armMemOperandPtr(&curI)); + armAsm->Ldr(regT, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xSHL(regT, 21); armAsm->Lsl(regT, regT, 21); // xSAR(regT, 27); @@ -1053,7 +1053,7 @@ mVUop(mVU_IADDI) else { // xMOV(gprT1, ptr32[&curI]); - armAsm->Ldr(gprT1, armMemOperandPtr(&curI)); + armAsm->Ldr(gprT1, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xSHL(gprT1, 21); armAsm->Lsl(gprT1, gprT1, 21); // xSAR(gprT1, 27); @@ -1091,7 +1091,7 @@ mVUop(mVU_IADDIU) else { // xMOV(regT, ptr32[&curI]); - armAsm->Ldr(regT, armMemOperandPtr(&curI)); + armAsm->Ldr(regT, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xMOV(gprT1, regT); armAsm->Mov(gprT1, regT); // xSHR(gprT1, 10); @@ -1118,7 +1118,7 @@ mVUop(mVU_IADDIU) else { // xMOV(gprT1, ptr32[&curI]); - armAsm->Ldr(gprT1, armMemOperandPtr(&curI)); + armAsm->Ldr(gprT1, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xMOV(gprT2, gprT1); armAsm->Mov(gprT2, gprT1); // xSHR(gprT2, 10); @@ -1218,7 +1218,7 @@ mVUop(mVU_ISUBIU) else { // xMOV(gprT1, ptr32[&curI]); - armAsm->Ldr(gprT1, armMemOperandPtr(&curI)); + armAsm->Ldr(gprT1, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xMOV(gprT2, gprT1); armAsm->Mov(gprT2, gprT1); // xSHR(gprT2, 10); @@ -1373,8 +1373,8 @@ mVUop(mVU_ILW) } pass2 { - void* ptr = mVU.regs().Mem + offsetSS; - std::optional optaddr(EmuConfig.Gamefixes.IbitHack ? std::nullopt : mVUoptimizeConstantAddr(mVU, _Is_, _Imm11_, offsetSS)); +// void* ptr = mVU.regs().Mem + offsetSS; + std::optional optaddr(EmuConfig.Gamefixes.IbitHack ? std::nullopt : mVUoptimizeConstantAddr(mVU, _Is_, _Imm11_, offsetSS)); if (!optaddr.has_value()) { mVU.regAlloc->moveVIToGPR(gprT1, _Is_); @@ -1388,7 +1388,7 @@ mVUop(mVU_ILW) else { // xMOV(gprT2, ptr32[&curI]); - armAsm->Ldr(gprT2, armMemOperandPtr(&curI)); + armAsm->Ldr(gprT2, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xSHL(gprT2, 21); armAsm->Lsl(gprT2, gprT2, 21); // xSAR(gprT2, 21); @@ -1405,7 +1405,8 @@ mVUop(mVU_ILW) if(optaddr.has_value()) { armAsm->Ldrh(regT, optaddr.value()); } else { - armMoveAddressToReg(gprT2q, ptr); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); + armAsm->Add(gprT2q, gprT2q, offsetSS); armAsm->Add(gprT2q, gprT2q, gprT1q); armAsm->Ldrh(regT, a64::MemOperand(gprT2q)); // test= mVU_ILW } @@ -1427,7 +1428,7 @@ mVUop(mVU_ILWR) } pass2 { - void* ptr = mVU.regs().Mem + offsetSS; +// void* ptr = mVU.regs().Mem + offsetSS; if (_Is_) { mVU.regAlloc->moveVIToGPR(gprT1, _Is_); @@ -1435,7 +1436,8 @@ mVUop(mVU_ILWR) const a64::Register& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI); // xMOVZX(regT, ptr16[xComplexAddress(gprT2q, ptr, gprT1q)]); - armMoveAddressToReg(gprT2q, ptr); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); + armAsm->Add(gprT2q, gprT2q, offsetSS); armAsm->Add(gprT2q, gprT2q, gprT1q); armAsm->Ldrh(regT, a64::MemOperand(gprT2q)); mVU.regAlloc->clearNeeded(regT); @@ -1444,7 +1446,9 @@ mVUop(mVU_ILWR) { const a64::Register& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI); // xMOVZX(regT, ptr16[ptr]); - armAsm->Ldrh(regT, armMemOperandPtr(ptr)); + armAsm->Ldr(REX, PTR_CPU(vuRegs[mVU.index].Mem)); + armAsm->Add(REX, REX, offsetSS); + armAsm->Ldrh(regT, a64::MemOperand(REX)); mVU.regAlloc->clearNeeded(regT); } mVU.profiler.EmitOp(opILWR); @@ -1480,7 +1484,7 @@ mVUop(mVU_ISW) else { // xMOV(gprT2, ptr32[&curI]); - armAsm->Ldr(gprT2, armMemOperandPtr(&curI)); + armAsm->Ldr(gprT2, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xSHL(gprT2, 21); armAsm->Lsl(gprT2, gprT2, 21); // xSAR(gprT2, 21); @@ -1499,7 +1503,7 @@ mVUop(mVU_ISW) if(optaddr.has_value()) { ptr = optaddr.value(); } else { - armMoveAddressToReg(gprT2q, mVU.regs().Mem); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); armAsm->Add(gprT2q, gprT2q, gprT1q); ptr = a64::MemOperand(gprT2q); } @@ -1560,7 +1564,8 @@ mVUop(mVU_ISWR) if (register_offset == -1) { // xLEA(gprT2q, ptr[(void*)((sptr)base + offset)]); - armMoveAddressToReg(gprT2q, (void*)((sptr)base + offset)); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); + armAsm->Add(gprT2q, gprT2q, offset); register_offset = offset; } // xMOV(ptr32[gprT2q + is + (offset - register_offset)], regT); @@ -1575,34 +1580,35 @@ mVUop(mVU_ISWR) } else if (is.IsNone()) { - auto base_ = armMemOperandPtr((void*)((uptr)base)); +// auto base_ = armMemOperandPtr((void*)((uptr)base)); + auto base_mop = PTR_CPU(vuRegs[mVU.index].Mem); // if (_X) xMOV(ptr32[(void*)((uptr)base)], regT); if (_X) { - armAsm->Str(regT, base_); + armAsm->Str(regT, base_mop); } // if (_Y) xMOV(ptr32[(void*)((uptr)base + 4)], regT); if (_Y) { - armGetMemOperandInRegister(RXVIXLSCRATCH, base_, 4); + armGetMemOperandInRegister(RXVIXLSCRATCH, base_mop, 4); armAsm->Str(regT, a64::MemOperand(RXVIXLSCRATCH)); } // if (_Z) xMOV(ptr32[(void*)((uptr)base + 8)], regT); if (_Z) { - armGetMemOperandInRegister(RXVIXLSCRATCH, base_, 8); + armGetMemOperandInRegister(RXVIXLSCRATCH, base_mop, 8); armAsm->Str(regT, a64::MemOperand(RXVIXLSCRATCH)); } // if (_W) xMOV(ptr32[(void*)((uptr)base + 12)], regT); if (_W) { - armGetMemOperandInRegister(RXVIXLSCRATCH, base_, 12); + armGetMemOperandInRegister(RXVIXLSCRATCH, base_mop, 12); armAsm->Str(regT, a64::MemOperand(RXVIXLSCRATCH)); } } else { - armMoveAddressToReg(REX, base); + armAsm->Ldr(REX, PTR_CPU(vuRegs[mVU.index].Mem)); armAsm->Add(REX, REX, is); auto base_is = a64::MemOperand(REX); @@ -1659,7 +1665,7 @@ mVUop(mVU_LQ) else { // xMOV(gprT2, ptr32[&curI]); - armAsm->Ldr(gprT2, armMemOperandPtr(&curI)); + armAsm->Ldr(gprT2, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xSHL(gprT2, 21); armAsm->Lsl(gprT2, gprT2, 21); // xSAR(gprT2, 21); @@ -1676,7 +1682,7 @@ mVUop(mVU_LQ) if(optaddr.has_value()) { mVUloadReg(Ft, optaddr.value(), _X_Y_Z_W); } else { - armMoveAddressToReg(gprT2q, mVU.regs().Mem); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); armAsm->Add(gprT2q, gprT2q, gprT1q); mVUloadReg(Ft, a64::MemOperand(gprT2q), _X_Y_Z_W); } @@ -1715,12 +1721,12 @@ mVUop(mVU_LQD) if (is.IsNone()) { // mVUloadReg(Ft, xAddressVoid(ptr), _X_Y_Z_W); - mVUloadReg(Ft, armMemOperandPtr(ptr), _X_Y_Z_W); + mVUloadReg(Ft, PTR_CPU(vuRegs[mVU.index].Mem), _X_Y_Z_W); } else { // mVUloadReg(Ft, xComplexAddress(gprT2q, ptr, is), _X_Y_Z_W); - armMoveAddressToReg(gprT2q, ptr); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); armAsm->Add(gprT2q, gprT2q, is); mVUloadReg(Ft, a64::MemOperand(gprT2q), _X_Y_Z_W); } @@ -1736,7 +1742,7 @@ mVUop(mVU_LQI) pass1 { mVUanalyzeLQ(mVU, _Ft_, _Is_, true); } pass2 { - void* ptr = mVU.regs().Mem; +// void* ptr = mVU.regs().Mem; // xAddressReg is = xEmptyReg; a64::Register is = a64::NoReg; if (_Is_) @@ -1755,11 +1761,11 @@ mVUop(mVU_LQI) const xmm& Ft = mVU.regAlloc->allocReg(-1, _Ft_, _X_Y_Z_W); if (is.IsNone()) { // mVUloadReg(Ft, xAddressVoid(ptr), _X_Y_Z_W); - mVUloadReg(Ft, armMemOperandPtr(ptr), _X_Y_Z_W); + mVUloadReg(Ft, PTR_CPU(vuRegs[mVU.index].Mem), _X_Y_Z_W); } else { // mVUloadReg(Ft, xComplexAddress(gprT2q, ptr, is), _X_Y_Z_W); - armMoveAddressToReg(gprT2q, ptr); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); armAsm->Add(gprT2q, gprT2q, is); mVUloadReg(Ft, a64::MemOperand(gprT2q), _X_Y_Z_W); } @@ -1793,7 +1799,7 @@ mVUop(mVU_SQ) else { // xMOV(gprT2, ptr32[&curI]); - armAsm->Ldr(gprT2, armMemOperandPtr(&curI)); + armAsm->Ldr(gprT2, armOffsetMemOperand(PTR_CPU(vuRegs[mVU.index].Micro), mVU.prog.IRinfo.curPC)); // xSHL(gprT2, 21); armAsm->Lsl(gprT2, gprT2, 21); // xSAR(gprT2, 21); @@ -1810,7 +1816,7 @@ mVUop(mVU_SQ) if(optptr.has_value()) { mVUsaveReg(Fs, optptr.value(), _X_Y_Z_W, 1); } else { - armMoveAddressToReg(gprT2q, mVU.regs().Mem); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); armAsm->Add(gprT2q, gprT2q, gprT1q); mVUsaveReg(Fs, a64::MemOperand(gprT2q), _X_Y_Z_W, 1); } @@ -1846,11 +1852,11 @@ mVUop(mVU_SQD) const xmm& Fs = mVU.regAlloc->allocReg(_Fs_, _XYZW_PS ? -1 : 0, _X_Y_Z_W); if (it.IsNone()) { // mVUsaveReg(Fs, xAddressVoid(ptr), _X_Y_Z_W, 1); - mVUsaveReg(Fs, armMemOperandPtr(ptr), _X_Y_Z_W, 1); + mVUsaveReg(Fs, PTR_CPU(vuRegs[mVU.index].Mem), _X_Y_Z_W, 1); } else { // mVUsaveReg(Fs, xComplexAddress(gprT2q, ptr, it), _X_Y_Z_W, 1); - armMoveAddressToReg(gprT2q, ptr); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); armAsm->Add(gprT2q, gprT2q, it); mVUsaveReg(Fs, a64::MemOperand(gprT2q), _X_Y_Z_W, 1); } @@ -1865,7 +1871,7 @@ mVUop(mVU_SQI) pass1 { mVUanalyzeSQ(mVU, _Fs_, _It_, true); } pass2 { - void* ptr = mVU.regs().Mem; +// void* ptr = mVU.regs().Mem; if (_It_) { const a64::Register& regT = mVU.regAlloc->allocGPR(_It_, _It_, mVUlow.backupVI); @@ -1879,13 +1885,13 @@ mVUop(mVU_SQI) const xmm& Fs = mVU.regAlloc->allocReg(_Fs_, _XYZW_PS ? -1 : 0, _X_Y_Z_W); if (_It_) { // mVUsaveReg(Fs, xComplexAddress(gprT2q, ptr, gprT1q), _X_Y_Z_W, 1); - armMoveAddressToReg(gprT2q, ptr); + armAsm->Ldr(gprT2q, PTR_CPU(vuRegs[mVU.index].Mem)); armAsm->Add(gprT2q, gprT2q, gprT1q); mVUsaveReg(Fs, a64::MemOperand(gprT2q), _X_Y_Z_W, 1); } else { // mVUsaveReg(Fs, xAddressVoid(ptr), _X_Y_Z_W, 1); - mVUsaveReg(Fs, armMemOperandPtr(ptr), _X_Y_Z_W, 1); + mVUsaveReg(Fs, PTR_CPU(vuRegs[mVU.index].Mem), _X_Y_Z_W, 1); } mVU.regAlloc->clearNeeded(Fs); mVU.profiler.EmitOp(opSQI); @@ -2062,7 +2068,11 @@ mVUop(mVU_XTOP) { const a64::Register& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI); // xMOVZX(regT, ptr16[&mVU.getVifRegs().top]); - armAsm->Ldrh(regT, armMemOperandPtr(&mVU.getVifRegs().top)); + if (mVU.index && THREAD_VU1) { + armAsm->Ldrh(regT, PTR_VU1(vifRegs.top)); + } else { + armAsm->Ldrh(regT, armMemOperandPtr(&mVU.getVifRegs().top)); + } mVU.regAlloc->clearNeeded(regT); mVU.profiler.EmitOp(opXTOP); } @@ -2082,7 +2092,11 @@ mVUop(mVU_XITOP) { const a64::Register& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI); // xMOVZX(regT, ptr16[&mVU.getVifRegs().itop]); - armAsm->Ldrh(regT, armMemOperandPtr(&mVU.getVifRegs().itop)); + if (mVU.index && THREAD_VU1) { + armAsm->Ldrh(regT, PTR_VU1(vifRegs.itop)); + } else { + armAsm->Ldrh(regT, armMemOperandPtr(&mVU.getVifRegs().itop)); + } // xAND(regT, isVU1 ? 0x3ff : 0xff); armAsm->And(regT, regT, isVU1 ? 0x3ff : 0xff); mVU.regAlloc->clearNeeded(regT); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl index 74d94ce..f8ab5a5 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl @@ -362,7 +362,7 @@ static void mVUwaitMTVU() // Transforms the Address in gprReg to valid VU0/VU1 Address __fi void mVUaddrFix(mV, const a64::Register& gprReg) { - auto reg32 = a64::WRegister(gprReg); + auto reg32 = gprReg.W(); if (isVU1) { // xAND(xRegister32(gprReg.Id), 0x3ff); // wrap around From 3ca937df0007300cbd42c029e2168d66423199e2 Mon Sep 17 00:00:00 2001 From: k2154 Date: Sat, 16 Aug 2025 01:20:39 +0900 Subject: [PATCH 02/12] Android project - Modify the _eeMoveGPRtoM function --- app/src/main/cpp/common/Pcsx2Defs.h | 4 +- app/src/main/cpp/pcsx2/x86/iCOP0.cpp | 10 ++--- app/src/main/cpp/pcsx2/x86/iR5900.h | 2 +- app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp | 12 +++--- .../main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp | 2 +- app/src/main/cpp/pcsx2/x86/microVU.h | 5 ++- .../main/cpp/pcsx2/x86/microVU_Execute.inl | 38 ++++++++--------- app/src/main/cpp/pcsx2/x86/microVU_Macro.inl | 42 ++++++++++--------- app/src/main/cpp/pcsx2/x86/microVU_Misc.inl | 13 +++++- 9 files changed, 70 insertions(+), 58 deletions(-) diff --git a/app/src/main/cpp/common/Pcsx2Defs.h b/app/src/main/cpp/common/Pcsx2Defs.h index be997ec..86f1261 100644 --- a/app/src/main/cpp/common/Pcsx2Defs.h +++ b/app/src/main/cpp/common/Pcsx2Defs.h @@ -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; diff --git a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp index 30a90c8..525d12a 100644 --- a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp +++ b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp @@ -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(COP0_UpdatePCCR)); - _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.PERF.n.pccr), _Rt_); // xFastCall((void*)COP0_DiagnosticPCCR); armEmitCall(reinterpret_cast(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; } } diff --git a/app/src/main/cpp/pcsx2/x86/iR5900.h b/app/src/main/cpp/pcsx2/x86/iR5900.h index 3e9c585..c4735b8 100644 --- a/app/src/main/cpp/pcsx2/x86/iR5900.h +++ b/app/src/main/cpp/pcsx2/x86/iR5900.h @@ -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); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp index e5830c5..29278af 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp @@ -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); } } } diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp index 94a6c72..96c94a8 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900Jump.cpp @@ -168,7 +168,7 @@ void recJALR() } else { - _eeMoveGPRtoM((uptr)&cpuRegs.pc, _Rs_); + _eeMoveGPRtoM(PTR_CPU(cpuRegs.pc), _Rs_); } } diff --git a/app/src/main/cpp/pcsx2/x86/microVU.h b/app/src/main/cpp/pcsx2/x86/microVU.h index 4441cf8..38f7084 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU.h +++ b/app/src/main/cpp/pcsx2/x86/microVU.h @@ -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) { diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl index f52a2de..64a57ae 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl @@ -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(); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Macro.inl b/app/src/main/cpp/pcsx2/x86/microVU_Macro.inl index 377e244..5295944 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Macro.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Macro.inl @@ -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; diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl index f8ab5a5..2f15850 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl @@ -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); From f5a2533be3ed0fe3685fb6d1eeff8bec5aac9c0f Mon Sep 17 00:00:00 2001 From: k2154 Date: Sat, 16 Aug 2025 05:06:43 +0900 Subject: [PATCH 03/12] Android project - mVU_Globals => PTR_CPU(mVUglob) --- app/src/main/cpp/common/arm64/AsmHelpers.h | 3 +- app/src/main/cpp/pcsx2/R5900.cpp | 2 +- app/src/main/cpp/pcsx2/VUDef.h | 38 +++++++++++ app/src/main/cpp/pcsx2/cpuRegistersPack.h | 4 +- app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp | 1 + app/src/main/cpp/pcsx2/x86/microVU_Branch.inl | 6 +- app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl | 8 +-- .../main/cpp/pcsx2/x86/microVU_Execute.inl | 6 +- app/src/main/cpp/pcsx2/x86/microVU_Lower.inl | 64 +++++++++---------- app/src/main/cpp/pcsx2/x86/microVU_Misc.h | 40 +----------- app/src/main/cpp/pcsx2/x86/microVU_Misc.inl | 16 ++--- app/src/main/cpp/pcsx2/x86/microVU_Upper.inl | 36 ++++++----- 12 files changed, 111 insertions(+), 113 deletions(-) diff --git a/app/src/main/cpp/common/arm64/AsmHelpers.h b/app/src/main/cpp/common/arm64/AsmHelpers.h index 84a96a2..960f624 100644 --- a/app/src/main/cpp/common/arm64/AsmHelpers.h +++ b/app/src/main/cpp/common/arm64/AsmHelpers.h @@ -57,6 +57,7 @@ namespace a64 = vixl::aarch64; // fastmem #define RFASTMEMBASE a64::x25 +#define PTR_MBLOCK(field) a64::MemOperand(RFASTMEMBASE, offsetof(microBlock, field)) #define RSTATE_x26 a64::x26 @@ -69,7 +70,7 @@ namespace a64 = vixl::aarch64; #define RSTATE_MVU a64::x28 #define PTR_MVU(field) a64::MemOperand(RSTATE_MVU, offsetof(vuRegistersPack, field)) -// iopMem->Main +// iopMem->Main, vu1Thread #define RSTATE_x29 a64::x29 #define PTR_VU1(field) a64::MemOperand(RSTATE_x29, offsetof(VU_Thread, field)) diff --git a/app/src/main/cpp/pcsx2/R5900.cpp b/app/src/main/cpp/pcsx2/R5900.cpp index 3f26d33..71d0671 100644 --- a/app/src/main/cpp/pcsx2/R5900.cpp +++ b/app/src/main/cpp/pcsx2/R5900.cpp @@ -34,7 +34,7 @@ using namespace R5900; // for R5900 disasm tools s32 EEsCycle; // used to sync the IOP to the EE u32 EEoCycle; -alignas(16) cpuRegistersPack g_cpuRegistersPack; +alignas(32) cpuRegistersPack g_cpuRegistersPack; alignas(16) tlbs tlb[48]; cachedTlbs_t cachedTlbs; diff --git a/app/src/main/cpp/pcsx2/VUDef.h b/app/src/main/cpp/pcsx2/VUDef.h index a978cc5..17e75fb 100644 --- a/app/src/main/cpp/pcsx2/VUDef.h +++ b/app/src/main/cpp/pcsx2/VUDef.h @@ -170,4 +170,42 @@ struct alignas(16) VURegs } }; +struct mVU_Globals +{ +#define __four(val) { val, val, val, val } + u32 absclip [4] = __four(0x7fffffff); + u32 signbit [4] = __four(0x80000000); + u32 minvals [4] = __four(0xff7fffff); + u32 maxvals [4] = __four(0x7f7fffff); + u32 exponent[4] = __four(0x7f800000); + u32 one [4] = __four(0x3f800000); + u32 Pi4 [4] = __four(0x3f490fdb); + u32 T1 [4] = __four(0x3f7ffff5); + u32 T5 [4] = __four(0xbeaaa61c); + u32 T2 [4] = __four(0x3e4c40a6); + u32 T3 [4] = __four(0xbe0e6c63); + u32 T4 [4] = __four(0x3dc577df); + u32 T6 [4] = __four(0xbd6501c4); + u32 T7 [4] = __four(0x3cb31652); + u32 T8 [4] = __four(0xbb84d7e7); + u32 S2 [4] = __four(0xbe2aaaa4); + u32 S3 [4] = __four(0x3c08873e); + u32 S4 [4] = __four(0xb94fb21f); + u32 S5 [4] = __four(0x362e9c14); + u32 E1 [4] = __four(0x3e7fffa8); + u32 E2 [4] = __four(0x3d0007f4); + u32 E3 [4] = __four(0x3b29d3ff); + u32 E4 [4] = __four(0x3933e553); + u32 E5 [4] = __four(0x36b63510); + u32 E6 [4] = __four(0x353961ac); + u32 I32MAXF [4] = __four(0x4effffff); + float FTOI_4 [4] = __four(16.0); + float FTOI_12 [4] = __four(4096.0); + float FTOI_15 [4] = __four(32768.0); + float ITOF_4 [4] = __four(0.0625f); + float ITOF_12 [4] = __four(0.000244140625); + float ITOF_15 [4] = __four(0.000030517578125); +#undef __four +}; + #endif //PCSX2_VUDEF_H diff --git a/app/src/main/cpp/pcsx2/cpuRegistersPack.h b/app/src/main/cpp/pcsx2/cpuRegistersPack.h index b0dbd40..5d3ffa6 100644 --- a/app/src/main/cpp/pcsx2/cpuRegistersPack.h +++ b/app/src/main/cpp/pcsx2/cpuRegistersPack.h @@ -15,13 +15,15 @@ struct cpuRegistersPack alignas(16) fpuRegisters fpuRegs{}; alignas(16) psxRegisters psxRegs{}; alignas(16) VURegs vuRegs[2]; + alignas(32) mVU_Globals mVUglob; }; -alignas(16) extern cpuRegistersPack g_cpuRegistersPack; +alignas(32) extern cpuRegistersPack g_cpuRegistersPack; //// static cpuRegisters& cpuRegs = g_cpuRegistersPack.cpuRegs; static fpuRegisters& fpuRegs = g_cpuRegistersPack.fpuRegs; static psxRegisters& psxRegs = g_cpuRegistersPack.psxRegs; static VURegs& VU0 = g_cpuRegistersPack.vuRegs[0]; static VURegs& VU1 = g_cpuRegistersPack.vuRegs[1]; +static mVU_Globals& mVUglob = g_cpuRegistersPack.mVUglob; #endif //PCSX2_CPUREGISTERSPACK_H diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp index 29278af..ac3cac8 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp @@ -20,6 +20,7 @@ #include "common/FastJmp.h" #include "common/HeapArray.h" #include "common/Perf.h" +#include "x86/microVU_Misc.h" // Only for MOVQ workaround. #if !defined(__ANDROID__) diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl b/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl index 10f44e6..7d8a3a1 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl @@ -413,7 +413,7 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump) else { // xLoadFarAddr(arg2reg, &mVUpBlock->pStateEnd); - armMoveAddressToReg(RCX, &mVUpBlock->pStateEnd); + armAsm->Ldr(RCX, PTR_MBLOCK(pStateEnd)); } if (mVUup.eBit && isEvilJump) // E-bit EvilJump @@ -515,7 +515,7 @@ void normBranch(mV, microFlagCycles& mFC) memcpy(&mVUpBlock->pStateEnd, &mVUregs, sizeof(microRegInfo)); // xLoadFarAddr(rax, &mVUpBlock->pStateEnd); - armMoveAddressToReg(RAX, &mVUpBlock->pStateEnd); + armAsm->Ldr(RAX, PTR_MBLOCK(pStateEnd)); // xCALL((void*)mVU.copyPLState); armEmitCall(mVU.copyPLState); @@ -654,7 +654,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc) memcpy(&mVUpBlock->pStateEnd, &mVUregs, sizeof(microRegInfo)); // xLoadFarAddr(rax, &mVUpBlock->pStateEnd); - armMoveAddressToReg(RAX, &mVUpBlock->pStateEnd); + armAsm->Ldr(RAX, PTR_MBLOCK(pStateEnd)); // xCALL((void*)mVU.copyPLState); armEmitCall(mVU.copyPLState); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl b/app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl index 60b27cf..e64176a 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl @@ -30,15 +30,15 @@ void mVUclamp1(microVU& mVU, const xmm& reg, const xmm& regT1, int xyzw, bool bC { case 1: case 2: case 4: case 8: // xMIN.SS(reg, ptr32[mVUglob.maxvals]); - armAsm->Fminnm(reg.S(), reg.S(), armLoadPtrV(mVUglob.maxvals).S()); + armAsm->Fminnm(reg.S(), reg.S(), armLoadPtrV(PTR_CPU(mVUglob.maxvals)).S()); // xMAX.SS(reg, ptr32[mVUglob.minvals]); - armAsm->Fmaxnm(reg.S(), reg.S(), armLoadPtrV(mVUglob.minvals).S()); + armAsm->Fmaxnm(reg.S(), reg.S(), armLoadPtrV(PTR_CPU(mVUglob.minvals)).S()); break; default: // xMIN.PS(reg, ptr32[mVUglob.maxvals]); - armAsm->Fminnm(reg.V4S(), reg.V4S(), armLoadPtrV(mVUglob.maxvals).V4S()); + armAsm->Fminnm(reg.V4S(), reg.V4S(), armLoadPtrV(PTR_CPU(mVUglob.maxvals)).V4S()); // xMAX.PS(reg, ptr32[mVUglob.minvals]); - armAsm->Fmaxnm(reg.V4S(), reg.V4S(), armLoadPtrV(mVUglob.minvals).V4S()); + armAsm->Fmaxnm(reg.V4S(), reg.V4S(), armLoadPtrV(PTR_CPU(mVUglob.minvals)).V4S()); break; } } diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl index 64a57ae..50c9913 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl @@ -23,15 +23,15 @@ static bool mvuNeedsFPCRUpdate(mV) void mVUdispatcherAB(mV) { mVU.startFunct = armStartBlock(); - { // xScopedStackFrame frame(false, true); armBeginStackFrame(); // From memory to registry + armMoveAddressToReg(RSTATE_x29, &vu1Thread); armMoveAddressToReg(RSTATE_MVU, &g_vuRegistersPack); armMoveAddressToReg(RSTATE_CPU, &g_cpuRegistersPack); - armMoveAddressToReg(RSTATE_x29, &vu1Thread); + armMoveAddressToReg(RFASTMEMBASE, &mVUpBlock); // = The caller has already put the needed parameters in ecx/edx: if (!isVU1) { @@ -139,7 +139,6 @@ void mVUdispatcherAB(mV) void mVUdispatcherCD(mV) { mVU.startFunctXG = armStartBlock(); - { // xScopedStackFrame frame(false, true); armBeginStackFrame(); @@ -261,7 +260,6 @@ static void mVUGenerateWaitMTVU(mV) static void mVUGenerateCopyPipelineState(mV) { mVU.copyPLState = armStartBlock(); - { // xMOVAPS(xmm0, ptr[rax]); armAsm->Ldr(xmm0, a64::MemOperand(RAX)); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl b/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl index 6c7ede1..21aca52 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl @@ -35,7 +35,7 @@ static __fi void testNeg(mV, const xmm& xmmReg, const x32& gprTemp) // xMOV(ptr32[&mVU.divFlag], divI); armStorePtr(divI, PTR_MVU(microVU[mVU.index].divFlag)); // xAND.PS(xmmReg, ptr128[mVUglob.absclip]); - armAsm->And(xmmReg.V16B(), xmmReg.V16B(), armLoadPtrV(mVUglob.absclip).V16B()); + armAsm->And(xmmReg.V16B(), xmmReg.V16B(), armLoadPtrV(PTR_CPU(mVUglob.absclip)).V16B()); // skip.SetTarget(); armBind(&skip); } @@ -75,9 +75,9 @@ mVUop(mVU_DIV) // xXOR.PS(Fs, Ft); armAsm->Eor(Fs.V16B(), Fs.V16B(), Ft.V16B()); // xAND.PS(Fs, ptr128[mVUglob.signbit]); - armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(mVUglob.signbit).V16B()); + armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(PTR_CPU(mVUglob.signbit)).V16B()); // xOR.PS (Fs, ptr128[mVUglob.maxvals]); // If division by zero, then xmmFs = +/- fmax - armAsm->Orr(Fs.V16B(), Fs.V16B(), armLoadPtrV(mVUglob.maxvals).V16B()); + armAsm->Orr(Fs.V16B(), Fs.V16B(), armLoadPtrV(PTR_CPU(mVUglob.maxvals)).V16B()); // xForwardJump8 djmp; a64::Label djmp; @@ -122,7 +122,7 @@ mVUop(mVU_SQRT) if (CHECK_VU_OVERFLOW(mVU.index)) { // Clamp infinities (only need to do positive clamp since xmmFt is positive) // xMIN.SS(Ft, ptr32[mVUglob.maxvals]); - armAsm->Umin(Ft.V4S(), Ft.V4S(), armLoadPtrV(mVUglob.maxvals).V4S()); + armAsm->Umin(Ft.V4S(), Ft.V4S(), armLoadPtrV(PTR_CPU(mVUglob.maxvals)).V4S()); } // xSQRT.SS(Ft, Ft); armAsm->Fsqrt(Ft.S(), Ft.S()); @@ -179,9 +179,9 @@ mVUop(mVU_RSQRT) armBind(&cjmp); // xAND.PS(Fs, ptr128[mVUglob.signbit]); - armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(mVUglob.signbit).V16B()); + armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(PTR_CPU(mVUglob.signbit)).V16B()); // xOR.PS(Fs, ptr128[mVUglob.maxvals]); // xmmFs = +/-Max - armAsm->Orr(Fs.V16B(), Fs.V16B(), armLoadPtrV(mVUglob.maxvals).V16B()); + armAsm->Orr(Fs.V16B(), Fs.V16B(), armLoadPtrV(PTR_CPU(mVUglob.maxvals)).V16B()); // xForwardJump8 djmp; a64::Label djmp; @@ -230,18 +230,18 @@ static __fi void mVU_EATAN_(mV, const xmm& PQ, const xmm& Fs, const xmm& t1, con // xMOVSS(PQ, Fs); armAsm->Mov(PQ.S(), 0, Fs.S(), 0); // xMUL.SS(PQ, ptr32[mVUglob.T1]); - armAsm->Fmul(PQ.S(), PQ.S(), armLoadPtrV(mVUglob.T1).S()); + armAsm->Fmul(PQ.S(), PQ.S(), armLoadPtrV(PTR_CPU(mVUglob.T1)).S()); // xMOVAPS(t2, Fs); armAsm->Mov(t2.Q(), Fs.Q()); - EATANhelper(mVUglob.T2); - EATANhelper(mVUglob.T3); - EATANhelper(mVUglob.T4); - EATANhelper(mVUglob.T5); - EATANhelper(mVUglob.T6); - EATANhelper(mVUglob.T7); - EATANhelper(mVUglob.T8); + EATANhelper(PTR_CPU(mVUglob.T2)); + EATANhelper(PTR_CPU(mVUglob.T3)); + EATANhelper(PTR_CPU(mVUglob.T4)); + EATANhelper(PTR_CPU(mVUglob.T5)); + EATANhelper(PTR_CPU(mVUglob.T6)); + EATANhelper(PTR_CPU(mVUglob.T7)); + EATANhelper(PTR_CPU(mVUglob.T8)); // xADD.SS(PQ, ptr32[mVUglob.Pi4]); - armAsm->Fadd(PQ.S(), PQ.S(), armLoadPtrV(mVUglob.Pi4).S()); + armAsm->Fadd(PQ.S(), PQ.S(), armLoadPtrV(PTR_CPU(mVUglob.Pi4)).S()); // xPSHUF.D(PQ, PQ, mVUinfo.writeP ? 0x27 : 0xC6); armPSHUFD(PQ, PQ, mVUinfo.writeP ? 0x27 : 0xC6); } @@ -267,9 +267,9 @@ mVUop(mVU_EATAN) // xMOVSS (xmmPQ, Fs); armAsm->Mov(xmmPQ.S(), 0, Fs.S(), 0); // xSUB.SS(Fs, ptr32[mVUglob.one]); - armAsm->Fsub(Fs.S(), Fs.S(), armLoadPtrV(mVUglob.one).S()); + armAsm->Fsub(Fs.S(), Fs.S(), armLoadPtrV(PTR_CPU(mVUglob.one)).S()); // xADD.SS(xmmPQ, ptr32[mVUglob.one]); - armAsm->Fadd(xmmPQ.S(), xmmPQ.S(), armLoadPtrV(mVUglob.one).S()); + armAsm->Fadd(xmmPQ.S(), xmmPQ.S(), armLoadPtrV(PTR_CPU(mVUglob.one)).S()); SSE_DIVSS(mVU, Fs, xmmPQ); mVU_EATAN_(mVU, xmmPQ, Fs, t1, t2); mVU.regAlloc->clearNeeded(Fs); @@ -377,28 +377,28 @@ mVUop(mVU_EEXP) // xMOVSS (xmmPQ, Fs); armAsm->Mov(xmmPQ.S(), 0, Fs.S(), 0); // xMUL.SS (xmmPQ, ptr32[mVUglob.E1]); - armAsm->Fmul(xmmPQ.S(), xmmPQ.S(), armLoadPtrV(mVUglob.E1).S()); + armAsm->Fmul(xmmPQ.S(), xmmPQ.S(), armLoadPtrV(PTR_CPU(mVUglob.E1)).S()); // xADD.SS (xmmPQ, ptr32[mVUglob.one]); - armAsm->Fadd(xmmPQ.S(), xmmPQ.S(), armLoadPtrV(mVUglob.one).S()); + armAsm->Fadd(xmmPQ.S(), xmmPQ.S(), armLoadPtrV(PTR_CPU(mVUglob.one)).S()); // xMOVAPS(t1, Fs); armAsm->Mov(t1.Q(), Fs.Q()); SSE_MULSS(mVU, t1, Fs); // xMOVAPS(t2, t1); armAsm->Mov(t2.Q(), t1.Q()); // xMUL.SS(t1, ptr32[mVUglob.E2]); - armAsm->Fmul(t1.S(), t1.S(), armLoadPtrV(mVUglob.E2).S()); + armAsm->Fmul(t1.S(), t1.S(), armLoadPtrV(PTR_CPU(mVUglob.E2)).S()); SSE_ADDSS(mVU, xmmPQ, t1); eexpHelper(&mVUglob.E3); eexpHelper(&mVUglob.E4); eexpHelper(&mVUglob.E5); SSE_MULSS(mVU, t2, Fs); // xMUL.SS(t2, ptr32[mVUglob.E6]); - armAsm->Fmul(t2.S(), t2.S(), armLoadPtrV(mVUglob.E6).S()); + armAsm->Fmul(t2.S(), t2.S(), armLoadPtrV(PTR_CPU(mVUglob.E6)).S()); SSE_ADDSS(mVU, xmmPQ, t2); SSE_MULSS(mVU, xmmPQ, xmmPQ); SSE_MULSS(mVU, xmmPQ, xmmPQ); // xMOVSSZX(t2, ptr32[mVUglob.one]); - armAsm->Ldr(t2, armMemOperandPtr(mVUglob.one)); + armAsm->Ldr(t2, PTR_CPU(mVUglob.one)); SSE_DIVSS(mVU, t2, xmmPQ); // xMOVSS(xmmPQ, t2); armAsm->Mov(xmmPQ.S(), 0, t2.S(), 0); @@ -470,7 +470,7 @@ mVUop(mVU_ERCPR) // xMOVSS (xmmPQ, Fs); armAsm->Mov(xmmPQ.S(), 0, Fs.S(), 0); // xMOVSSZX (Fs, ptr32[mVUglob.one]); - armAsm->Ldr(Fs, armMemOperandPtr(mVUglob.one)); + armAsm->Ldr(Fs, PTR_CPU(mVUglob.one)); SSE_DIVSS(mVU, Fs, xmmPQ); // xMOVSS (xmmPQ, Fs); armAsm->Mov(xmmPQ.S(), 0, Fs.S(), 0); @@ -503,7 +503,7 @@ mVUop(mVU_ERLENG) armAsm->Fsqrt(RQSCRATCH.S(), RQSCRATCH.S()); armAsm->Mov(xmmPQ.S(), 0, RQSCRATCH.S(), 0); // xMOVSSZX (Fs, ptr32[mVUglob.one]); - armAsm->Ldr(Fs, armMemOperandPtr(mVUglob.one)); + armAsm->Ldr(Fs, PTR_CPU(mVUglob.one)); SSE_DIVSS (mVU, Fs, xmmPQ); // xMOVSS (xmmPQ, Fs); armAsm->Mov(xmmPQ.S(), 0, Fs.S(), 0); @@ -533,7 +533,7 @@ mVUop(mVU_ERSADD) armPSHUFD(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); mVU_sumXYZ(mVU, xmmPQ, Fs); // xMOVSSZX (Fs, ptr32[mVUglob.one]); - armAsm->Ldr(Fs, armMemOperandPtr(mVUglob.one)); + armAsm->Ldr(Fs, PTR_CPU(mVUglob.one)); SSE_DIVSS (mVU, Fs, xmmPQ); // xMOVSS (xmmPQ, Fs); armAsm->Mov(xmmPQ.S(), 0, Fs.S(), 0); @@ -562,11 +562,11 @@ mVUop(mVU_ERSQRT) // xPSHUF.D (xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance armPSHUFD(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // xAND.PS (Fs, ptr128[mVUglob.absclip]); - armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(mVUglob.absclip).V16B()); + armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(PTR_CPU(mVUglob.absclip)).V16B()); // xSQRT.SS (xmmPQ, Fs); armAsm->Fsqrt(xmmPQ.S(), Fs.S()); // xMOVSSZX (Fs, ptr32[mVUglob.one]); - armAsm->Ldr(Fs, armMemOperandPtr(mVUglob.one)); + armAsm->Ldr(Fs, PTR_CPU(mVUglob.one)); SSE_DIVSS(mVU, Fs, xmmPQ); // xMOVSS (xmmPQ, Fs); armAsm->Mov(xmmPQ.S(), 0, Fs.S(), 0); @@ -630,26 +630,26 @@ mVUop(mVU_ESIN) // xMOVAPS (t2, Fs); // t2 = X^3 armAsm->Mov(t2, Fs); // xMUL.SS (Fs, ptr32[mVUglob.S2]); // fs = s2 * X^3 - armAsm->Fmul(Fs.S(), Fs.S(), armLoadPtrV(mVUglob.S2).S()); + armAsm->Fmul(Fs.S(), Fs.S(), armLoadPtrV(PTR_CPU(mVUglob.S2)).S()); SSE_ADDSS(mVU, xmmPQ, Fs); // pq = X + s2 * X^3 SSE_MULSS(mVU, t2, t1); // t2 = X^3 * X^2 // xMOVAPS (Fs, t2); // fs = X^5 armAsm->Mov(Fs, t2); // xMUL.SS (Fs, ptr32[mVUglob.S3]); // ps = s3 * X^5 - armAsm->Fmul(Fs.S(), Fs.S(), armLoadPtrV(mVUglob.S3).S()); + armAsm->Fmul(Fs.S(), Fs.S(), armLoadPtrV(PTR_CPU(mVUglob.S3)).S()); SSE_ADDSS(mVU, xmmPQ, Fs); // pq = X + s2 * X^3 + s3 * X^5 SSE_MULSS(mVU, t2, t1); // t2 = X^5 * X^2 // xMOVAPS (Fs, t2); // fs = X^7 armAsm->Mov(Fs, t2); // xMUL.SS (Fs, ptr32[mVUglob.S4]); // fs = s4 * X^7 - armAsm->Fmul(Fs.S(), Fs.S(), armLoadPtrV(mVUglob.S4).S()); + armAsm->Fmul(Fs.S(), Fs.S(), armLoadPtrV(PTR_CPU(mVUglob.S4)).S()); SSE_ADDSS(mVU, xmmPQ, Fs); // pq = X + s2 * X^3 + s3 * X^5 + s4 * X^7 SSE_MULSS(mVU, t2, t1); // t2 = X^7 * X^2 // xMUL.SS (t2, ptr32[mVUglob.S5]); // t2 = s5 * X^9 - armAsm->Fmul(t2.S(), t2.S(), armLoadPtrV(mVUglob.S5).S()); + armAsm->Fmul(t2.S(), t2.S(), armLoadPtrV(PTR_CPU(mVUglob.S5)).S()); SSE_ADDSS(mVU, xmmPQ, t2); // pq = X + s2 * X^3 + s3 * X^5 + s4 * X^7 + s5 * X^9 // xPSHUF.D (xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back armPSHUFD(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); @@ -678,7 +678,7 @@ mVUop(mVU_ESQRT) // xPSHUF.D(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance armPSHUFD(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // xAND.PS (Fs, ptr128[mVUglob.absclip]); - armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(mVUglob.absclip).V16B()); + armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(PTR_CPU(mVUglob.absclip)).V16B()); // xSQRT.SS(xmmPQ, Fs); armAsm->Fsqrt(xmmPQ.S(), Fs.S()); // xPSHUF.D(xmmPQ, xmmPQ, mVUinfo.writeP ? 0x27 : 0xC6); // Flip back diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Misc.h b/app/src/main/cpp/pcsx2/x86/microVU_Misc.h index 98cbee5..e99e6a2 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Misc.h +++ b/app/src/main/cpp/pcsx2/x86/microVU_Misc.h @@ -16,45 +16,7 @@ struct microVU; // Global Variables //------------------------------------------------------------------ -struct mVU_Globals -{ -#define __four(val) { val, val, val, val } - u32 absclip [4] = __four(0x7fffffff); - u32 signbit [4] = __four(0x80000000); - u32 minvals [4] = __four(0xff7fffff); - u32 maxvals [4] = __four(0x7f7fffff); - u32 exponent[4] = __four(0x7f800000); - u32 one [4] = __four(0x3f800000); - u32 Pi4 [4] = __four(0x3f490fdb); - u32 T1 [4] = __four(0x3f7ffff5); - u32 T5 [4] = __four(0xbeaaa61c); - u32 T2 [4] = __four(0x3e4c40a6); - u32 T3 [4] = __four(0xbe0e6c63); - u32 T4 [4] = __four(0x3dc577df); - u32 T6 [4] = __four(0xbd6501c4); - u32 T7 [4] = __four(0x3cb31652); - u32 T8 [4] = __four(0xbb84d7e7); - u32 S2 [4] = __four(0xbe2aaaa4); - u32 S3 [4] = __four(0x3c08873e); - u32 S4 [4] = __four(0xb94fb21f); - u32 S5 [4] = __four(0x362e9c14); - u32 E1 [4] = __four(0x3e7fffa8); - u32 E2 [4] = __four(0x3d0007f4); - u32 E3 [4] = __four(0x3b29d3ff); - u32 E4 [4] = __four(0x3933e553); - u32 E5 [4] = __four(0x36b63510); - u32 E6 [4] = __four(0x353961ac); - u32 I32MAXF [4] = __four(0x4effffff); - float FTOI_4 [4] = __four(16.0); - float FTOI_12 [4] = __four(4096.0); - float FTOI_15 [4] = __four(32768.0); - float ITOF_4 [4] = __four(0.0625f); - float ITOF_12 [4] = __four(0.000244140625); - float ITOF_15 [4] = __four(0.000030517578125); -#undef __four -}; - -alignas(32) static constexpr struct mVU_Globals mVUglob; +//alignas(32) static constexpr struct mVU_Globals mVUglob; static const uint _Ibit_ = 1 << 31; static const uint _Ebit_ = 1 << 30; diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl index 2f15850..b821da0 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl @@ -401,19 +401,13 @@ __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); + a64::MemOperand mop1 = PTR_CPU(vuRegs[1].VF); + a64::MemOperand mop2 = PTR_CPU(vuRegs[0].Mem); + armAsm->Sub(REX, mop1.GetBaseRegister(), mop2.GetBaseRegister()); + armAsm->Add(gprReg, gprReg, REX); -// 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); // xSHL(gprReg, 4); // multiply by 16 (shift left by 4) diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Upper.inl b/app/src/main/cpp/pcsx2/x86/microVU_Upper.inl index f87b7fd..e6c492f 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Upper.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Upper.inl @@ -454,7 +454,7 @@ mVUop(mVU_ABS) return; const xmm& Fs = mVU.regAlloc->allocReg(_Fs_, _Ft_, _X_Y_Z_W, !((_Fs_ == _Ft_) && (_X_Y_Z_W == 0xf))); // xAND.PS(Fs, ptr128[mVUglob.absclip]); - armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(mVUglob.absclip).V16B()); + armAsm->And(Fs.V16B(), Fs.V16B(), armLoadPtrV(PTR_CPU(mVUglob.absclip)).V16B()); mVU.regAlloc->clearNeeded(Fs); mVU.profiler.EmitOp(opABS); } @@ -525,7 +525,8 @@ mVUop(mVU_OPMSUB) } // FTOI0/FTIO4/FTIO12/FTIO15 Opcodes -static void mVU_FTOIx(mP, const float* addr, microOpcode opEnum) +//static void mVU_FTOIx(mP, const float* addr, microOpcode opEnum) +static void mVU_FTOIx(mP, const a64::MemOperand& addr, microOpcode opEnum) { pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); } pass2 @@ -538,14 +539,14 @@ static void mVU_FTOIx(mP, const float* addr, microOpcode opEnum) // cvttps2dq returns 0x8000000 for any unrepresentable values. // We want it to return 0x8000000 for negative and 0x7fffffff for positive. // So for unrepresentable positive values, xor with 0xffffffff to turn 0x80000000 into 0x7fffffff. - if (addr) { + if (addr.IsValid()) { // xMUL.PS(Fs, ptr128[addr]); armAsm->Fmul(Fs.V4S(), Fs.V4S(), armLoadPtrV(addr).V4S()); } // xMOVAPS(t1, Fs); armAsm->Mov(t1.Q(), Fs.Q()); // xPCMP.GTD(t1, ptr128[mVUglob.I32MAXF]); - armAsm->Cmgt(t1.V4S(), t1.V4S(), armLoadPtrV(mVUglob.I32MAXF).V4S()); + armAsm->Cmgt(t1.V4S(), t1.V4S(), armLoadPtrV(PTR_CPU(mVUglob.I32MAXF)).V4S()); // xCVTTPS2DQ(Fs, Fs); armAsm->Fcvtzs(Fs.V4S(), Fs.V4S()); // xPXOR(Fs, t1); @@ -563,7 +564,8 @@ static void mVU_FTOIx(mP, const float* addr, microOpcode opEnum) } // ITOF0/ITOF4/ITOF12/ITOF15 Opcodes -static void mVU_ITOFx(mP, const float* addr, microOpcode opEnum) +//static void mVU_ITOFx(mP, const float* addr, microOpcode opEnum) +static void mVU_ITOFx(mP, const a64::MemOperand& addr, microOpcode opEnum) { pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); } pass2 @@ -574,7 +576,7 @@ static void mVU_ITOFx(mP, const float* addr, microOpcode opEnum) // xCVTDQ2PS(Fs, Fs); armAsm->Scvtf(Fs.V4S(), Fs.V4S()); - if (addr) { + if (addr.IsValid()) { // xMUL.PS(Fs, ptr128[addr]); armAsm->Fmul(Fs.V4S(), Fs.V4S(), armLoadPtrV(addr).V4S()); } @@ -607,7 +609,7 @@ mVUop(mVU_CLIP) armAsm->Lsl(gprT1, gprT1, 6); // xMOVAPS (t1, ptr128[mVUglob.exponent]); - armAsm->Ldr(t1, armMemOperandPtr(mVUglob.exponent)); + armAsm->Ldr(t1, PTR_CPU(mVUglob.exponent)); // xPAND (t1, Fs); armAsm->And(t1.V16B(), t1.V16B(), Fs.V16B()); // xPXOR (t2, t2); @@ -617,10 +619,10 @@ mVUop(mVU_CLIP) // xPANDN (t1, Fs); // If denormal, set to zero, which can't be greater than any nonnegative denormal in Ft armAsm->Bic(t1.V16B(), Fs.V16B(), t1.V16B()); // xPAND (Ft, ptr128[mVUglob.absclip]); - armAsm->And(Ft.V16B(), Ft.V16B(), armLoadPtrV(mVUglob.absclip).V16B()); + armAsm->And(Ft.V16B(), Ft.V16B(), armLoadPtrV(PTR_CPU(mVUglob.absclip)).V16B()); // xMOVAPS (Fs, ptr128[mVUglob.signbit]); - armAsm->Ldr(Fs, armMemOperandPtr(mVUglob.signbit)); + armAsm->Ldr(Fs, PTR_CPU(mVUglob.signbit)); // xPXOR (Fs, t1); // Negate armAsm->Eor(Fs.V16B(), Fs.V16B(), t1.V16B()); // xPCMP.GTD(t1, Ft); // +w, +z, +y, +x @@ -741,12 +743,12 @@ mVUop(mVU_MINIx) { mVU_FMACa(mVU, recPass, 2, 4, false, opMINIx, 0); } mVUop(mVU_MINIy) { mVU_FMACa(mVU, recPass, 2, 4, false, opMINIy, 0); } mVUop(mVU_MINIz) { mVU_FMACa(mVU, recPass, 2, 4, false, opMINIz, 0); } mVUop(mVU_MINIw) { mVU_FMACa(mVU, recPass, 2, 4, false, opMINIw, 0); } -mVUop(mVU_FTOI0) { mVU_FTOIx(mX, NULL, opFTOI0); } -mVUop(mVU_FTOI4) { mVU_FTOIx(mX, mVUglob.FTOI_4, opFTOI4); } -mVUop(mVU_FTOI12) { mVU_FTOIx(mX, mVUglob.FTOI_12, opFTOI12); } -mVUop(mVU_FTOI15) { mVU_FTOIx(mX, mVUglob.FTOI_15, opFTOI15); } -mVUop(mVU_ITOF0) { mVU_ITOFx(mX, NULL, opITOF0); } -mVUop(mVU_ITOF4) { mVU_ITOFx(mX, mVUglob.ITOF_4, opITOF4); } -mVUop(mVU_ITOF12) { mVU_ITOFx(mX, mVUglob.ITOF_12, opITOF12); } -mVUop(mVU_ITOF15) { mVU_ITOFx(mX, mVUglob.ITOF_15, opITOF15); } +mVUop(mVU_FTOI0) { mVU_FTOIx(mX, a64::MemOperand(), opFTOI0); } +mVUop(mVU_FTOI4) { mVU_FTOIx(mX, PTR_CPU(mVUglob.FTOI_4), opFTOI4); } +mVUop(mVU_FTOI12) { mVU_FTOIx(mX, PTR_CPU(mVUglob.FTOI_12), opFTOI12); } +mVUop(mVU_FTOI15) { mVU_FTOIx(mX, PTR_CPU(mVUglob.FTOI_15), opFTOI15); } +mVUop(mVU_ITOF0) { mVU_ITOFx(mX, a64::MemOperand(), opITOF0); } +mVUop(mVU_ITOF4) { mVU_ITOFx(mX, PTR_CPU(mVUglob.ITOF_4), opITOF4); } +mVUop(mVU_ITOF12) { mVU_ITOFx(mX, PTR_CPU(mVUglob.ITOF_12), opITOF12); } +mVUop(mVU_ITOF15) { mVU_ITOFx(mX, PTR_CPU(mVUglob.ITOF_15), opITOF15); } mVUop(mVU_NOP) { pass2 { mVU.profiler.EmitOp(opNOP); } pass3 { mVUlog("NOP"); } } From 990404c7c4202fcd9ad619ce6b7f825c5f48d250 Mon Sep 17 00:00:00 2001 From: k2154 Date: Sat, 16 Aug 2025 08:02:11 +0900 Subject: [PATCH 04/12] Android project - Add mVU_SSE4 structure to VUDef.h header --- app/src/main/cpp/pcsx2/R5900.cpp | 4 + app/src/main/cpp/pcsx2/VUDef.h | 72 ++++++++ app/src/main/cpp/pcsx2/cpuRegistersPack.h | 3 + app/src/main/cpp/pcsx2/x86/iFPU.cpp | 72 ++++---- app/src/main/cpp/pcsx2/x86/iFPUd.cpp | 174 +++++++++--------- .../cpp/pcsx2/x86/ix86-32/iR5900LoadStore.cpp | 8 +- app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl | 20 +- app/src/main/cpp/pcsx2/x86/microVU_Lower.inl | 4 +- app/src/main/cpp/pcsx2/x86/microVU_Upper.inl | 16 +- 9 files changed, 226 insertions(+), 147 deletions(-) diff --git a/app/src/main/cpp/pcsx2/R5900.cpp b/app/src/main/cpp/pcsx2/R5900.cpp index 71d0671..633ed36 100644 --- a/app/src/main/cpp/pcsx2/R5900.cpp +++ b/app/src/main/cpp/pcsx2/R5900.cpp @@ -58,6 +58,10 @@ uptr g_argPtrs[kMaxArgs]; void cpuReset() { + //// cpuRegistersPack -> VIFregisters + g_cpuRegistersPack.vifRegs[0] = vif0Regs; + g_cpuRegistersPack.vifRegs[1] = vif1Regs; + //// std::memset(&cpuRegs, 0, sizeof(cpuRegs)); std::memset(&fpuRegs, 0, sizeof(fpuRegs)); std::memset(&tlb, 0, sizeof(tlb)); diff --git a/app/src/main/cpp/pcsx2/VUDef.h b/app/src/main/cpp/pcsx2/VUDef.h index 17e75fb..763f3ce 100644 --- a/app/src/main/cpp/pcsx2/VUDef.h +++ b/app/src/main/cpp/pcsx2/VUDef.h @@ -208,4 +208,76 @@ struct mVU_Globals #undef __four }; +#define SINGLE(sign, exp, mant) (((u32)(sign) << 31) | ((u32)(exp) << 23) | (u32)(mant)) +#define DOUBLE(sign, exp, mant) (((sign##ULL) << 63) | ((exp##ULL) << 52) | (mant##ULL)) + +struct FPUd_Globals +{ + u32 neg[4], pos[4]; + + u32 pos_inf[4], neg_inf[4], + one_exp[4]; + + u64 dbl_one_exp[2]; + + u64 dbl_cvt_overflow, // needs special code if above or equal + dbl_ps2_overflow, // overflow & clamp if above or equal + dbl_underflow; // underflow if below + + u64 padding; + + u64 dbl_s_pos[2]; + //u64 dlb_s_neg[2]; +}; + +struct mVU_SSE4 +{ + u32 sse4_minvals[2][4] = { + {0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff}, //1000 + {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}, //1111 + }; + u32 sse4_maxvals[2][4] = { + {0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1000 + {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111 + }; + //// + u32 sse4_compvals[2][4] = { + {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111 + {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1111 + }; + //// + u32 s_neg[4] = {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}; + u32 s_pos[4] = {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff}; + //// + u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}; + u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}; + //// + FPUd_Globals s_const = + { + {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}, + {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff}, + + {SINGLE(0, 0xff, 0), 0, 0, 0}, + {SINGLE(1, 0xff, 0), 0, 0, 0}, + {SINGLE(0, 1, 0), 0, 0, 0}, + + {DOUBLE(0, 1, 0), 0}, + + DOUBLE(0, 1151, 0), // cvt_overflow + DOUBLE(0, 1152, 0), // ps2_overflow + DOUBLE(0, 897, 0), // underflow + + 0, // Padding!! + + {0x7fffffffffffffffULL, 0}, + //{0x8000000000000000ULL, 0}, + }; + //// + u32 minmax_mask[8] = + { + 0xffffffff, 0x80000000, 0, 0, + 0, 0x40000000, 0, 0, + }; +}; + #endif //PCSX2_VUDEF_H diff --git a/app/src/main/cpp/pcsx2/cpuRegistersPack.h b/app/src/main/cpp/pcsx2/cpuRegistersPack.h index 5d3ffa6..95675c5 100644 --- a/app/src/main/cpp/pcsx2/cpuRegistersPack.h +++ b/app/src/main/cpp/pcsx2/cpuRegistersPack.h @@ -15,6 +15,8 @@ struct cpuRegistersPack alignas(16) fpuRegisters fpuRegs{}; alignas(16) psxRegisters psxRegs{}; alignas(16) VURegs vuRegs[2]; + alignas(16) VIFregisters vifRegs[2]; + alignas(16) mVU_SSE4 mVUss4; alignas(32) mVU_Globals mVUglob; }; alignas(32) extern cpuRegistersPack g_cpuRegistersPack; @@ -24,6 +26,7 @@ static fpuRegisters& fpuRegs = g_cpuRegistersPack.fpuRegs; static psxRegisters& psxRegs = g_cpuRegistersPack.psxRegs; static VURegs& VU0 = g_cpuRegistersPack.vuRegs[0]; static VURegs& VU1 = g_cpuRegistersPack.vuRegs[1]; +static mVU_SSE4& mVUClamp = g_cpuRegistersPack.mVUss4; static mVU_Globals& mVUglob = g_cpuRegistersPack.mVUglob; #endif //PCSX2_CPUREGISTERSPACK_H diff --git a/app/src/main/cpp/pcsx2/x86/iFPU.cpp b/app/src/main/cpp/pcsx2/x86/iFPU.cpp index 93702e4..686d22c 100644 --- a/app/src/main/cpp/pcsx2/x86/iFPU.cpp +++ b/app/src/main/cpp/pcsx2/x86/iFPU.cpp @@ -10,8 +10,8 @@ using namespace x86Emitter; #endif -alignas(16) const u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}; -alignas(16) const u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}; +//alignas(16) const u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}; +//alignas(16) const u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}; //------------------------------------------------------------------ namespace R5900 { @@ -67,8 +67,8 @@ namespace DOUBLE // Add/Sub opcodes produce the same results as the ps2 #define FPU_CORRECT_ADD_SUB 1 -alignas(16) static const u32 s_neg[4] = {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}; -alignas(16) static const u32 s_pos[4] = {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff}; +//alignas(16) static const u32 s_neg[4] = {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}; +//alignas(16) static const u32 s_pos[4] = {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff}; #define REC_FPUBRANCH(f) \ void f(); \ @@ -382,9 +382,9 @@ __fi void fpuFloat3(int regd) // +NaN -> +fMax, -NaN -> -fMax, +Inf -> +fMax, -I auto regQ = a64::QRegister(regd); // xPMIN.SD(xRegisterSSE(regd), ptr128[&g_maxvals[0]]); - armAsm->Smin(regQ.V4S(), regQ.V4S(), armLoadPtrV(&g_maxvals[0]).V4S()); + armAsm->Smin(regQ.V4S(), regQ.V4S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).V4S()); // xPMIN.UD(xRegisterSSE(regd), ptr128[&g_minvals[0]]); - armAsm->Umin(regQ.V4S(), regQ.V4S(), armLoadPtrV(&g_minvals[0]).V4S()); + armAsm->Umin(regQ.V4S(), regQ.V4S(), armLoadPtrV(PTR_CPU(mVUss4.g_minvals[0])).V4S()); } __fi void fpuFloat(int regd) // +/-NaN -> +fMax, +Inf -> +fMax, -Inf -> -fMax @@ -394,9 +394,9 @@ __fi void fpuFloat(int regd) // +/-NaN -> +fMax, +Inf -> +fMax, -Inf -> -fMax auto regQ = a64::QRegister(regd); // xMIN.SS(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // MIN() must be before MAX()! So that NaN's become +Maximum - armAsm->Fminnm(regQ.S(), regQ.S(), armLoadPtrV(&g_maxvals[0]).S()); + armAsm->Fminnm(regQ.S(), regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S()); // xMAX.SS(xRegisterSSE(regd), ptr[&g_minvals[0]]); - armAsm->Fmaxnm(regQ.S(), regQ.S(), armLoadPtrV(&g_minvals[0]).S()); + armAsm->Fmaxnm(regQ.S(), regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.g_minvals[0])).S()); } } @@ -434,12 +434,12 @@ void recABS_S_xmm(int info) } // xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_pos[0]]); - armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_pos[0]).V16B()); + armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B()); //xAND(ptr32[&fpuRegs.fprc[31]], ~(FPUflagO|FPUflagU)); // Clear O and U flags if (CHECK_FPU_OVERFLOW) { // Only need to do positive clamp, since EEREC_D is positive // xMIN.SS(xRegisterSSE(EEREC_D), ptr[&g_maxvals[0]]); - armAsm->Fminnm(regED.S(), regED.S(), armLoadPtrV(&g_maxvals[0]).S()); + armAsm->Fminnm(regED.S(), regED.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S()); } } @@ -529,7 +529,7 @@ void FPU_ADD_SUB(int regd, int regt, int issub) // xMOVAPS(xRegisterSSE(xmmtemp), xRegisterSSE(regt)); armAsm->Mov(regQTemp, regT); // xAND.PS(xRegisterSSE(xmmtemp), ptr[s_neg]); - armAsm->And(regQTemp.V16B(), regQTemp.V16B(), armLoadPtrV(s_neg).V16B()); + armAsm->And(regQTemp.V16B(), regQTemp.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg)).V16B()); if (issub) { // xSUB.SS(xRegisterSSE(regd), xRegisterSSE(xmmtemp)); armAsm->Fsub(regD.S(), regD.S(), regQTemp.S()); @@ -569,7 +569,7 @@ void FPU_ADD_SUB(int regd, int regt, int issub) armBind(&j8Ptr3); //diff = -255 .. -25, expd < expt // xAND.PS(xRegisterSSE(regd), ptr[s_neg]); - armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(s_neg).V16B()); + armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg)).V16B()); if (issub) { // xSUB.SS(xRegisterSSE(regd), xRegisterSSE(regt)); armAsm->Fsub(regD.S(), regD.S(), regT.S()); @@ -1340,9 +1340,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags // xMOVMSKPS(eax, xRegisterSSE(t1reg)); armMOVMSKPS(EAX, regT1); // xAND(eax, 1); //Check sign (if regt == zero, sign will be set) - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // ajmp32 = JZ32(0); //Skip if not set - armAsm->B(&ajmp32, a64::Condition::eq); + armAsm->Cbz(EAX, &ajmp32); /*--- Check for 0/0 ---*/ // xXOR.PS(xRegisterSSE(t1reg), xRegisterSSE(t1reg)); @@ -1352,9 +1352,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags // xMOVMSKPS(eax, xRegisterSSE(t1reg)); armMOVMSKPS(EAX, regT1); // xAND(eax, 1); //Check sign (if regd == zero, sign will be set) - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // pjmp1 = JZ8(0); //Skip if not set - armAsm->B(&pjmp1, a64::Condition::eq); + armAsm->Cbz(EAX, &pjmp1); // xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags ( 0/0 ) armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI); // pjmp2 = JMP8(0); @@ -1370,9 +1370,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags // xXOR.PS(xRegisterSSE(regd), xRegisterSSE(regt)); // Make regd Positive or Negative armAsm->Eor(regD.V16B(), regD.V16B(), regT.V16B()); // xAND.PS(xRegisterSSE(regd), ptr[&s_neg[0]]); // Get the sign bit - armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(&s_neg[0]).V16B()); + armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg[0])).V16B()); // xOR.PS(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // regd = +/- Maximum - armAsm->Orr(regD.V16B(), regD.V16B(), armLoadPtrV(&g_maxvals[0]).V16B()); + armAsm->Orr(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).V16B()); //xMOVSSZX(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // bjmp32 = JMP32(0); armAsm->B(&bjmp32); @@ -2087,7 +2087,7 @@ void recNEG_S_xmm(int info) //xAND(ptr32[&fpuRegs.fprc[31]], ~(FPUflagO|FPUflagU)); // Clear O and U flags // xXOR.PS(xRegisterSSE(EEREC_D), ptr[&s_neg[0]]); - armAsm->Eor(regED.V16B(), regED.V16B(), armLoadPtrV(&s_neg[0]).V16B()); + armAsm->Eor(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg[0])).V16B()); // Always preserve sign. Using float clamping here would result in // +inf to become +fMax instead of -fMax, which is definitely wrong. @@ -2235,25 +2235,25 @@ void recSQRT_S_xmm(int info) // xMOVMSKPS(eax, xRegisterSSE(EEREC_D)); armMOVMSKPS(EAX, regED); // xAND(eax, 1); //Check sign - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // u8* pjmp = JZ8(0); //Skip if none are a64::Label pjmp; - armAsm->B(&pjmp, a64::Condition::eq); + armAsm->Cbz(EAX, &pjmp); // xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI); // xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_pos[0]]); // Make EEREC_D Positive - armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_pos[0]).V16B()); + armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B()); // x86SetJ8(pjmp); armBind(&pjmp); } else { // xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_pos[0]]); // Make EEREC_D Positive - armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_pos[0]).V16B()); + armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B()); } if (CHECK_FPU_OVERFLOW) { // Only need to do positive clamp, since EEREC_D is positive // xMIN.SS(xRegisterSSE(EEREC_D), ptr[&g_maxvals[0]]); - armAsm->Fminnm(regED.S(), regED.S(), armLoadPtrV(&g_maxvals[0]).S()); + armAsm->Fminnm(regED.S(), regED.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S()); } // xSQRT.SS(xRegisterSSE(EEREC_D), xRegisterSSE(EEREC_D)); armAsm->Fsqrt(regED.S(), regED.S()); @@ -2294,13 +2294,13 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re // xMOVMSKPS(eax, xRegisterSSE(t0reg)); armMOVMSKPS(EAX, regT0); // xAND(eax, 1); //Check sign - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // pjmp2 = JZ8(0); //Skip if not set - armAsm->B(&pjmp2, a64::Condition::eq); + armAsm->Cbz(EAX, &pjmp2); // xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI); // xAND.PS(xRegisterSSE(t0reg), ptr[&s_pos[0]]); // Make t0reg Positive - armAsm->And(regT0.V16B(), regT0.V16B(), armLoadPtrV(&s_pos[0]).V16B()); // Make t0reg Positive + armAsm->And(regT0.V16B(), regT0.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B()); // Make t0reg Positive // x86SetJ8(pjmp2); armBind(&pjmp2); @@ -2312,9 +2312,9 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re // xMOVMSKPS(eax, xRegisterSSE(t1reg)); armMOVMSKPS(EAX, a64::QRegister(t1reg)); // xAND(eax, 1); //Check sign (if t0reg == zero, sign will be set) - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // pjmp1 = JZ8(0); //Skip if not set - armAsm->B(&pjmp1, a64::Condition::eq); + armAsm->Cbz(EAX, &pjmp1); /*--- Check for 0/0 ---*/ // xXOR.PS(xRegisterSSE(t1reg), xRegisterSSE(t1reg)); armAsm->Eor(a64::QRegister(t1reg).V16B(), a64::QRegister(t1reg).V16B(), a64::QRegister(t1reg).V16B()); @@ -2323,9 +2323,9 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re // xMOVMSKPS(eax, xRegisterSSE(t1reg)); armMOVMSKPS(EAX, a64::QRegister(t1reg)); // xAND(eax, 1); //Check sign (if regd == zero, sign will be set) - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // qjmp1 = JZ8(0); //Skip if not set - armAsm->B(&qjmp1, a64::Condition::eq); + armAsm->Cbz(EAX, &qjmp1); // xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags ( 0/0 ) armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI); // qjmp2 = JMP8(0); @@ -2339,9 +2339,9 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re /*--- Make regd +/- Maximum ---*/ // xAND.PS(xRegisterSSE(regd), ptr[&s_neg[0]]); // Get the sign bit - armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(&s_neg[0]).V16B()); + armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_neg[0])).V16B()); // xOR.PS(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // regd = +/- Maximum - armAsm->Orr(regD.V16B(), regD.V16B(), armLoadPtrV(&g_maxvals[0]).V16B()); + armAsm->Orr(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).V16B()); // pjmp32 = JMP32(0); armAsm->B(&pjmp32); // x86SetJ8(pjmp1); @@ -2350,7 +2350,7 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re if (CHECK_FPU_EXTRA_OVERFLOW) { // xMIN.SS(xRegisterSSE(t0reg), ptr[&g_maxvals[0]]); // Only need to do positive clamp, since t0reg is positive - armAsm->Fminnm(regT0.S(), regT0.S(), armLoadPtrV(&g_maxvals[0]).S()); + armAsm->Fminnm(regT0.S(), regT0.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S()); fpuFloat2(regd); } @@ -2372,11 +2372,11 @@ void recRSQRThelper2(int regd, int t0reg) // Preforms the RSQRT function when re auto regT0 = a64::QRegister(t0reg); // xAND.PS(xRegisterSSE(t0reg), ptr[&s_pos[0]]); // Make t0reg Positive - armAsm->And(regT0.V16B(), regT0.V16B(), armLoadPtrV(&s_pos[0]).V16B()); + armAsm->And(regT0.V16B(), regT0.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_pos[0])).V16B()); if (CHECK_FPU_EXTRA_OVERFLOW) { // xMIN.SS(xRegisterSSE(t0reg), ptr[&g_maxvals[0]]); // Only need to do positive clamp, since t0reg is positive - armAsm->Fminnm(regT0.S(), regT0.S(), armLoadPtrV(&g_maxvals[0]).S()); + armAsm->Fminnm(regT0.S(), regT0.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S()); fpuFloat2(regd); } // xSQRT.SS(xRegisterSSE(t0reg), xRegisterSSE(t0reg)); diff --git a/app/src/main/cpp/pcsx2/x86/iFPUd.cpp b/app/src/main/cpp/pcsx2/x86/iFPUd.cpp index 7915130..da32857 100644 --- a/app/src/main/cpp/pcsx2/x86/iFPUd.cpp +++ b/app/src/main/cpp/pcsx2/x86/iFPUd.cpp @@ -80,48 +80,48 @@ namespace DOUBLE { // PS2 -> DOUBLE //------------------------------------------------------------------ -#define SINGLE(sign, exp, mant) (((u32)(sign) << 31) | ((u32)(exp) << 23) | (u32)(mant)) -#define DOUBLE(sign, exp, mant) (((sign##ULL) << 63) | ((exp##ULL) << 52) | (mant##ULL)) +//#define SINGLE(sign, exp, mant) (((u32)(sign) << 31) | ((u32)(exp) << 23) | (u32)(mant)) +//#define DOUBLE(sign, exp, mant) (((sign##ULL) << 63) | ((exp##ULL) << 52) | (mant##ULL)) -struct FPUd_Globals -{ - u32 neg[4], pos[4]; +//struct FPUd_Globals +//{ +// u32 neg[4], pos[4]; +// +// u32 pos_inf[4], neg_inf[4], +// one_exp[4]; +// +// u64 dbl_one_exp[2]; +// +// u64 dbl_cvt_overflow, // needs special code if above or equal +// dbl_ps2_overflow, // overflow & clamp if above or equal +// dbl_underflow; // underflow if below +// +// u64 padding; +// +// u64 dbl_s_pos[2]; +// //u64 dlb_s_neg[2]; +//}; - u32 pos_inf[4], neg_inf[4], - one_exp[4]; - - u64 dbl_one_exp[2]; - - u64 dbl_cvt_overflow, // needs special code if above or equal - dbl_ps2_overflow, // overflow & clamp if above or equal - dbl_underflow; // underflow if below - - u64 padding; - - u64 dbl_s_pos[2]; - //u64 dlb_s_neg[2]; -}; - -alignas(32) static const FPUd_Globals s_const = -{ - {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}, - {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff}, - - {SINGLE(0, 0xff, 0), 0, 0, 0}, - {SINGLE(1, 0xff, 0), 0, 0, 0}, - {SINGLE(0, 1, 0), 0, 0, 0}, - - {DOUBLE(0, 1, 0), 0}, - - DOUBLE(0, 1151, 0), // cvt_overflow - DOUBLE(0, 1152, 0), // ps2_overflow - DOUBLE(0, 897, 0), // underflow - - 0, // Padding!! - - {0x7fffffffffffffffULL, 0}, - //{0x8000000000000000ULL, 0}, -}; +//alignas(32) static const FPUd_Globals s_const = +//{ +// {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}, +// {0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff}, +// +// {SINGLE(0, 0xff, 0), 0, 0, 0}, +// {SINGLE(1, 0xff, 0), 0, 0, 0}, +// {SINGLE(0, 1, 0), 0, 0, 0}, +// +// {DOUBLE(0, 1, 0), 0}, +// +// DOUBLE(0, 1151, 0), // cvt_overflow +// DOUBLE(0, 1152, 0), // ps2_overflow +// DOUBLE(0, 897, 0), // underflow +// +// 0, // Padding!! +// +// {0x7fffffffffffffffULL, 0}, +// //{0x8000000000000000ULL, 0}, +//}; // ToDouble : converts single-precision PS2 float to double-precision IEEE float @@ -131,12 +131,12 @@ void ToDouble(int reg) auto regQ = a64::QRegister(reg); // xUCOMI.SS(xRegisterSSE(reg), ptr[s_const.pos_inf]); // Sets ZF if reg is equal or incomparable to pos_inf - armAsm->Fcmp(regQ.S(), armLoadPtrV(s_const.pos_inf).S()); + armAsm->Fcmp(regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos_inf)).S()); // u8* to_complex = JE8(0); // Complex conversion if positive infinity or NaN a64::Label to_complex; armAsm->B(&to_complex, a64::Condition::eq); // xUCOMI.SS(xRegisterSSE(reg), ptr[s_const.neg_inf]); - armAsm->Fcmp(regQ.S(), armLoadPtrV(s_const.neg_inf).S()); + armAsm->Fcmp(regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg_inf)).S()); // u8* to_complex2 = JE8(0); // Complex conversion if negative infinity a64::Label to_complex2; armAsm->B(&to_complex2, a64::Condition::eq); @@ -154,11 +154,11 @@ void ToDouble(int reg) // Special conversion for when IEEE sees the value in reg as an INF/NaN // xPSUB.D(xRegisterSSE(reg), ptr[s_const.one_exp]); // Lower exponent by one - armAsm->Sub(regQ.V4S(), regQ.V4S(), armLoadPtrV(s_const.one_exp).V4S()); + armAsm->Sub(regQ.V4S(), regQ.V4S(), armLoadPtrV(PTR_CPU(mVUss4.s_const.one_exp)).V4S()); // xCVTSS2SD(xRegisterSSE(reg), xRegisterSSE(reg)); armAsm->Fcvt(regQ.V1D(), regQ.S()); // xPADD.Q(xRegisterSSE(reg), ptr[s_const.dbl_one_exp]); // Raise exponent by one - armAsm->Fadd(regQ.V2D(), regQ.V2D(), armLoadPtrV(s_const.dbl_one_exp).V2D()); + armAsm->Fadd(regQ.V2D(), regQ.V2D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_one_exp)).V2D()); // x86SetJ8(end); armBind(&end); @@ -198,16 +198,16 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub) // xMOVAPS(xRegisterSSE(absreg), xRegisterSSE(reg)); armAsm->Mov(regAbs, a64::QRegister(reg)); // xAND.PD(xRegisterSSE(absreg), ptr[&s_const.dbl_s_pos]); - armAsm->And(regAbs.V16B(), regAbs.V16B(), armLoadPtrV(&s_const.dbl_s_pos).V16B()); + armAsm->And(regAbs.V16B(), regAbs.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_s_pos)).V16B()); // xUCOMI.SD(xRegisterSSE(absreg), ptr[&s_const.dbl_cvt_overflow]); - armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(&s_const.dbl_cvt_overflow).V1D()); + armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_cvt_overflow)).V1D()); // u8* to_complex = JAE8(0); a64::Label to_complex; armAsm->B(&to_complex, a64::Condition::cs); // xUCOMI.SD(xRegisterSSE(absreg), ptr[&s_const.dbl_underflow]); - armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(&s_const.dbl_underflow).V1D()); + armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_underflow)).V1D()); // u8* to_underflow = JB8(0); a64::Label to_underflow; armAsm->B(&to_underflow, a64::Condition::cc); @@ -222,17 +222,17 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub) // x86SetJ8(to_complex); armBind(&to_complex); // xUCOMI.SD(xRegisterSSE(absreg), ptr[&s_const.dbl_ps2_overflow]); - armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(&s_const.dbl_ps2_overflow).V1D()); + armAsm->Fcmp(regAbs.V1D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_ps2_overflow)).V1D()); // u8* to_overflow = JAE8(0); a64::Label to_overflow; armAsm->B(&to_overflow, a64::Condition::cs); // xPSUB.Q(xRegisterSSE(reg), ptr[&s_const.dbl_one_exp]); //lower exponent - armAsm->Sub(regQ.V2D(), regQ.V2D(), armLoadPtrV(&s_const.dbl_one_exp).V2D()); + armAsm->Sub(regQ.V2D(), regQ.V2D(), armLoadPtrV(PTR_CPU(mVUss4.s_const.dbl_one_exp)).V2D()); // xCVTSD2SS(xRegisterSSE(reg), xRegisterSSE(reg)); //convert armAsm->Fcvt(regQ.S(), regQ.V1D()); // xPADD.D(xRegisterSSE(reg), ptr[s_const.one_exp]); //raise exponent - armAsm->Add(regQ.V4S(), regQ.V4S(), armLoadPtrV(s_const.one_exp).V4S()); + armAsm->Add(regQ.V4S(), regQ.V4S(), armLoadPtrV(PTR_CPU(mVUss4.s_const.one_exp)).V4S()); // u32* end2 = JMP32(0); a64::Label end2; @@ -243,7 +243,7 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub) // xCVTSD2SS(xRegisterSSE(reg), xRegisterSSE(reg)); armAsm->Fcvt(regQ.S(), regQ.V1D()); // xOR.PS(xRegisterSSE(reg), ptr[&s_const.pos]); //clamp - armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(&s_const.pos).V16B()); + armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos)).V16B()); if (flags && FPU_FLAGS_OVERFLOW) { // xOR(ptr32[&fpuRegs.fprc[31]], (FPUflagO | FPUflagSO)); armOrr(PTR_CPU(fpuRegs.fprc[31]), (FPUflagO | FPUflagSO)); @@ -299,7 +299,7 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub) // xCVTSD2SS(xRegisterSSE(reg), xRegisterSSE(reg)); armAsm->Fcvt(regQ.S(), regQ.V1D()); // xAND.PS(xRegisterSSE(reg), ptr[s_const.neg]); //flush to zero - armAsm->And(regQ.V16B(), regQ.V16B(), armLoadPtrV(s_const.neg).V16B()); + armAsm->And(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg)).V16B()); // x86SetJ32(end); armBind(&end); @@ -326,9 +326,9 @@ void ToPS2FPU(int reg, bool flags, int absreg, bool acc, bool addsub = false) // xCVTSD2SS(xRegisterSSE(reg), xRegisterSSE(reg)); //clamp armAsm->Fcvt(regQ.S(), regQ.V1D()); // xMIN.SS(xRegisterSSE(reg), ptr[&g_maxvals[0]]); - armAsm->Fminnm(regQ.S(), regQ.S(), armLoadPtrV(&g_maxvals[0]).S()); + armAsm->Fminnm(regQ.S(), regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).S()); // xMAX.SS(xRegisterSSE(reg), ptr[&g_minvals[0]]); - armAsm->Fmaxnm(regQ.S(), regQ.S(), armLoadPtrV(&g_minvals[0]).S()); + armAsm->Fmaxnm(regQ.S(), regQ.S(), armLoadPtrV(PTR_CPU(mVUss4.g_minvals[0])).S()); } } @@ -339,14 +339,14 @@ void SetMaxValue(int regd) if (FPU_RESULT) { // xOR.PS(xRegisterSSE(regd), ptr[&s_const.pos[0]]); // set regd to maximum - armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(&s_const.pos[0]).V16B()); + armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B()); } else { // xAND.PS(xRegisterSSE(regd), ptr[&s_const.neg[0]]); // Get the sign bit - armAsm->And(regQ.V16B(), regQ.V16B(), armLoadPtrV(&s_const.neg[0]).V16B()); + armAsm->And(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg[0])).V16B()); // xOR.PS(xRegisterSSE(regd), ptr[&g_maxvals[0]]); // regd = +/- Maximum (CLAMP)! - armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(&g_maxvals[0]).V16B()); + armAsm->Orr(regQ.V16B(), regQ.V16B(), armLoadPtrV(PTR_CPU(mVUss4.g_maxvals[0])).V16B()); } } @@ -410,7 +410,7 @@ void recABS_S_xmm(int info) // xAND.PS(xRegisterSSE(EEREC_D), ptr[s_const.pos]); auto regED = a64::QRegister(EEREC_D); - armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(s_const.pos).V16B()); + armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos)).V16B()); } FPURECOMPILE_CONSTCODE(ABS_S, XMMINFO_WRITED | XMMINFO_READS); @@ -489,7 +489,7 @@ void FPU_ADD_SUB(int tempd, int tempt) //tempd and tempt are overwritten, they a armBind(&j8Ptr0); //diff = 25 .. 255 , expt < expd // xAND.PS(xRegisterSSE(tempt), ptr[s_const.neg]); - armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(s_const.neg).V16B()); + armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg)).V16B()); // j8Ptr[5] = JMP8(0); armAsm->B(&j8Ptr5); @@ -513,7 +513,7 @@ void FPU_ADD_SUB(int tempd, int tempt) //tempd and tempt are overwritten, they a armBind(&j8Ptr3); //diff = -255 .. -25, expd < expt // xAND.PS(xRegisterSSE(tempd), ptr[s_const.neg]); - armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(s_const.neg).V16B()); + armAsm->And(regD.V16B(), regD.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg)).V16B()); // x86SetJ8(j8Ptr[2]); armBind(&j8Ptr2); @@ -765,9 +765,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags // xMOVMSKPS(eax, xRegisterSSE(t1reg)); armMOVMSKPS(EAX, regT1); // xAND(eax, 1); //Check sign (if regt == zero, sign will be set) - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // ajmp32 = JZ32(0); //Skip if not set - armAsm->B(&ajmp32, a64::Condition::eq); + armAsm->Cbz(EAX, &ajmp32); //--- Check for 0/0 --- // xXOR.PS(xRegisterSSE(t1reg), xRegisterSSE(t1reg)); @@ -777,9 +777,9 @@ void recDIVhelper1(int regd, int regt) // Sets flags // xMOVMSKPS(eax, xRegisterSSE(t1reg)); armMOVMSKPS(EAX, regT1); // xAND(eax, 1); //Check sign (if regd == zero, sign will be set) - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // pjmp1 = JZ8(0); //Skip if not set - armAsm->B(&pjmp1, a64::Condition::eq); + armAsm->Cbz(EAX, &pjmp1); // xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags ( 0/0 ) armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI); // pjmp2 = JMP8(0); @@ -912,7 +912,7 @@ void recMaddsub(int info, int regd, int op, bool acc) armBind(&mulovf); if (op == 1) { //sub // xXOR.PS(xRegisterSSE(sreg), ptr[s_const.neg]); - armAsm->Eor(regS.V16B(), regS.V16B(), armLoadPtrV(s_const.neg).V16B()); + armAsm->Eor(regS.V16B(), regS.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg)).V16B()); } // xMOVAPS(xRegisterSSE(treg), xRegisterSSE(sreg)); //fall through below armAsm->Mov(regT, regS); @@ -978,11 +978,11 @@ FPURECOMPILE_CONSTCODE(MADDA_S, XMMINFO_WRITEACC | XMMINFO_READACC | XMMINFO_REA // MAX / MIN XMM //------------------------------------------------------------------ -alignas(16) static const u32 minmax_mask[8] = -{ - 0xffffffff, 0x80000000, 0, 0, - 0, 0x40000000, 0, 0, -}; +//alignas(16) static const u32 minmax_mask[8] = +//{ +// 0xffffffff, 0x80000000, 0, 0, +// 0, 0x40000000, 0, 0, +//}; // FPU's MAX/MIN work with all numbers (including "denormals"). Check VU's logical min max for more info. void recMINMAX(int info, bool ismin) { @@ -997,15 +997,15 @@ void recMINMAX(int info, bool ismin) // xPSHUF.D(xRegisterSSE(sreg), xRegisterSSE(sreg), 0x00); armPSHUFD(regS, regS, 0x00); // xPAND(xRegisterSSE(sreg), ptr[minmax_mask]); - armAsm->And(regS.V16B(), regS.V16B(), armLoadPtrV(minmax_mask).V16B()); + armAsm->And(regS.V16B(), regS.V16B(), armLoadPtrV(PTR_CPU(mVUss4.minmax_mask)).V16B()); // xPOR(xRegisterSSE(sreg), ptr[&minmax_mask[4]]); - armAsm->Orr(regS.V16B(), regS.V16B(), armLoadPtrV(&minmax_mask[4]).V16B()); + armAsm->Orr(regS.V16B(), regS.V16B(), armLoadPtrV(PTR_CPU(mVUss4.minmax_mask[4])).V16B()); // xPSHUF.D(xRegisterSSE(treg), xRegisterSSE(treg), 0x00); armPSHUFD(regT, regT, 0x00); // xPAND(xRegisterSSE(treg), ptr[minmax_mask]); - armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(minmax_mask).V16B()); + armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.minmax_mask)).V16B()); // xPOR(xRegisterSSE(treg), ptr[&minmax_mask[4]]); - armAsm->Orr(regT.V16B(), regT.V16B(), armLoadPtrV(&minmax_mask[4]).V16B()); + armAsm->Orr(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.minmax_mask[4])).V16B()); if (ismin) { // xMIN.SD(xRegisterSSE(sreg), xRegisterSSE(treg)); armAsm->Fminnm(regS.V1D(), regS.V1D(), regT.V1D()); @@ -1113,7 +1113,7 @@ void recNEG_S_xmm(int info) CLEAR_OU_FLAGS; // xXOR.PS(xRegisterSSE(EEREC_D), ptr[&s_const.neg[0]]); - armAsm->Eor(a64::QRegister(EEREC_D).V16B(), a64::QRegister(EEREC_D).V16B(), armLoadPtrV(&s_const.neg[0]).V16B()); + armAsm->Eor(a64::QRegister(EEREC_D).V16B(), a64::QRegister(EEREC_D).V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.neg[0])).V16B()); } FPURECOMPILE_CONSTCODE(NEG_S, XMMINFO_WRITED | XMMINFO_READS); @@ -1177,21 +1177,21 @@ void recSQRT_S_xmm(int info) // xMOVMSKPS(eax, xRegisterSSE(EEREC_D)); armMOVMSKPS(EAX, regED); // xAND(eax, 1); //Check sign - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // u8* pjmp = JZ8(0); //Skip if none are a64::Label pjmp; - armAsm->B(&pjmp, a64::Condition::eq); + armAsm->Cbz(EAX, &pjmp); // xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI); // xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_const.pos[0]]); // Make EEREC_D Positive - armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_const.pos[0]).V16B()); + armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B()); // x86SetJ8(pjmp); armBind(&pjmp); } else { // xAND.PS(xRegisterSSE(EEREC_D), ptr[&s_const.pos[0]]); // Make EEREC_D Positive - armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(&s_const.pos[0]).V16B()); + armAsm->And(regED.V16B(), regED.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B()); } @@ -1239,13 +1239,13 @@ void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when reg // xMOVMSKPS(eax, xRegisterSSE(regt)); armMOVMSKPS(EAX, regT); // xAND(eax, 1); //Check sign - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // pjmp2 = JZ8(0); //Skip if not set - armAsm->B(&pjmp2, a64::Condition::eq); + armAsm->Cbz(EAX, &pjmp2); // xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI); // xAND.PS(xRegisterSSE(regt), ptr[&s_const.pos[0]]); // Make regt Positive - armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(&s_const.pos[0]).V16B()); + armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B()); // x86SetJ8(pjmp2); armBind(&pjmp2); @@ -1257,9 +1257,9 @@ void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when reg // xMOVMSKPS(eax, xRegisterSSE(t1reg)); armMOVMSKPS(EAX, regT1); // xAND(eax, 1); //Check sign (if regt == zero, sign will be set) - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // pjmp1 = JZ8(0); //Skip if not set - armAsm->B(&pjmp1, a64::Condition::eq); + armAsm->Cbz(EAX, &pjmp1); //--- Check for 0/0 --- // xXOR.PS(xRegisterSSE(t1reg), xRegisterSSE(t1reg)); @@ -1269,9 +1269,9 @@ void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when reg // xMOVMSKPS(eax, xRegisterSSE(t1reg)); armMOVMSKPS(EAX, regT1); // xAND(eax, 1); //Check sign (if regd == zero, sign will be set) - armAsm->Ands(EAX, EAX, 1); + armAsm->And(EAX, EAX, 1); // qjmp1 = JZ8(0); //Skip if not set - armAsm->B(&qjmp1, a64::Condition::eq); + armAsm->Cbz(EAX, &qjmp1); // xOR(ptr32[&fpuRegs.fprc[31]], FPUflagI | FPUflagSI); // Set I and SI flags ( 0/0 ) armOrr(PTR_CPU(fpuRegs.fprc[31]), FPUflagI | FPUflagSI); // qjmp2 = JMP8(0); @@ -1309,7 +1309,7 @@ void recRSQRThelper2(int regd, int regt) // Preforms the RSQRT function when reg auto regT = a64::QRegister(regt); // xAND.PS(xRegisterSSE(regt), ptr[&s_const.pos[0]]); // Make regt Positive - armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(&s_const.pos[0]).V16B()); + armAsm->And(regT.V16B(), regT.V16B(), armLoadPtrV(PTR_CPU(mVUss4.s_const.pos[0])).V16B()); ToDouble(regt); ToDouble(regd); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900LoadStore.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900LoadStore.cpp index f784989..80802b8 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900LoadStore.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900LoadStore.cpp @@ -389,11 +389,11 @@ void recLWR() auto reg32 = a64::WRegister(treg); // xAND(temp, 3); - armAsm->Ands(temp, temp, 3); + armAsm->And(temp, temp, 3); // xForwardJE8 nomask; a64::Label nomask; - armAsm->B(&nomask, a64::Condition::eq); + armAsm->Cbz(temp, &nomask); // xSHL(temp, 3); armAsm->Lsl(temp, temp, 3); // mask off bytes loaded @@ -576,7 +576,7 @@ void recSWR() // xMOV(temp, arg1regd); armAsm->Mov(temp, ECX); // xAND(arg1regd, ~3); - armAsm->And(ECX, ECX, ~3); + armAsm->Ands(ECX, ECX, ~3); // xAND(temp, 3); armAsm->Ands(temp, temp, 3); @@ -1239,7 +1239,7 @@ void recSDR() // xMOV(temp2, arg2reg); armAsm->Mov(temp2, RDX); // xAND(arg1regd, ~0x07); - armAsm->And(ECX, ECX, ~0x07); + armAsm->Ands(ECX, ECX, ~0x07); // xAND(temp1, 0x7); armAsm->Ands(temp1, temp1, 0x7); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl b/app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl index e64176a..44794c5 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Clamp.inl @@ -7,14 +7,14 @@ // Micro VU - Clamp Functions //------------------------------------------------------------------ -alignas(16) const u32 sse4_minvals[2][4] = { - {0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff}, //1000 - {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}, //1111 -}; -alignas(16) const u32 sse4_maxvals[2][4] = { - {0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1000 - {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111 -}; +//alignas(16) const u32 sse4_minvals[2][4] = { +// {0xff7fffff, 0xffffffff, 0xffffffff, 0xffffffff}, //1000 +// {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}, //1111 +//}; +//alignas(16) const u32 sse4_maxvals[2][4] = { +// {0x7f7fffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1000 +// {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111 +//}; // Used for Result Clamping // Note: This function will not preserve NaN values' sign. @@ -55,9 +55,9 @@ void mVUclamp2(microVU& mVU, const xmm& reg, const xmm& regT1in, int xyzw, bool { int i = (xyzw == 1 || xyzw == 2 || xyzw == 4 || xyzw == 8) ? 0 : 1; // xPMIN.SD(reg, ptr128[&sse4_maxvals[i][0]]); - armAsm->Smin(reg.V4S(), reg.V4S(), armLoadPtrV(&sse4_maxvals[i][0]).V4S()); + armAsm->Smin(reg.V4S(), reg.V4S(), armLoadPtrV(PTR_CPU(mVUss4.sse4_maxvals[i][0])).V4S()); // xPMIN.UD(reg, ptr128[&sse4_minvals[i][0]]); - armAsm->Umin(reg.V4S(), reg.V4S(), armLoadPtrV(&sse4_minvals[i][0]).V4S()); + armAsm->Umin(reg.V4S(), reg.V4S(), armLoadPtrV(PTR_CPU(mVUss4.sse4_minvals[i][0])).V4S()); return; } else diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl b/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl index 21aca52..779f47f 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl @@ -2071,7 +2071,7 @@ mVUop(mVU_XTOP) if (mVU.index && THREAD_VU1) { armAsm->Ldrh(regT, PTR_VU1(vifRegs.top)); } else { - armAsm->Ldrh(regT, armMemOperandPtr(&mVU.getVifRegs().top)); + armAsm->Ldrh(regT, PTR_CPU(vifRegs[mVU.index].top)); } mVU.regAlloc->clearNeeded(regT); mVU.profiler.EmitOp(opXTOP); @@ -2095,7 +2095,7 @@ mVUop(mVU_XITOP) if (mVU.index && THREAD_VU1) { armAsm->Ldrh(regT, PTR_VU1(vifRegs.itop)); } else { - armAsm->Ldrh(regT, armMemOperandPtr(&mVU.getVifRegs().itop)); + armAsm->Ldrh(regT, PTR_CPU(vifRegs[mVU.index].itop)); } // xAND(regT, isVU1 ? 0x3ff : 0xff); armAsm->And(regT, regT, isVU1 ? 0x3ff : 0xff); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Upper.inl b/app/src/main/cpp/pcsx2/x86/microVU_Upper.inl index e6c492f..1f60ed4 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Upper.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Upper.inl @@ -18,10 +18,10 @@ } while (0) -alignas(16) const u32 sse4_compvals[2][4] = { - {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111 - {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1111 -}; +//alignas(16) const u32 sse4_compvals[2][4] = { +// {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}, //1111 +// {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}, //1111 +//}; const std::array flipMask{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; @@ -96,16 +96,16 @@ static void mVUupdateFlags(mV, const xmm& reg, const xmm& regT1in = a64::NoVReg, // xMOVAPS(regT1, regT2); armAsm->Mov(regT1.Q(), regT2.Q()); // xAND.PS(regT1, ptr128[&sse4_compvals[1][0]]); // Remove sign flags (we don't care) - armAsm->And(regT1.V16B(), regT1.V16B(), armLoadPtrV(&sse4_compvals[1][0]).V16B()); + armAsm->And(regT1.V16B(), regT1.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sse4_compvals[1][0])).V16B()); // xCMPNLT.PS(regT1, ptr128[&sse4_compvals[0][0]]); // Compare if T1 == FLT_MAX - armAsm->Fcmge(regT1.V4S(), regT1.V4S(), armLoadPtrV(&sse4_compvals[0][0]).V4S()); + armAsm->Fcmeq(regT1.V4S(), regT1.V4S(), armLoadPtrV(PTR_CPU(mVUss4.sse4_compvals[0][0])).V4S()); // xMOVMSKPS(gprT2, regT1); // Grab sign bits for equal results armMOVMSKPS(gprT2, regT1); // xAND(gprT2, AND_XYZW); // Grab "Is FLT_MAX" bits from the previous calculation - armAsm->Ands(gprT2, gprT2, AND_XYZW); + armAsm->And(gprT2, gprT2, AND_XYZW); // xForwardJump32 oJMP(Jcc_Zero); a64::Label oJMP; - armAsm->B(&oJMP, a64::Condition::eq); + armAsm->Cbz(gprT2, &oJMP); // xOR(sReg, 0x820000); armAsm->Orr(sReg, sReg, 0x820000); From 9da187a868cbb6022c209283dc439fd955f944b2 Mon Sep 17 00:00:00 2001 From: k2154 Date: Sat, 16 Aug 2025 08:19:54 +0900 Subject: [PATCH 05/12] Android project - Add mVU_SSE4 structure to VUDef.h header --- app/src/main/cpp/pcsx2/VUDef.h | 18 +++++-- .../main/cpp/pcsx2/x86/microVU_Compile.inl | 2 +- app/src/main/cpp/pcsx2/x86/microVU_Misc.inl | 48 +++++++++---------- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/app/src/main/cpp/pcsx2/VUDef.h b/app/src/main/cpp/pcsx2/VUDef.h index 763f3ce..b1e5f00 100644 --- a/app/src/main/cpp/pcsx2/VUDef.h +++ b/app/src/main/cpp/pcsx2/VUDef.h @@ -230,6 +230,11 @@ struct FPUd_Globals //u64 dlb_s_neg[2]; }; +struct SSEMasks +{ + u32 MIN_MAX_1[4], MIN_MAX_2[4], ADD_SS[4]; +}; + struct mVU_SSE4 { u32 sse4_minvals[2][4] = { @@ -252,6 +257,12 @@ struct mVU_SSE4 u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}; u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}; //// + u32 minmax_mask[8] = + { + 0xffffffff, 0x80000000, 0, 0, + 0, 0x40000000, 0, 0, + }; + //// FPUd_Globals s_const = { {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}, @@ -273,10 +284,11 @@ struct mVU_SSE4 //{0x8000000000000000ULL, 0}, }; //// - u32 minmax_mask[8] = + SSEMasks sseMasks = { - 0xffffffff, 0x80000000, 0, 0, - 0, 0x40000000, 0, 0, + {0xffffffff, 0x80000000, 0xffffffff, 0x80000000}, + {0x00000000, 0x40000000, 0x00000000, 0x40000000}, + {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}, }; }; diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl b/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl index 65cf31b..2d3a3f8 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl @@ -515,7 +515,7 @@ void mVUtestCycles(microVU& mVU, microFlagCycles& mFC) armAsm->B(&skip, a64::Condition::pl); // xLoadFarAddr(rax, &mVUpBlock->pState); - armMoveAddressToReg(RAX, &mVUpBlock->pState); + armAsm->Ldr(RAX, PTR_MBLOCK(pState)); // xCALL((void*)mVU.copyPLState); armEmitCall(mVU.copyPLState); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl index b821da0..64130d3 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Misc.inl @@ -445,17 +445,17 @@ __fi std::optional mVUoptimizeConstantAddr(mV, u32 srcreg, s32 // Micro VU - Custom SSE Instructions //------------------------------------------------------------------ -struct SSEMasks -{ - u32 MIN_MAX_1[4], MIN_MAX_2[4], ADD_SS[4]; -}; +//struct SSEMasks +//{ +// u32 MIN_MAX_1[4], MIN_MAX_2[4], ADD_SS[4]; +//}; -alignas(16) static const SSEMasks sseMasks = -{ - {0xffffffff, 0x80000000, 0xffffffff, 0x80000000}, - {0x00000000, 0x40000000, 0x00000000, 0x40000000}, - {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}, -}; +//alignas(16) static const SSEMasks sseMasks = +//{ +// {0xffffffff, 0x80000000, 0xffffffff, 0x80000000}, +// {0x00000000, 0x40000000, 0x00000000, 0x40000000}, +// {0x80000000, 0xffffffff, 0xffffffff, 0xffffffff}, +//}; // Warning: Modifies t1 and t2 @@ -470,15 +470,15 @@ void MIN_MAX_PS(microVU& mVU, const xmm& to, const xmm& from, const xmm& t1in, c // xPSHUF.D(t1, to, 0xfa); 1234 => 3344 armPSHUFD(t1, to, 0xfa); // xPAND (t1, ptr128[sseMasks.MIN_MAX_1]); - armAsm->And(t1.V16B(), t1.V16B(), armLoadPtrV(sseMasks.MIN_MAX_1).V16B()); + armAsm->And(t1.V16B(), t1.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_1)).V16B()); // xPOR (t1, ptr128[sseMasks.MIN_MAX_2]); - armAsm->Orr(t1.V16B(), t1.V16B(), armLoadPtrV(sseMasks.MIN_MAX_2).V16B()); + armAsm->Orr(t1.V16B(), t1.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_2)).V16B()); // xPSHUF.D(t2, from, 0xfa); 1234 => 3344 armPSHUFD(t2, from, 0xfa); // xPAND (t2, ptr128[sseMasks.MIN_MAX_1]); - armAsm->And(t2.V16B(), t2.V16B(), armLoadPtrV(sseMasks.MIN_MAX_1).V16B()); + armAsm->And(t2.V16B(), t2.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_1)).V16B()); // xPOR (t2, ptr128[sseMasks.MIN_MAX_2]); - armAsm->Orr(t2.V16B(), t2.V16B(), armLoadPtrV(sseMasks.MIN_MAX_2).V16B()); + armAsm->Orr(t2.V16B(), t2.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_2)).V16B()); // if (min) xMIN.PD(t1, t2); if (min) armAsm->Fminnm(t1.V2D(), t1.V2D(), t2.V2D()); // else xMAX.PD(t1, t2); @@ -488,15 +488,15 @@ void MIN_MAX_PS(microVU& mVU, const xmm& to, const xmm& from, const xmm& t1in, c // xPSHUF.D(t2, from, 0x50); 1234 => 1122 armPSHUFD(t2, from, 0x50); // xPAND (t2, ptr128[sseMasks.MIN_MAX_1]); - armAsm->And(t2.V16B(), t2.V16B(), armLoadPtrV(sseMasks.MIN_MAX_1).V16B()); + armAsm->And(t2.V16B(), t2.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_1)).V16B()); // xPOR (t2, ptr128[sseMasks.MIN_MAX_2]); - armAsm->Orr(t2.V16B(), t2.V16B(), armLoadPtrV(sseMasks.MIN_MAX_2).V16B()); + armAsm->Orr(t2.V16B(), t2.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_2)).V16B()); // xPSHUF.D(to, to, 0x50); 1234 => 1122 armPSHUFD(to, to, 0x50); // xPAND (to, ptr128[sseMasks.MIN_MAX_1]); - armAsm->And(to.V16B(), to.V16B(), armLoadPtrV(sseMasks.MIN_MAX_1).V16B()); + armAsm->And(to.V16B(), to.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_1)).V16B()); // xPOR (to, ptr128[sseMasks.MIN_MAX_2]); - armAsm->Orr(to.V16B(), to.V16B(), armLoadPtrV(sseMasks.MIN_MAX_2).V16B()); + armAsm->Orr(to.V16B(), to.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_2)).V16B()); // if (min) xMIN.PD(to, t2); // else xMAX.PD(to, t2); if (min) armAsm->Fminnm(to.V2D(), to.V2D(), t2.V2D()); @@ -551,9 +551,9 @@ void MIN_MAX_SS(mV, const xmm& to, const xmm& from, const xmm& t1in, bool min) // xSHUF.PS(to, from, 0); armSHUFPS(to, from, 0); // xPAND (to, ptr128[sseMasks.MIN_MAX_1]); - armAsm->And(to.V16B(), to.V16B(), armLoadPtrV(sseMasks.MIN_MAX_1).V16B()); + armAsm->And(to.V16B(), to.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_1)).V16B()); // xPOR (to, ptr128[sseMasks.MIN_MAX_2]); - armAsm->Orr(to.V16B(), to.V16B(), armLoadPtrV(sseMasks.MIN_MAX_2).V16B()); + armAsm->Orr(to.V16B(), to.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.MIN_MAX_2)).V16B()); // xPSHUF.D(t1, to, 0xee); armAsm->Dup(t1.V2D(), to.V2D(), 1); //v3v2v3v2 // if (min) xMIN.PD(to, t1); @@ -602,7 +602,7 @@ void ADD_SS_Single_Guard_Bit(microVU& mVU, const xmm& to, const xmm& from, const // case_pos_big: // xPAND(to, ptr128[sseMasks.ADD_SS]); - armAsm->And(to.V16B(), to.V16B(), armLoadPtrV(sseMasks.ADD_SS).V16B()); + armAsm->And(to.V16B(), to.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.ADD_SS)).V16B()); // xForwardJump8 case_end2; a64::Label case_end2; armAsm->B(&case_end2); @@ -633,7 +633,7 @@ void ADD_SS_Single_Guard_Bit(microVU& mVU, const xmm& to, const xmm& from, const // case_neg_big: // xPAND(from, ptr128[sseMasks.ADD_SS]); - armAsm->And(from.V16B(), from.V16B(), armLoadPtrV(sseMasks.ADD_SS).V16B()); + armAsm->And(from.V16B(), from.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.ADD_SS)).V16B()); // xForwardJump8 case_end4; a64::Label case_end4; armAsm->B(&case_end4); @@ -698,7 +698,7 @@ void ADD_SS_TriAceHack(microVU& mVU, const xmm& to, const xmm& from) // case_pos_big: // xPAND(to, ptr128[sseMasks.ADD_SS]); - armAsm->And(to.V16B(), to.V16B(), armLoadPtrV(sseMasks.ADD_SS).V16B()); + armAsm->And(to.V16B(), to.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.ADD_SS)).V16B()); // xForwardJump8 case_end2; a64::Label case_end2; armAsm->B(&case_end2); @@ -706,7 +706,7 @@ void ADD_SS_TriAceHack(microVU& mVU, const xmm& to, const xmm& from) // case_neg_big.SetTarget(); armBind(&case_neg_big); // xPAND(from, ptr128[sseMasks.ADD_SS]); - armAsm->And(from.V16B(), from.V16B(), armLoadPtrV(sseMasks.ADD_SS).V16B()); + armAsm->And(from.V16B(), from.V16B(), armLoadPtrV(PTR_CPU(mVUss4.sseMasks.ADD_SS)).V16B()); // case_end1.SetTarget(); armBind(&case_end1); From 71f36c6ea318b143433d3a536e1664b0c473eb42 Mon Sep 17 00:00:00 2001 From: k2154 Date: Mon, 18 Aug 2025 07:26:56 +0900 Subject: [PATCH 06/12] Android project - Add vtlbDef.h --- app/src/main/cpp/common/arm64/AsmHelpers.h | 4 +- app/src/main/cpp/pcsx2/MTVU.cpp | 2 +- app/src/main/cpp/pcsx2/MTVU.h | 2 +- app/src/main/cpp/pcsx2/R5900.cpp | 2 +- app/src/main/cpp/pcsx2/cpuRegistersPack.h | 8 +- app/src/main/cpp/pcsx2/vtlb.cpp | 2 +- app/src/main/cpp/pcsx2/vtlb.h | 138 +---------------- app/src/main/cpp/pcsx2/vtlbDef.h | 145 ++++++++++++++++++ app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp | 2 +- .../main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp | 139 +++++++++++------ app/src/main/cpp/pcsx2/x86/microVU.cpp | 3 +- app/src/main/cpp/pcsx2/x86/microVU.h | 3 +- app/src/main/cpp/pcsx2/x86/microVU_Branch.inl | 26 ++-- .../main/cpp/pcsx2/x86/microVU_Compile.inl | 6 +- .../main/cpp/pcsx2/x86/microVU_Execute.inl | 2 - app/src/main/cpp/pcsx2/x86/microVU_Lower.inl | 10 +- 16 files changed, 274 insertions(+), 220 deletions(-) create mode 100644 app/src/main/cpp/pcsx2/vtlbDef.h diff --git a/app/src/main/cpp/common/arm64/AsmHelpers.h b/app/src/main/cpp/common/arm64/AsmHelpers.h index 960f624..d027345 100644 --- a/app/src/main/cpp/common/arm64/AsmHelpers.h +++ b/app/src/main/cpp/common/arm64/AsmHelpers.h @@ -57,7 +57,6 @@ namespace a64 = vixl::aarch64; // fastmem #define RFASTMEMBASE a64::x25 -#define PTR_MBLOCK(field) a64::MemOperand(RFASTMEMBASE, offsetof(microBlock, field)) #define RSTATE_x26 a64::x26 @@ -70,9 +69,8 @@ namespace a64 = vixl::aarch64; #define RSTATE_MVU a64::x28 #define PTR_MVU(field) a64::MemOperand(RSTATE_MVU, offsetof(vuRegistersPack, field)) -// iopMem->Main, vu1Thread +// iopMem->Main #define RSTATE_x29 a64::x29 -#define PTR_VU1(field) a64::MemOperand(RSTATE_x29, offsetof(VU_Thread, field)) static inline s64 GetPCDisplacement(const void* current, const void* target) { diff --git a/app/src/main/cpp/pcsx2/MTVU.cpp b/app/src/main/cpp/pcsx2/MTVU.cpp index 907b1c6..8c77a60 100644 --- a/app/src/main/cpp/pcsx2/MTVU.cpp +++ b/app/src/main/cpp/pcsx2/MTVU.cpp @@ -9,7 +9,7 @@ #include -VU_Thread vu1Thread; +//VU_Thread vu1Thread; #define MTVU_ALWAYS_KICK 0 #define MTVU_SYNC_MODE 0 diff --git a/app/src/main/cpp/pcsx2/MTVU.h b/app/src/main/cpp/pcsx2/MTVU.h index 7625c47..f007fb7 100644 --- a/app/src/main/cpp/pcsx2/MTVU.h +++ b/app/src/main/cpp/pcsx2/MTVU.h @@ -120,4 +120,4 @@ private: u32 Get_vuCycles(); }; -extern VU_Thread vu1Thread; +extern VU_Thread& vu1Thread; diff --git a/app/src/main/cpp/pcsx2/R5900.cpp b/app/src/main/cpp/pcsx2/R5900.cpp index 633ed36..0d7fd7d 100644 --- a/app/src/main/cpp/pcsx2/R5900.cpp +++ b/app/src/main/cpp/pcsx2/R5900.cpp @@ -34,7 +34,7 @@ using namespace R5900; // for R5900 disasm tools s32 EEsCycle; // used to sync the IOP to the EE u32 EEoCycle; -alignas(32) cpuRegistersPack g_cpuRegistersPack; +alignas(64) cpuRegistersPack g_cpuRegistersPack; alignas(16) tlbs tlb[48]; cachedTlbs_t cachedTlbs; diff --git a/app/src/main/cpp/pcsx2/cpuRegistersPack.h b/app/src/main/cpp/pcsx2/cpuRegistersPack.h index 95675c5..d4450a3 100644 --- a/app/src/main/cpp/pcsx2/cpuRegistersPack.h +++ b/app/src/main/cpp/pcsx2/cpuRegistersPack.h @@ -8,25 +8,25 @@ #include "R5900Def.h" #include "R3000ADef.h" #include "VUDef.h" +#include "vtlbDef.h" struct cpuRegistersPack { alignas(16) cpuRegisters cpuRegs{}; alignas(16) fpuRegisters fpuRegs{}; alignas(16) psxRegisters psxRegs{}; + alignas(16) VIFregisters vifRegs[2]{}; alignas(16) VURegs vuRegs[2]; - alignas(16) VIFregisters vifRegs[2]; alignas(16) mVU_SSE4 mVUss4; alignas(32) mVU_Globals mVUglob; + alignas(64) vtlb_private::MapData vtlbdata; }; -alignas(32) extern cpuRegistersPack g_cpuRegistersPack; +alignas(64) extern cpuRegistersPack g_cpuRegistersPack; //// static cpuRegisters& cpuRegs = g_cpuRegistersPack.cpuRegs; static fpuRegisters& fpuRegs = g_cpuRegistersPack.fpuRegs; static psxRegisters& psxRegs = g_cpuRegistersPack.psxRegs; static VURegs& VU0 = g_cpuRegistersPack.vuRegs[0]; static VURegs& VU1 = g_cpuRegistersPack.vuRegs[1]; -static mVU_SSE4& mVUClamp = g_cpuRegistersPack.mVUss4; -static mVU_Globals& mVUglob = g_cpuRegistersPack.mVUglob; #endif //PCSX2_CPUREGISTERSPACK_H diff --git a/app/src/main/cpp/pcsx2/vtlb.cpp b/app/src/main/cpp/pcsx2/vtlb.cpp index d719f2e..ee2c044 100644 --- a/app/src/main/cpp/pcsx2/vtlb.cpp +++ b/app/src/main/cpp/pcsx2/vtlb.cpp @@ -44,7 +44,7 @@ using namespace vtlb_private; namespace vtlb_private { - alignas(64) MapData vtlbdata; + MapData& vtlbdata = g_cpuRegistersPack.vtlbdata; } // namespace vtlb_private static vtlbHandler vtlbHandlerCount = 0; diff --git a/app/src/main/cpp/pcsx2/vtlb.h b/app/src/main/cpp/pcsx2/vtlb.h index bf069c1..ee6cd4e 100644 --- a/app/src/main/cpp/pcsx2/vtlb.h +++ b/app/src/main/cpp/pcsx2/vtlb.h @@ -3,42 +3,11 @@ #pragma once -#include "MemoryTypes.h" - +#include "vtlbDef.h" #include "common/HostSys.h" -#include "common/SingleRegisterTypes.h" static const uptr VTLB_AllocUpperBounds = _1gb * 2; -// Specialized function pointers for each read type -typedef mem8_t vtlbMemR8FP(u32 addr); -typedef mem16_t vtlbMemR16FP(u32 addr); -typedef mem32_t vtlbMemR32FP(u32 addr); -typedef mem64_t vtlbMemR64FP(u32 addr); -typedef RETURNS_R128 vtlbMemR128FP(u32 addr); - -// Specialized function pointers for each write type -typedef void vtlbMemW8FP(u32 addr,mem8_t data); -typedef void vtlbMemW16FP(u32 addr,mem16_t data); -typedef void vtlbMemW32FP(u32 addr,mem32_t data); -typedef void vtlbMemW64FP(u32 addr,mem64_t data); -typedef void TAKES_R128 vtlbMemW128FP(u32 addr,r128 data); - -template struct vtlbMemFP; - -template<> struct vtlbMemFP< 8, false> { typedef vtlbMemR8FP fn; static const uptr Index = 0; }; -template<> struct vtlbMemFP< 16, false> { typedef vtlbMemR16FP fn; static const uptr Index = 1; }; -template<> struct vtlbMemFP< 32, false> { typedef vtlbMemR32FP fn; static const uptr Index = 2; }; -template<> struct vtlbMemFP< 64, false> { typedef vtlbMemR64FP fn; static const uptr Index = 3; }; -template<> struct vtlbMemFP<128, false> { typedef vtlbMemR128FP fn; static const uptr Index = 4; }; -template<> struct vtlbMemFP< 8, true> { typedef vtlbMemW8FP fn; static const uptr Index = 0; }; -template<> struct vtlbMemFP< 16, true> { typedef vtlbMemW16FP fn; static const uptr Index = 1; }; -template<> struct vtlbMemFP< 32, true> { typedef vtlbMemW32FP fn; static const uptr Index = 2; }; -template<> struct vtlbMemFP< 64, true> { typedef vtlbMemW64FP fn; static const uptr Index = 3; }; -template<> struct vtlbMemFP<128, true> { typedef vtlbMemW128FP fn; static const uptr Index = 4; }; - -typedef u32 vtlbHandler; - extern bool vtlb_Core_Alloc(); extern void vtlb_Core_Free(); extern void vtlb_Alloc_Ppmap(); @@ -115,111 +84,6 @@ extern void vtlb_DynGenWrite_Const(u32 bits, bool xmm, u32 addr_const, int value extern void vtlb_DynGenDispatchers(); -namespace vtlb_private -{ - static const uint VTLB_PAGE_BITS = 12; - static const uint VTLB_PAGE_MASK = 4095; - static const uint VTLB_PAGE_SIZE = 4096; - - static const uint VTLB_PMAP_SZ = _1mb * 512; - static const uint VTLB_PMAP_ITEMS = VTLB_PMAP_SZ / VTLB_PAGE_SIZE; - static const uint VTLB_VMAP_ITEMS = _4gb / VTLB_PAGE_SIZE; - - static const uint VTLB_HANDLER_ITEMS = 128; - - static const uptr POINTER_SIGN_BIT = 1ULL << (sizeof(uptr) * 8 - 1); - - struct VTLBPhysical - { - private: - sptr value; - explicit VTLBPhysical(sptr value): value(value) { } - public: - VTLBPhysical(): value(0) {} - /// Create from a pointer to raw memory - static VTLBPhysical fromPointer(void *ptr) { return fromPointer((sptr)ptr); } - /// Create from an integer representing a pointer to raw memory - static VTLBPhysical fromPointer(sptr ptr); - /// Create from a handler and address - static VTLBPhysical fromHandler(vtlbHandler handler); - - /// Get the raw value held by the entry - uptr raw() const { return value; } - /// Returns whether or not this entry is a handler - bool isHandler() const { return value < 0; } - /// Assumes the entry is a pointer, giving back its value - uptr assumePtr() const { return value; } - /// Assumes the entry is a handler, and gets the raw handler ID - u8 assumeHandler() const { return value; } - }; - - struct VTLBVirtual - { - private: - uptr value; - explicit VTLBVirtual(uptr value): value(value) { } - public: - VTLBVirtual(): value(0) {} - VTLBVirtual(VTLBPhysical phys, u32 paddr, u32 vaddr); - static VTLBVirtual fromPointer(uptr ptr, u32 vaddr) { - return VTLBVirtual(VTLBPhysical::fromPointer(ptr), 0, vaddr); - } - - /// Get the raw value held by the entry - uptr raw() const { return value; } - /// Returns whether or not this entry is a handler - bool isHandler(u32 vaddr) const { return (sptr)(value + vaddr) < 0; } - /// Assumes the entry is a pointer, giving back its value - uptr assumePtr(u32 vaddr) const { return value + vaddr; } - /// Assumes the entry is a handler, and gets the raw handler ID - u8 assumeHandlerGetID() const { return value; } - /// Assumes the entry is a handler, and gets the physical address - u32 assumeHandlerGetPAddr(u32 vaddr) const { return (value + vaddr - assumeHandlerGetID()) & ~POINTER_SIGN_BIT; } - /// Assumes the entry is a handler, returning it as a void* - void *assumeHandlerGetRaw(int index, bool write) const; - /// Assumes the entry is a handler, returning it - template - typename vtlbMemFP::fn *assumeHandler() const; - }; - - struct MapData - { - // first indexer -- 8/16/32/64/128 bit tables [values 0-4] - // second indexer -- read/write [0 or 1] - // third indexer -- 128 possible handlers! - void* RWFT[5][2][VTLB_HANDLER_ITEMS]; - - VTLBPhysical pmap[VTLB_PMAP_ITEMS]; //512KB // PS2 physical to x86 physical - - VTLBVirtual* vmap; //4MB (allocated by vtlb_init) // PS2 virtual to x86 physical - - u32* ppmap; //4MB (allocated by vtlb_init) // PS2 virtual to PS2 physical - - uptr fastmem_base; - - MapData() - { - vmap = NULL; - ppmap = NULL; - fastmem_base = 0; - } - }; - - alignas(64) extern MapData vtlbdata; - - inline void *VTLBVirtual::assumeHandlerGetRaw(int index, bool write) const - { - return vtlbdata.RWFT[index][write][assumeHandlerGetID()]; - } - - template - typename vtlbMemFP::fn *VTLBVirtual::assumeHandler() const - { - using FP = vtlbMemFP; - return (typename FP::fn *)assumeHandlerGetRaw(FP::Index, Write); - } -} - enum vtlb_ProtectionMode { ProtMode_None = 0, // page is 'unaccounted' -- neither protected nor unprotected diff --git a/app/src/main/cpp/pcsx2/vtlbDef.h b/app/src/main/cpp/pcsx2/vtlbDef.h new file mode 100644 index 0000000..5bd75a3 --- /dev/null +++ b/app/src/main/cpp/pcsx2/vtlbDef.h @@ -0,0 +1,145 @@ +// +// Created by k2154 on 2025-08-18. +// + +#ifndef PCSX2_VTLBDEF_H +#define PCSX2_VTLBDEF_H + +#include "MemoryTypes.h" +#include "common/SingleRegisterTypes.h" + +// Specialized function pointers for each read type +typedef mem8_t vtlbMemR8FP(u32 addr); +typedef mem16_t vtlbMemR16FP(u32 addr); +typedef mem32_t vtlbMemR32FP(u32 addr); +typedef mem64_t vtlbMemR64FP(u32 addr); +typedef RETURNS_R128 vtlbMemR128FP(u32 addr); + +// Specialized function pointers for each write type +typedef void vtlbMemW8FP(u32 addr,mem8_t data); +typedef void vtlbMemW16FP(u32 addr,mem16_t data); +typedef void vtlbMemW32FP(u32 addr,mem32_t data); +typedef void vtlbMemW64FP(u32 addr,mem64_t data); +typedef void TAKES_R128 vtlbMemW128FP(u32 addr,r128 data); + +template struct vtlbMemFP; + +template<> struct vtlbMemFP< 8, false> { typedef vtlbMemR8FP fn; static const uptr Index = 0; }; +template<> struct vtlbMemFP< 16, false> { typedef vtlbMemR16FP fn; static const uptr Index = 1; }; +template<> struct vtlbMemFP< 32, false> { typedef vtlbMemR32FP fn; static const uptr Index = 2; }; +template<> struct vtlbMemFP< 64, false> { typedef vtlbMemR64FP fn; static const uptr Index = 3; }; +template<> struct vtlbMemFP<128, false> { typedef vtlbMemR128FP fn; static const uptr Index = 4; }; +template<> struct vtlbMemFP< 8, true> { typedef vtlbMemW8FP fn; static const uptr Index = 0; }; +template<> struct vtlbMemFP< 16, true> { typedef vtlbMemW16FP fn; static const uptr Index = 1; }; +template<> struct vtlbMemFP< 32, true> { typedef vtlbMemW32FP fn; static const uptr Index = 2; }; +template<> struct vtlbMemFP< 64, true> { typedef vtlbMemW64FP fn; static const uptr Index = 3; }; +template<> struct vtlbMemFP<128, true> { typedef vtlbMemW128FP fn; static const uptr Index = 4; }; + +typedef u32 vtlbHandler; + +namespace vtlb_private +{ + static const uint VTLB_PAGE_BITS = 12; + static const uint VTLB_PAGE_MASK = 4095; + static const uint VTLB_PAGE_SIZE = 4096; + + static const uint VTLB_PMAP_SZ = _1mb * 512; + static const uint VTLB_PMAP_ITEMS = VTLB_PMAP_SZ / VTLB_PAGE_SIZE; + static const uint VTLB_VMAP_ITEMS = _4gb / VTLB_PAGE_SIZE; + + static const uint VTLB_HANDLER_ITEMS = 128; + + static const uptr POINTER_SIGN_BIT = 1ULL << (sizeof(uptr) * 8 - 1); + + struct VTLBPhysical + { + private: + sptr value; + explicit VTLBPhysical(sptr value): value(value) { } + public: + VTLBPhysical(): value(0) {} + /// Create from a pointer to raw memory + static VTLBPhysical fromPointer(void *ptr) { return fromPointer((sptr)ptr); } + /// Create from an integer representing a pointer to raw memory + static VTLBPhysical fromPointer(sptr ptr); + /// Create from a handler and address + static VTLBPhysical fromHandler(vtlbHandler handler); + + /// Get the raw value held by the entry + uptr raw() const { return value; } + /// Returns whether or not this entry is a handler + bool isHandler() const { return value < 0; } + /// Assumes the entry is a pointer, giving back its value + uptr assumePtr() const { return value; } + /// Assumes the entry is a handler, and gets the raw handler ID + u8 assumeHandler() const { return value; } + }; + + struct VTLBVirtual + { + public: + uptr value; + explicit VTLBVirtual(uptr value): value(value) { } + public: + VTLBVirtual(): value(0) {} + VTLBVirtual(VTLBPhysical phys, u32 paddr, u32 vaddr); + static VTLBVirtual fromPointer(uptr ptr, u32 vaddr) { + return VTLBVirtual(VTLBPhysical::fromPointer(ptr), 0, vaddr); + } + + /// Get the raw value held by the entry + uptr raw() const { return value; } + /// Returns whether or not this entry is a handler + bool isHandler(u32 vaddr) const { return (sptr)(value + vaddr) < 0; } + /// Assumes the entry is a pointer, giving back its value + uptr assumePtr(u32 vaddr) const { return value + vaddr; } + /// Assumes the entry is a handler, and gets the raw handler ID + u8 assumeHandlerGetID() const { return value; } + /// Assumes the entry is a handler, and gets the physical address + u32 assumeHandlerGetPAddr(u32 vaddr) const { return (value + vaddr - assumeHandlerGetID()) & ~POINTER_SIGN_BIT; } + /// Assumes the entry is a handler, returning it as a void* + void *assumeHandlerGetRaw(int index, bool write) const; + /// Assumes the entry is a handler, returning it + template + typename vtlbMemFP::fn *assumeHandler() const; + }; + + struct MapData + { + // first indexer -- 8/16/32/64/128 bit tables [values 0-4] + // second indexer -- read/write [0 or 1] + // third indexer -- 128 possible handlers! + void* RWFT[5][2][VTLB_HANDLER_ITEMS]; + + VTLBPhysical pmap[VTLB_PMAP_ITEMS]; //512KB // PS2 physical to x86 physical + + VTLBVirtual* vmap; //4MB (allocated by vtlb_init) // PS2 virtual to x86 physical + + u32* ppmap; //4MB (allocated by vtlb_init) // PS2 virtual to PS2 physical + + uptr fastmem_base; + + MapData() + { + vmap = NULL; + ppmap = NULL; + fastmem_base = 0; + } + }; + + extern MapData& vtlbdata; + + inline void *VTLBVirtual::assumeHandlerGetRaw(int index, bool write) const + { + return vtlbdata.RWFT[index][write][assumeHandlerGetID()]; + } + + template + typename vtlbMemFP::fn *VTLBVirtual::assumeHandler() const + { + using FP = vtlbMemFP; + return (typename FP::fn *)assumeHandlerGetRaw(FP::Index, Write); + } +} + +#endif //PCSX2_VTLBDEF_H diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp index ac3cac8..eed1dad 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp @@ -493,7 +493,7 @@ static const void* _DynGen_EnterRecompiledCode() if (CHECK_FASTMEM) { // xMOV(RFASTMEMBASE, ptrNative[&vtlb_private::vtlbdata.fastmem_base]); - armAsm->Ldr(RFASTMEMBASE, armMemOperandPtr(&vtlb_private::vtlbdata.fastmem_base)); + armAsm->Ldr(RFASTMEMBASE, PTR_CPU(vtlbdata.fastmem_base)); } // xJMP(DispatcherReg); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp index 777d306..f2315e1 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp @@ -166,7 +166,8 @@ namespace vtlb_private // xSHR(eax, VTLB_PAGE_BITS); armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS); // xMOV(rax, ptrNative[xComplexAddress(arg3reg, vtlbdata.vmap, rax * wordsize)]); - armMoveAddressToReg(RXVIXLSCRATCH, vtlbdata.vmap); +// armMoveAddressToReg(RXVIXLSCRATCH, vtlbdata.vmap); + armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap)); armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3)); // xADD(arg1reg, rax); armAsm->Adds(RCX, RCX, RAX); @@ -177,49 +178,50 @@ namespace vtlb_private { pxAssert(bits == 8 || bits == 16 || bits == 32 || bits == 64 || bits == 128); + auto mop = a64::MemOperand(RCX); switch (bits) { case 8: if (sign) { // xMOVSX(rax, ptr8[arg1reg]); - armAsm->Ldrsb(RAX, a64::MemOperand(RCX)); + armAsm->Ldrsb(RAX, mop); } else { // xMOVZX(rax, ptr8[arg1reg]); - armAsm->Ldrb(RAX, a64::MemOperand(RCX)); + armAsm->Ldrb(RAX, mop); } break; case 16: if (sign) { // xMOVSX(rax, ptr16[arg1reg]); - armAsm->Ldrsh(RAX, a64::MemOperand(RCX)); + armAsm->Ldrsh(RAX, mop); } else { // xMOVZX(rax, ptr16[arg1reg]); - armAsm->Ldrh(RAX, a64::MemOperand(RCX)); + armAsm->Ldrh(RAX, mop); } break; case 32: if (sign) { // xMOVSX(rax, ptr32[arg1reg]); - armAsm->Ldrsw(RAX, a64::MemOperand(RCX)); + armAsm->Ldrsw(RAX, mop); } else { // xMOV(eax, ptr32[arg1reg]); - armAsm->Ldr(EAX, a64::MemOperand(RCX)); + armAsm->Ldr(EAX, mop); } break; case 64: // xMOV(rax, ptr64[arg1reg]); - armAsm->Ldr(RAX, a64::MemOperand(RCX)); + armAsm->Ldr(RAX, mop); break; case 128: // xMOVAPS(xmm0, ptr128[arg1reg]); - armAsm->Ldr(xmm0.Q(), a64::MemOperand(RCX)); + armAsm->Ldr(xmm0.Q(), mop); break; jNO_DEFAULT @@ -229,31 +231,32 @@ namespace vtlb_private // ------------------------------------------------------------------------ static void DynGen_DirectWrite(u32 bits) { + auto mop = a64::MemOperand(RCX); switch (bits) { case 8: // xMOV(ptr[arg1reg], xRegister8(arg2regd)); - armAsm->Strb(EDX, a64::MemOperand(RCX)); + armAsm->Strb(EDX, mop); break; case 16: // xMOV(ptr[arg1reg], xRegister16(arg2regd)); - armAsm->Strh(EDX, a64::MemOperand(RCX)); + armAsm->Strh(EDX, mop); break; case 32: // xMOV(ptr[arg1reg], arg2regd); - armAsm->Str(EDX, a64::MemOperand(RCX)); + armAsm->Str(EDX, mop); break; case 64: // xMOV(ptr[arg1reg], arg2reg); - armAsm->Str(RDX, a64::MemOperand(RCX)); + armAsm->Str(RDX, mop); break; case 128: // xMOVAPS(ptr[arg1reg], xRegisterSSE::GetArgRegister(1, 0)); - armAsm->Str(armQRegister(1).Q(), a64::MemOperand(RCX)); + armAsm->Str(armQRegister(1).Q(), mop); break; } } @@ -425,7 +428,7 @@ void vtlb_DynGenDispatchers() //// copy code memcpy(code_start, m_IndirectDispatchers, INDIRECT_DISPATCHERS_SIZE); //// - armSetAsmPtr(code_start, INDIRECT_DISPATCHERS_SIZE, nullptr); + armSetAsmPtr(code_start + INDIRECT_DISPATCHERS_SIZE, INDIRECT_DISPATCHERS_SIZE, nullptr); armStartBlock(); } @@ -469,7 +472,7 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea const u8* codeStart; // const xAddressReg x86addr(addr_reg); - a64::MemOperand baseAddr = a64::MemOperand(RFASTMEMBASE, a64::XRegister(addr_reg)); + a64::MemOperand x86addr = a64::MemOperand(RFASTMEMBASE, a64::XRegister(addr_reg)); if (!xmm) { @@ -479,23 +482,24 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea codeStart = armGetCurrentCodePointer(); // const xRegister64 x86reg(x86_dest_reg); + auto x86reg = a64::XRegister(x86_dest_reg); switch (bits) { case 8: // sign ? xMOVSX(x86reg, ptr8[RFASTMEMBASE + x86addr]) : xMOVZX(xRegister32(x86reg), ptr8[RFASTMEMBASE + x86addr]); - sign ? armAsm->Ldrsb(a64::XRegister(x86_dest_reg), baseAddr) : armAsm->Ldrb(a64::WRegister(x86_dest_reg), baseAddr); + sign ? armAsm->Ldrsb(x86reg, x86addr) : armAsm->Ldrb(x86reg.W(), x86addr); break; case 16: // sign ? xMOVSX(x86reg, ptr16[RFASTMEMBASE + x86addr]) : xMOVZX(xRegister32(x86reg), ptr16[RFASTMEMBASE + x86addr]); - sign ? armAsm->Ldrsh(a64::XRegister(x86_dest_reg), baseAddr) : armAsm->Ldrh(a64::WRegister(x86_dest_reg), baseAddr); + sign ? armAsm->Ldrsh(x86reg, x86addr) : armAsm->Ldrh(x86reg.W(), x86addr); break; case 32: // sign ? xMOVSX(x86reg, ptr32[RFASTMEMBASE + x86addr]) : xMOV(xRegister32(x86reg), ptr32[RFASTMEMBASE + x86addr]); - sign ? armAsm->Ldrsw(a64::XRegister(x86_dest_reg), baseAddr) : armAsm->Ldr(a64::WRegister(x86_dest_reg), baseAddr); + sign ? armAsm->Ldrsw(x86reg, x86addr) : armAsm->Ldr(x86reg.W(), x86addr); break; case 64: // xMOV(x86reg, ptr64[RFASTMEMBASE + x86addr]); - armAsm->Ldr(a64::XRegister(x86_dest_reg), baseAddr); + armAsm->Ldr(x86reg, x86addr); break; jNO_DEFAULT @@ -510,7 +514,7 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea // const xRegisterSSE xmmreg(x86_dest_reg); const a64::QRegister xmmreg(x86_dest_reg); // xMOVSSZX(xmmreg, ptr32[RFASTMEMBASE + x86addr]); - armAsm->Ldr(xmmreg.S(), baseAddr); + armAsm->Ldr(xmmreg.S(), x86addr); } // vtlb_AddLoadStoreInfo((uptr)codeStart, static_cast(x86Ptr - codeStart), @@ -536,31 +540,43 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const, auto vmv = vtlbdata.vmap[addr_const >> VTLB_PAGE_BITS]; if (!vmv.isHandler(addr_const)) { - auto ppf = vmv.assumePtr(addr_const); +// uptr ppf = vmv.assumePtr(addr_const); +// auto mop = armMemOperandPtr((u8*)ppf); + + armAsm->Mov(ECX, addr_const); + armAsm->Mov(EAX, ECX); + armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS); + armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap)); + armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3)); + armAsm->Add(RCX, RCX, RAX); + auto mop = a64::MemOperand(RCX); + if (!xmm) { // x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(eax), eax.GetId()); x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(EAX), EAX.GetCode()); + + auto regX = a64::XRegister(x86_dest_reg); switch (bits) { case 8: // sign ? xMOVSX(xRegister64(x86_dest_reg), ptr8[(u8*)ppf]) : xMOVZX(xRegister32(x86_dest_reg), ptr8[(u8*)ppf]); - sign ? armAsm->Ldrsb(a64::XRegister(x86_dest_reg), armMemOperandPtr((u8*)ppf)) : armAsm->Ldrb(a64::WRegister(x86_dest_reg), armMemOperandPtr((u8*)ppf)); + sign ? armAsm->Ldrsb(regX, mop) : armAsm->Ldrb(regX.W(), mop); break; case 16: // sign ? xMOVSX(xRegister64(x86_dest_reg), ptr16[(u16*)ppf]) : xMOVZX(xRegister32(x86_dest_reg), ptr16[(u16*)ppf]); - sign ? armAsm->Ldrsh(a64::XRegister(x86_dest_reg), armMemOperandPtr((u16*)ppf)) : armAsm->Ldrh(a64::WRegister(x86_dest_reg), armMemOperandPtr((u16*)ppf)); + sign ? armAsm->Ldrsh(regX, mop) : armAsm->Ldrh(regX.W(), mop); break; case 32: // sign ? xMOVSX(xRegister64(x86_dest_reg), ptr32[(u32*)ppf]) : xMOV(xRegister32(x86_dest_reg), ptr32[(u32*)ppf]); - sign ? armAsm->Ldrsw(a64::XRegister(x86_dest_reg), armMemOperandPtr((u32*)ppf)) : armAsm->Ldr(a64::WRegister(x86_dest_reg), armMemOperandPtr((u32*)ppf)); + sign ? armAsm->Ldrsw(regX, mop) : armAsm->Ldr(regX.W(), mop); break; case 64: // xMOV(xRegister64(x86_dest_reg), ptr64[(u64*)ppf]); - armAsm->Ldr(a64::XRegister(x86_dest_reg), armMemOperandPtr((u64*)ppf)); + armAsm->Ldr(regX, mop); break; } } @@ -568,7 +584,7 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const, { x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeXMMreg(0), 0); // xMOVSSZX(xRegisterSSE(x86_dest_reg), ptr32[(float*)ppf]); - armAsm->Ldr(a64::QRegister(x86_dest_reg).S(), armMemOperandPtr((float*)ppf)); + armAsm->Ldr(a64::QRegister(x86_dest_reg).S(), mop); } } else @@ -619,27 +635,29 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const, { // x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(eax), eax.GetId()); x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(EAX), EAX.GetCode()); + + auto regX = a64::XRegister(x86_dest_reg); switch (bits) { // save REX prefix by using 32bit dest for zext case 8: // sign ? xMOVSX(xRegister64(x86_dest_reg), al) : xMOVZX(xRegister32(x86_dest_reg), al); - sign ? armAsm->Sxtb(a64::XRegister(x86_dest_reg), EAX) : armAsm->Uxtb(a64::WRegister(x86_dest_reg), EAX); + sign ? armAsm->Sxtb(regX, EAX) : armAsm->Uxtb(regX.W(), EAX); break; case 16: // sign ? xMOVSX(xRegister64(x86_dest_reg), ax) : xMOVZX(xRegister32(x86_dest_reg), ax); - sign ? armAsm->Sxth(a64::XRegister(x86_dest_reg), EAX) : armAsm->Uxth(a64::WRegister(x86_dest_reg), EAX); + sign ? armAsm->Sxth(regX, EAX) : armAsm->Uxth(regX.W(), EAX); break; case 32: // sign ? xMOVSX(xRegister64(x86_dest_reg), eax) : xMOV(xRegister32(x86_dest_reg), eax); - sign ? armAsm->Sxtw(a64::XRegister(x86_dest_reg), EAX) : armAsm->Mov(a64::WRegister(x86_dest_reg), EAX); + sign ? armAsm->Sxtw(regX, EAX) : armAsm->Mov(regX.W(), EAX); break; case 64: // xMOV(xRegister64(x86_dest_reg), rax); - armAsm->Mov(a64::XRegister(x86_dest_reg) , RAX); + armAsm->Mov(regX , RAX); break; } } @@ -704,11 +722,19 @@ int vtlb_DynGenReadQuad_Const(u32 bits, u32 addr_const, vtlb_ReadRegAllocCallbac auto vmv = vtlbdata.vmap[addr_const >> VTLB_PAGE_BITS]; if (!vmv.isHandler(addr_const)) { - void* ppf = reinterpret_cast(vmv.assumePtr(addr_const)); +// void* ppf = reinterpret_cast(vmv.assumePtr(addr_const)); reg = dest_reg_alloc ? dest_reg_alloc() : (_freeXMMreg(0), 0); if (reg >= 0) { // xMOVAPS(xRegisterSSE(reg), ptr128[ppf]); - armAsm->Ldr(a64::QRegister(reg).Q(), armMemOperandPtr(ppf)); +// armAsm->Ldr(a64::QRegister(reg).Q(), armMemOperandPtr(ppf)); + + armAsm->Mov(ECX, addr_const); + armAsm->Mov(EAX, ECX); + armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS); + armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap)); + armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3)); + armAsm->Add(RCX, RCX, RAX); + armAsm->Ldr(a64::QRegister(reg).Q(), a64::MemOperand(RCX)); } } else @@ -806,23 +832,24 @@ void vtlb_DynGenWrite(u32 sz, bool xmm, int addr_reg, int value_reg) if (!xmm) { + auto regX = a64::XRegister(value_reg); switch (sz) { case 8: // xMOV(ptr8[RFASTMEMBASE + vaddr_reg], xRegister8(xRegister32(value_reg))); - armAsm->Strb(a64::WRegister(value_reg), mop); + armAsm->Strb(regX.W(), mop); break; case 16: // xMOV(ptr16[RFASTMEMBASE + vaddr_reg], xRegister16(value_reg)); - armAsm->Strh(a64::WRegister(value_reg), mop); + armAsm->Strh(regX.W(), mop); break; case 32: // xMOV(ptr32[RFASTMEMBASE + vaddr_reg], xRegister32(value_reg)); - armAsm->Str(a64::WRegister(value_reg), mop); + armAsm->Str(regX.W(), mop); break; case 64: // xMOV(ptr64[RFASTMEMBASE + vaddr_reg], xRegister64(value_reg)); - armAsm->Str(a64::XRegister(value_reg), mop); + armAsm->Str(regX, mop); break; jNO_DEFAULT @@ -831,15 +858,17 @@ void vtlb_DynGenWrite(u32 sz, bool xmm, int addr_reg, int value_reg) else { pxAssert(sz == 32 || sz == 128); + + auto regQ = a64::QRegister(value_reg); switch (sz) { case 32: // xMOVSS(ptr32[RFASTMEMBASE + vaddr_reg], xRegisterSSE(value_reg)); - armAsm->Str(a64::QRegister(value_reg).S(), mop); + armAsm->Str(regQ.S(), mop); break; case 128: // xMOVAPS(ptr128[RFASTMEMBASE + vaddr_reg], xRegisterSSE(value_reg)); - armAsm->Str(a64::QRegister(value_reg).Q(), mop); + armAsm->Str(regQ.Q(), mop); break; jNO_DEFAULT @@ -918,30 +947,40 @@ void vtlb_DynGenWrite_Const(u32 bits, bool xmm, u32 addr_const, int value_reg) auto vmv = vtlbdata.vmap[addr_const >> VTLB_PAGE_BITS]; if (!vmv.isHandler(addr_const)) { - auto ppf = vmv.assumePtr(addr_const); - const a64::MemOperand mop = armMemOperandPtr((void*)ppf); +// auto ppf = vmv.assumePtr(addr_const); +// a64::MemOperand mop = armMemOperandPtr((u8*)ppf); + + armAsm->Mov(ECX, addr_const); + armAsm->Mov(EAX, ECX); + armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS); + armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap)); + armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3)); + armAsm->Add(RCX, RCX, RAX); + auto mop = a64::MemOperand(RCX); + if (!xmm) { + auto regX = a64::XRegister(value_reg); switch (bits) { case 8: // xMOV(ptr[(void*)ppf], xRegister8(xRegister32(value_reg))); - armAsm->Strb(a64::WRegister(value_reg), mop); + armAsm->Strb(regX.W(), mop); break; case 16: // xMOV(ptr[(void*)ppf], xRegister16(value_reg)); - armAsm->Strh(a64::WRegister(value_reg), mop); + armAsm->Strh(regX.W(), mop); break; case 32: // xMOV(ptr[(void*)ppf], xRegister32(value_reg)); - armAsm->Str(a64::WRegister(value_reg), mop); + armAsm->Str(regX.W(), mop); break; case 64: // xMOV(ptr64[(void*)ppf], xRegister64(value_reg)); - armAsm->Str(a64::XRegister(value_reg), mop); + armAsm->Str(regX, mop); break; jNO_DEFAULT @@ -949,16 +988,17 @@ void vtlb_DynGenWrite_Const(u32 bits, bool xmm, u32 addr_const, int value_reg) } else { + auto regQ = a64::QRegister(value_reg); switch (bits) { case 32: // xMOVSS(ptr[(void*)ppf], xRegisterSSE(value_reg)); - armAsm->Str(a64::QRegister(value_reg).S(), mop); + armAsm->Str(regQ.S(), mop); break; case 128: // xMOVAPS(ptr128[(void*)ppf], xRegisterSSE(value_reg)); - armAsm->Str(a64::QRegister(value_reg).Q(), mop); + armAsm->Str(regQ.Q(), mop); break; jNO_DEFAULT @@ -1047,8 +1087,9 @@ void vtlb_DynV2P() // xSHR(eax, VTLB_PAGE_BITS); armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS); // xMOV(eax, ptr[xComplexAddress(rdx, vtlbdata.ppmap, rax * 4)]); - armMoveAddressToReg(RDX, vtlbdata.ppmap); - armAsm->Ldr(EAX, a64::MemOperand(RDX, RAX, a64::LSL, 2)); +// armMoveAddressToReg(RDX, vtlbdata.ppmap); + armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.ppmap)); + armAsm->Ldr(EAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 2)); // xOR(eax, ecx); armAsm->Orr(EAX, EAX, ECX); diff --git a/app/src/main/cpp/pcsx2/x86/microVU.cpp b/app/src/main/cpp/pcsx2/x86/microVU.cpp index e6cf3df..d36f8c6 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU.cpp +++ b/app/src/main/cpp/pcsx2/x86/microVU.cpp @@ -7,7 +7,8 @@ #include "common/Perf.h" #include "common/StringUtil.h" -alignas(16) vuRegistersPack g_vuRegistersPack; +alignas(64) vuRegistersPack g_vuRegistersPack; +VU_Thread& vu1Thread = g_vuRegistersPack.vu1Thread; //------------------------------------------------------------------ // Micro VU - Main Functions diff --git a/app/src/main/cpp/pcsx2/x86/microVU.h b/app/src/main/cpp/pcsx2/x86/microVU.h index 38f7084..05b9f99 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU.h +++ b/app/src/main/cpp/pcsx2/x86/microVU.h @@ -278,8 +278,9 @@ public: struct vuRegistersPack { alignas(16) microVU microVU[2]; + alignas(64) VU_Thread vu1Thread; }; -alignas(16) extern vuRegistersPack g_vuRegistersPack; +alignas(64) extern vuRegistersPack g_vuRegistersPack; //// static microVU& microVU0 = g_vuRegistersPack.microVU[0]; static microVU& microVU1 = g_vuRegistersPack.microVU[1]; diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl b/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl index 7d8a3a1..7e3141f 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Branch.inl @@ -413,7 +413,9 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump) else { // xLoadFarAddr(arg2reg, &mVUpBlock->pStateEnd); - armAsm->Ldr(RCX, PTR_MBLOCK(pStateEnd)); + armMoveAddressToReg(RCX, &mVUpBlock->pStateEnd); +// armAsm->Ldr(RXVIXLSCRATCH, PTR_MVU(microVU[mVU.index].prog.IRinfo.pBlock)); +// armAsm->Add(RCX, RXVIXLSCRATCH, offsetof(microBlock, pStateEnd)); } if (mVUup.eBit && isEvilJump) // E-bit EvilJump @@ -442,7 +444,7 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump) mVUrestoreRegs(mVU); // xJMP(gprT1q); // Jump to rec-code address - armAsm->Br(RAX); + armAsm->Br(gprT1q); } void normBranch(mV, microFlagCycles& mFC) @@ -456,7 +458,7 @@ void normBranch(mV, microFlagCycles& mFC) u32 tempPC = iPC; if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4)); - armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4)); + armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x400 : 0x4)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); @@ -486,7 +488,7 @@ void normBranch(mV, microFlagCycles& mFC) u32 tempPC = iPC; if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8)); - armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8)); + armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x800 : 0x8)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8)); @@ -515,7 +517,9 @@ void normBranch(mV, microFlagCycles& mFC) memcpy(&mVUpBlock->pStateEnd, &mVUregs, sizeof(microRegInfo)); // xLoadFarAddr(rax, &mVUpBlock->pStateEnd); - armAsm->Ldr(RAX, PTR_MBLOCK(pStateEnd)); + armMoveAddressToReg(RAX, &mVUpBlock->pStateEnd); +// armAsm->Ldr(RXVIXLSCRATCH, PTR_MVU(microVU[mVU.index].prog.IRinfo.pBlock)); +// armAsm->Add(RAX, RXVIXLSCRATCH, offsetof(microBlock, pStateEnd)); // xCALL((void*)mVU.copyPLState); armEmitCall(mVU.copyPLState); @@ -557,7 +561,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc) u32 tempPC = iPC; if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8)); - armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8)); + armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x800 : 0x8)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8)); @@ -609,7 +613,7 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc) u32 tempPC = iPC; if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4)); - armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4)); + armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x400 : 0x4)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); @@ -654,7 +658,9 @@ void condBranch(mV, microFlagCycles& mFC, a64::Condition JMPcc) memcpy(&mVUpBlock->pStateEnd, &mVUregs, sizeof(microRegInfo)); // xLoadFarAddr(rax, &mVUpBlock->pStateEnd); - armAsm->Ldr(RAX, PTR_MBLOCK(pStateEnd)); + armMoveAddressToReg(RAX, &mVUpBlock->pStateEnd); +// armAsm->Ldr(RXVIXLSCRATCH, PTR_MVU(microVU[mVU.index].prog.IRinfo.pBlock)); +// armAsm->Add(RAX, RXVIXLSCRATCH, offsetof(microBlock, pStateEnd)); // xCALL((void*)mVU.copyPLState); armEmitCall(mVU.copyPLState); @@ -800,7 +806,7 @@ void normJump(mV, microFlagCycles& mFC) if (THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4)); - armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4)); + armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x400 : 0x4)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); @@ -833,7 +839,7 @@ void normJump(mV, microFlagCycles& mFC) if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8)); - armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8)); + armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x800 : 0x8)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8)); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl b/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl index 2d3a3f8..52fa537 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl @@ -515,7 +515,7 @@ void mVUtestCycles(microVU& mVU, microFlagCycles& mFC) armAsm->B(&skip, a64::Condition::pl); // xLoadFarAddr(rax, &mVUpBlock->pState); - armAsm->Ldr(RAX, PTR_MBLOCK(pState)); + armMoveAddressToReg(RAX, &mVUpBlock->pState); // xCALL((void*)mVU.copyPLState); armEmitCall(mVU.copyPLState); @@ -597,7 +597,7 @@ void mVUDoDBit(microVU& mVU, microFlagCycles* mFC) { if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x400 : 0x4)); - armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x400 : 0x4)); + armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x400 : 0x4)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x400 : 0x4)); @@ -624,7 +624,7 @@ void mVUDoTBit(microVU& mVU, microFlagCycles* mFC) { if (mVU.index && THREAD_VU1) { // xTEST(ptr32[&vu1Thread.vuFBRST], (isVU1 ? 0x800 : 0x8)); - armAsm->Tst(armLoadPtr(PTR_VU1(vuFBRST)), (isVU1 ? 0x800 : 0x8)); + armAsm->Tst(armLoadPtr(PTR_MVU(vu1Thread.vuFBRST)), (isVU1 ? 0x800 : 0x8)); } else { // xTEST(ptr32[&VU0.VI[REG_FBRST].UL], (isVU1 ? 0x800 : 0x8)); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl index 50c9913..43476ec 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl @@ -28,10 +28,8 @@ void mVUdispatcherAB(mV) armBeginStackFrame(); // From memory to registry - armMoveAddressToReg(RSTATE_x29, &vu1Thread); armMoveAddressToReg(RSTATE_MVU, &g_vuRegistersPack); armMoveAddressToReg(RSTATE_CPU, &g_cpuRegistersPack); - armMoveAddressToReg(RFASTMEMBASE, &mVUpBlock); // = The caller has already put the needed parameters in ecx/edx: if (!isVU1) { diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl b/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl index 779f47f..c275666 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Lower.inl @@ -388,9 +388,9 @@ mVUop(mVU_EEXP) // xMUL.SS(t1, ptr32[mVUglob.E2]); armAsm->Fmul(t1.S(), t1.S(), armLoadPtrV(PTR_CPU(mVUglob.E2)).S()); SSE_ADDSS(mVU, xmmPQ, t1); - eexpHelper(&mVUglob.E3); - eexpHelper(&mVUglob.E4); - eexpHelper(&mVUglob.E5); + eexpHelper(PTR_CPU(mVUglob.E3)); + eexpHelper(PTR_CPU(mVUglob.E4)); + eexpHelper(PTR_CPU(mVUglob.E5)); SSE_MULSS(mVU, t2, Fs); // xMUL.SS(t2, ptr32[mVUglob.E6]); armAsm->Fmul(t2.S(), t2.S(), armLoadPtrV(PTR_CPU(mVUglob.E6)).S()); @@ -2069,7 +2069,7 @@ mVUop(mVU_XTOP) const a64::Register& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI); // xMOVZX(regT, ptr16[&mVU.getVifRegs().top]); if (mVU.index && THREAD_VU1) { - armAsm->Ldrh(regT, PTR_VU1(vifRegs.top)); + armAsm->Ldrh(regT, PTR_MVU(vu1Thread.vifRegs.top)); } else { armAsm->Ldrh(regT, PTR_CPU(vifRegs[mVU.index].top)); } @@ -2093,7 +2093,7 @@ mVUop(mVU_XITOP) const a64::Register& regT = mVU.regAlloc->allocGPR(-1, _It_, mVUlow.backupVI); // xMOVZX(regT, ptr16[&mVU.getVifRegs().itop]); if (mVU.index && THREAD_VU1) { - armAsm->Ldrh(regT, PTR_VU1(vifRegs.itop)); + armAsm->Ldrh(regT, PTR_MVU(vu1Thread.vifRegs.itop)); } else { armAsm->Ldrh(regT, PTR_CPU(vifRegs[mVU.index].itop)); } From e74ffc555dcf67487a55d379db62365f97ed3f57 Mon Sep 17 00:00:00 2001 From: k2154 Date: Tue, 19 Aug 2025 07:16:48 +0900 Subject: [PATCH 07/12] Android project - Supports chd files --- app/src/main/cpp/common/FileSystem.cpp | 51 +++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/app/src/main/cpp/common/FileSystem.cpp b/app/src/main/cpp/common/FileSystem.cpp index 86e0e15..3367519 100644 --- a/app/src/main/cpp/common/FileSystem.cpp +++ b/app/src/main/cpp/common/FileSystem.cpp @@ -998,7 +998,16 @@ std::FILE* FileSystem::OpenCFile(const char* filename, const char* mode, Error* return fp; #else - std::FILE* fp = std::fopen(filename, mode); + + std::FILE* fp; + //// + std::string _filename(filename); + if (_filename.rfind("content://", 0) == 0) { + fp = fdopen(FileSystem::OpenFDFileContent(_filename.c_str()), "rb"); + } else { + fp = std::fopen(_filename.c_str(), mode); + } + //// if (!fp) Error::SetErrno(error, errno); return fp; @@ -1010,7 +1019,15 @@ std::FILE* FileSystem::OpenCFileTryIgnoreCase(const char* filename, const char* #if defined(_WIN32) || defined(__APPLE__) return OpenCFile(filename, mode, error); #else - std::FILE* fp = std::fopen(filename, mode); + std::FILE* fp; + //// + std::string _filename(filename); + if (_filename.rfind("content://", 0) == 0) { + fp = fdopen(FileSystem::OpenFDFileContent(_filename.c_str()), "rb"); + } else { + fp = std::fopen(_filename.c_str(), mode); + } + //// const auto cur_errno = errno; if (!fp) @@ -1023,7 +1040,13 @@ std::FILE* FileSystem::OpenCFileTryIgnoreCase(const char* filename, const char* { if (StringUtil::compareNoCase(file.FileName, filename)) { - fp = std::fopen(file.FileName.c_str(), mode); + //// + if (file.FileName.rfind("content://", 0) == 0) { + fp = fdopen(FileSystem::OpenFDFileContent(file.FileName.c_str()), "rb"); + } else { + fp = std::fopen(file.FileName.c_str(), mode); + } + //// break; } } @@ -1045,7 +1068,16 @@ int FileSystem::OpenFDFile(const char* filename, int flags, int mode, Error* err return -1; #else - const int fd = open(filename, flags, mode); + + int fd; + //// + std::string _filename(filename); + if (_filename.rfind("content://", 0) == 0) { + fd = FileSystem::OpenFDFileContent(_filename.c_str()); + } else { + fd = open(_filename.c_str(), flags, mode); + } + //// if (fd < 0) Error::SetErrno(error, errno); return fd; @@ -1095,7 +1127,16 @@ std::FILE* FileSystem::OpenSharedCFile(const char* filename, const char* mode, F Error::SetErrno(error, errno); return nullptr; #else - std::FILE* fp = std::fopen(filename, mode); + + std::FILE* fp; + //// + std::string _filename(filename); + if (_filename.rfind("content://", 0) == 0) { + fp = fdopen(FileSystem::OpenFDFileContent(_filename.c_str()), "rb"); + } else { + fp = std::fopen(_filename.c_str(), mode); + } + //// if (!fp) Error::SetErrno(error, errno); return fp; From e3b71c4611f35d7f4f14f5703debc4a81c70303d Mon Sep 17 00:00:00 2001 From: k2154 Date: Wed, 20 Aug 2025 22:37:00 +0900 Subject: [PATCH 08/12] Android project - Added ShuffleLanes.h used in VixlHelpers.cpp(armSHUFPS, armPSHUFD) --- app/src/main/cpp/common/CMakeLists.txt | 9 +- .../main/cpp/common/emitter/x86emitter.cpp | 1 + app/src/main/cpp/common/emitter/x86types.h | 5 +- app/src/main/cpp/pcsx2/CMakeLists.txt | 8 +- app/src/main/cpp/pcsx2/Common.h | 1 + app/src/main/cpp/pcsx2/Pcsx2Config.cpp | 2 + app/src/main/cpp/pcsx2/R3000A.h | 2 +- app/src/main/cpp/pcsx2/R5900.h | 2 +- app/src/main/cpp/pcsx2/VUDef.h | 2 + app/src/main/cpp/pcsx2/arm64/ShuffleLanes.h | 272 ++++++++++++++++++ app/src/main/cpp/pcsx2/arm64/Vif_UnpackNEON.h | 2 +- .../arm64/VixlHelpers.cpp} | 82 ++---- .../arm64/VixlHelpers.h} | 12 +- .../cpp/pcsx2/{ => arm64}/cpuRegistersPack.h | 4 + app/src/main/cpp/pcsx2/vtlbDef.h | 2 +- app/src/main/cpp/pcsx2/x86/BaseblockEx.h | 2 +- app/src/main/cpp/pcsx2/x86/iCOP0.cpp | 6 +- app/src/main/cpp/pcsx2/x86/iFPU.cpp | 14 +- app/src/main/cpp/pcsx2/x86/iFPUd.cpp | 18 +- app/src/main/cpp/pcsx2/x86/iR3000A.cpp | 10 +- app/src/main/cpp/pcsx2/x86/iR3000A.h | 2 +- app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp | 2 +- app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp | 7 +- .../cpp/pcsx2/x86/ix86-32/iR5900MultDiv.cpp | 2 +- .../main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp | 25 +- .../main/cpp/pcsx2/x86/microVU_Execute.inl | 16 +- 26 files changed, 380 insertions(+), 130 deletions(-) create mode 100644 app/src/main/cpp/pcsx2/arm64/ShuffleLanes.h rename app/src/main/cpp/{common/arm64/AsmHelpers.cpp => pcsx2/arm64/VixlHelpers.cpp} (94%) rename app/src/main/cpp/{common/arm64/AsmHelpers.h => pcsx2/arm64/VixlHelpers.h} (97%) rename app/src/main/cpp/pcsx2/{ => arm64}/cpuRegistersPack.h (87%) diff --git a/app/src/main/cpp/common/CMakeLists.txt b/app/src/main/cpp/common/CMakeLists.txt index ae2b605..1d9c463 100644 --- a/app/src/main/cpp/common/CMakeLists.txt +++ b/app/src/main/cpp/common/CMakeLists.txt @@ -124,8 +124,6 @@ if(_M_X86) ) else() target_sources(common PRIVATE - arm64/AsmHelpers.cpp - arm64/AsmHelpers.h emitter/x86emitter.cpp emitter/x86emitter.h emitter/x86types.h @@ -216,7 +214,6 @@ if(NOT WIN32) endif() if(ANDROID) - target_link_libraries(common INTERFACE vixl) target_link_libraries(common PRIVATE ${LIBC_LIBRARIES} jpeg @@ -248,11 +245,7 @@ endif() fixup_file_properties(common) target_compile_features(common PUBLIC cxx_std_20) -if(ANDROID) - target_include_directories(common PUBLIC ../3rdparty/include ../3rdparty/vixl/include ../) -else() - target_include_directories(common PUBLIC ../3rdparty/include ../) -endif() +target_include_directories(common PUBLIC ../3rdparty/include ../3rdparty/vixl/include ../) target_compile_definitions(common PUBLIC "${PCSX2_DEFS}") target_compile_options(common PRIVATE "${PCSX2_WARNINGS}") diff --git a/app/src/main/cpp/common/emitter/x86emitter.cpp b/app/src/main/cpp/common/emitter/x86emitter.cpp index dd613ad..6c0084d 100644 --- a/app/src/main/cpp/common/emitter/x86emitter.cpp +++ b/app/src/main/cpp/common/emitter/x86emitter.cpp @@ -18,6 +18,7 @@ #if defined(__ANDROID__) #include "common/emitter/x86types.h" + #else #include "common/emitter/internal.h" #endif diff --git a/app/src/main/cpp/common/emitter/x86types.h b/app/src/main/cpp/common/emitter/x86types.h index cf8d0fe..310f56b 100644 --- a/app/src/main/cpp/common/emitter/x86types.h +++ b/app/src/main/cpp/common/emitter/x86types.h @@ -6,7 +6,10 @@ #include "common/Threading.h" #include "common/Assertions.h" #include "common/Pcsx2Defs.h" -#include "common/arm64/AsmHelpers.h" + +#include "vixl/aarch64/constants-aarch64.h" +#include "vixl/aarch64/macro-assembler-aarch64.h" +namespace a64 = vixl::aarch64; static const uint iREGCNT_XMM = 16; #if defined(__ANDROID__) diff --git a/app/src/main/cpp/pcsx2/CMakeLists.txt b/app/src/main/cpp/pcsx2/CMakeLists.txt index 0561aed..a7d0226 100644 --- a/app/src/main/cpp/pcsx2/CMakeLists.txt +++ b/app/src/main/cpp/pcsx2/CMakeLists.txt @@ -1056,13 +1056,13 @@ set(pcsx2x86Headers set(pcsx2arm64Sources arm64/Vif_Dynarec.cpp arm64/Vif_UnpackNEON.cpp -# arm64/AsmHelpers.cpp + arm64/VixlHelpers.cpp # arm64/RecStubs.cpp ) -#set(pcsx2arm64Headers -# arm64/AsmHelpers.h -#) +set(pcsx2arm64Headers + arm64/VixlHelpers.h +) # These ones benefit a lot from LTO set(pcsx2LTOSources diff --git a/app/src/main/cpp/pcsx2/Common.h b/app/src/main/cpp/pcsx2/Common.h index 244b534..c8032d5 100644 --- a/app/src/main/cpp/pcsx2/Common.h +++ b/app/src/main/cpp/pcsx2/Common.h @@ -3,6 +3,7 @@ #pragma once +#include "arm64/VixlHelpers.h" #include "common/Pcsx2Defs.h" static const u32 BIAS = 2; // Bus is half of the actual ps2 speed diff --git a/app/src/main/cpp/pcsx2/Pcsx2Config.cpp b/app/src/main/cpp/pcsx2/Pcsx2Config.cpp index 15d07e7..6a0a000 100644 --- a/app/src/main/cpp/pcsx2/Pcsx2Config.cpp +++ b/app/src/main/cpp/pcsx2/Pcsx2Config.cpp @@ -603,6 +603,8 @@ Pcsx2Config::CpuOptions::CpuOptions() VU0FPCR = DEFAULT_VU_FP_CONTROL_REGISTER; VU1FPCR = DEFAULT_VU_FP_CONTROL_REGISTER; ExtraMemory = false; + //// + g_cpuRegistersPack.Cpu = *this; } void Pcsx2Config::CpuOptions::ApplySanityCheck() diff --git a/app/src/main/cpp/pcsx2/R3000A.h b/app/src/main/cpp/pcsx2/R3000A.h index 85bd37d..a2783cc 100644 --- a/app/src/main/cpp/pcsx2/R3000A.h +++ b/app/src/main/cpp/pcsx2/R3000A.h @@ -3,7 +3,7 @@ #pragma once -#include "cpuRegistersPack.h" +#include "arm64/VixlHelpers.h" #ifndef _PC_ diff --git a/app/src/main/cpp/pcsx2/R5900.h b/app/src/main/cpp/pcsx2/R5900.h index de915bb..a2effc7 100644 --- a/app/src/main/cpp/pcsx2/R5900.h +++ b/app/src/main/cpp/pcsx2/R5900.h @@ -3,7 +3,7 @@ #pragma once -#include "cpuRegistersPack.h" +#include "arm64/VixlHelpers.h" #include // -------------------------------------------------------------------------------------- diff --git a/app/src/main/cpp/pcsx2/VUDef.h b/app/src/main/cpp/pcsx2/VUDef.h index b1e5f00..4e3fc11 100644 --- a/app/src/main/cpp/pcsx2/VUDef.h +++ b/app/src/main/cpp/pcsx2/VUDef.h @@ -257,6 +257,8 @@ struct mVU_SSE4 u32 g_minvals[4] = {0xff7fffff, 0xff7fffff, 0xff7fffff, 0xff7fffff}; u32 g_maxvals[4] = {0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff}; //// + u32 result[4] = { 0x3f490fda }; + //// u32 minmax_mask[8] = { 0xffffffff, 0x80000000, 0, 0, diff --git a/app/src/main/cpp/pcsx2/arm64/ShuffleLanes.h b/app/src/main/cpp/pcsx2/arm64/ShuffleLanes.h new file mode 100644 index 0000000..847deb3 --- /dev/null +++ b/app/src/main/cpp/pcsx2/arm64/ShuffleLanes.h @@ -0,0 +1,272 @@ +// +// Created by k2154 on 2025-08-20. +// + +#ifndef PCSX2_SHUFFLELANES_H +#define PCSX2_SHUFFLELANES_H + +#include + +struct ShuffleLanes +{ + __uint8_t data[256][2][16] = { + {{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},{0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},{4, 5, 6, 7, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},{8, 9, 10, 11, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},{12, 13, 14, 15, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3},{0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3},{4, 5, 6, 7, 4, 5, 6, 7, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3},{8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3},{12, 13, 14, 15, 4, 5, 6, 7, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3},{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3},{4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3},{8, 9, 10, 11, 8, 9, 10, 11, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3},{12, 13, 14, 15, 8, 9, 10, 11, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3},{0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3},{4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3},{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3},{12, 13, 14, 15, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3},{0, 1, 2, 3, 0, 1, 2, 3, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3},{4, 5, 6, 7, 0, 1, 2, 3, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3},{8, 9, 10, 11, 0, 1, 2, 3, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3},{12, 13, 14, 15, 0, 1, 2, 3, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3},{0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3},{4, 5, 6, 7, 4, 5, 6, 7, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3},{8, 9, 10, 11, 4, 5, 6, 7, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3},{12, 13, 14, 15, 4, 5, 6, 7, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},{0, 1, 2, 3, 8, 9, 10, 11, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},{4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},{8, 9, 10, 11, 8, 9, 10, 11, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3},{12, 13, 14, 15, 8, 9, 10, 11, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3},{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3},{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3},{8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3},{12, 13, 14, 15, 12, 13, 14, 15, 20, 21, 22, 23, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3},{0, 1, 2, 3, 0, 1, 2, 3, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3},{4, 5, 6, 7, 0, 1, 2, 3, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3},{8, 9, 10, 11, 0, 1, 2, 3, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3},{12, 13, 14, 15, 0, 1, 2, 3, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3},{0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3},{4, 5, 6, 7, 4, 5, 6, 7, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3},{8, 9, 10, 11, 4, 5, 6, 7, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3},{12, 13, 14, 15, 4, 5, 6, 7, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3},{0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3},{4, 5, 6, 7, 8, 9, 10, 11, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3},{8, 9, 10, 11, 8, 9, 10, 11, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3},{12, 13, 14, 15, 8, 9, 10, 11, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3},{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3},{4, 5, 6, 7, 12, 13, 14, 15, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3},{8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3},{12, 13, 14, 15, 12, 13, 14, 15, 24, 25, 26, 27, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3},{0, 1, 2, 3, 0, 1, 2, 3, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3},{4, 5, 6, 7, 0, 1, 2, 3, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3},{8, 9, 10, 11, 0, 1, 2, 3, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3},{12, 13, 14, 15, 0, 1, 2, 3, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3},{0, 1, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3},{4, 5, 6, 7, 4, 5, 6, 7, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3},{8, 9, 10, 11, 4, 5, 6, 7, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3},{12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3},{0, 1, 2, 3, 8, 9, 10, 11, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3},{4, 5, 6, 7, 8, 9, 10, 11, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3},{8, 9, 10, 11, 8, 9, 10, 11, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3},{12, 13, 14, 15, 8, 9, 10, 11, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3},{0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3},{4, 5, 6, 7, 12, 13, 14, 15, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3},{8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3},{12, 13, 14, 15, 12, 13, 14, 15, 28, 29, 30, 31, 16, 17, 18, 19}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7},{0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7},{4, 5, 6, 7, 0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7},{8, 9, 10, 11, 0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7},{12, 13, 14, 15, 0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},{0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},{4, 5, 6, 7, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},{8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},{12, 13, 14, 15, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7},{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7},{4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7},{8, 9, 10, 11, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7},{12, 13, 14, 15, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},{0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},{4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},{12, 13, 14, 15, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7},{0, 1, 2, 3, 0, 1, 2, 3, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7},{4, 5, 6, 7, 0, 1, 2, 3, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7},{8, 9, 10, 11, 0, 1, 2, 3, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7},{12, 13, 14, 15, 0, 1, 2, 3, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7},{0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7},{4, 5, 6, 7, 4, 5, 6, 7, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7},{8, 9, 10, 11, 4, 5, 6, 7, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7},{12, 13, 14, 15, 4, 5, 6, 7, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7},{0, 1, 2, 3, 8, 9, 10, 11, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7},{4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7},{8, 9, 10, 11, 8, 9, 10, 11, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7},{12, 13, 14, 15, 8, 9, 10, 11, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7},{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7},{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7},{8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7},{12, 13, 14, 15, 12, 13, 14, 15, 20, 21, 22, 23, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7},{0, 1, 2, 3, 0, 1, 2, 3, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7},{4, 5, 6, 7, 0, 1, 2, 3, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7},{8, 9, 10, 11, 0, 1, 2, 3, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7},{12, 13, 14, 15, 0, 1, 2, 3, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7},{0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7},{4, 5, 6, 7, 4, 5, 6, 7, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7},{8, 9, 10, 11, 4, 5, 6, 7, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7},{12, 13, 14, 15, 4, 5, 6, 7, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7},{0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7},{4, 5, 6, 7, 8, 9, 10, 11, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7},{8, 9, 10, 11, 8, 9, 10, 11, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7},{12, 13, 14, 15, 8, 9, 10, 11, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7},{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7},{4, 5, 6, 7, 12, 13, 14, 15, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7},{8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7},{12, 13, 14, 15, 12, 13, 14, 15, 24, 25, 26, 27, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7},{0, 1, 2, 3, 0, 1, 2, 3, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7},{4, 5, 6, 7, 0, 1, 2, 3, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7},{8, 9, 10, 11, 0, 1, 2, 3, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7},{12, 13, 14, 15, 0, 1, 2, 3, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7},{0, 1, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7},{4, 5, 6, 7, 4, 5, 6, 7, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7},{8, 9, 10, 11, 4, 5, 6, 7, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7},{12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7},{0, 1, 2, 3, 8, 9, 10, 11, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7},{4, 5, 6, 7, 8, 9, 10, 11, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7},{8, 9, 10, 11, 8, 9, 10, 11, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7},{12, 13, 14, 15, 8, 9, 10, 11, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7},{0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7},{4, 5, 6, 7, 12, 13, 14, 15, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7},{8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7},{12, 13, 14, 15, 12, 13, 14, 15, 28, 29, 30, 31, 20, 21, 22, 23}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11},{0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11},{4, 5, 6, 7, 0, 1, 2, 3, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11},{8, 9, 10, 11, 0, 1, 2, 3, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11},{12, 13, 14, 15, 0, 1, 2, 3, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11},{0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11},{4, 5, 6, 7, 4, 5, 6, 7, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11},{8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11},{12, 13, 14, 15, 4, 5, 6, 7, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11},{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11},{4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11},{8, 9, 10, 11, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11},{12, 13, 14, 15, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11},{0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11},{4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11},{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11},{12, 13, 14, 15, 12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{0, 1, 2, 3, 0, 1, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{4, 5, 6, 7, 0, 1, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{8, 9, 10, 11, 0, 1, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},{12, 13, 14, 15, 0, 1, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11},{0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11},{4, 5, 6, 7, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11},{8, 9, 10, 11, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11},{12, 13, 14, 15, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11},{0, 1, 2, 3, 8, 9, 10, 11, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11},{4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11},{8, 9, 10, 11, 8, 9, 10, 11, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11},{12, 13, 14, 15, 8, 9, 10, 11, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11},{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11},{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11},{8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11},{12, 13, 14, 15, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11},{0, 1, 2, 3, 0, 1, 2, 3, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11},{4, 5, 6, 7, 0, 1, 2, 3, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11},{8, 9, 10, 11, 0, 1, 2, 3, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11},{12, 13, 14, 15, 0, 1, 2, 3, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11},{0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11},{4, 5, 6, 7, 4, 5, 6, 7, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11},{8, 9, 10, 11, 4, 5, 6, 7, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11},{12, 13, 14, 15, 4, 5, 6, 7, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11},{0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11},{4, 5, 6, 7, 8, 9, 10, 11, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11},{8, 9, 10, 11, 8, 9, 10, 11, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11},{12, 13, 14, 15, 8, 9, 10, 11, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11},{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11},{4, 5, 6, 7, 12, 13, 14, 15, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11},{8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11},{12, 13, 14, 15, 12, 13, 14, 15, 24, 25, 26, 27, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11},{0, 1, 2, 3, 0, 1, 2, 3, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11},{4, 5, 6, 7, 0, 1, 2, 3, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11},{8, 9, 10, 11, 0, 1, 2, 3, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11},{12, 13, 14, 15, 0, 1, 2, 3, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11},{0, 1, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11},{4, 5, 6, 7, 4, 5, 6, 7, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11},{8, 9, 10, 11, 4, 5, 6, 7, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11},{12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11},{0, 1, 2, 3, 8, 9, 10, 11, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11},{4, 5, 6, 7, 8, 9, 10, 11, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11},{8, 9, 10, 11, 8, 9, 10, 11, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11},{12, 13, 14, 15, 8, 9, 10, 11, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11},{0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11},{4, 5, 6, 7, 12, 13, 14, 15, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11},{8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11},{12, 13, 14, 15, 12, 13, 14, 15, 28, 29, 30, 31, 24, 25, 26, 27}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15},{0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15},{4, 5, 6, 7, 0, 1, 2, 3, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15},{8, 9, 10, 11, 0, 1, 2, 3, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15},{12, 13, 14, 15, 0, 1, 2, 3, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15},{0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15},{4, 5, 6, 7, 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15},{8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15},{12, 13, 14, 15, 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15},{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15},{4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15},{8, 9, 10, 11, 8, 9, 10, 11, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15},{12, 13, 14, 15, 8, 9, 10, 11, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15},{0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15},{4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15},{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15},{12, 13, 14, 15, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15},{0, 1, 2, 3, 0, 1, 2, 3, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15},{4, 5, 6, 7, 0, 1, 2, 3, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15},{8, 9, 10, 11, 0, 1, 2, 3, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15},{12, 13, 14, 15, 0, 1, 2, 3, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15},{0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15},{4, 5, 6, 7, 4, 5, 6, 7, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15},{8, 9, 10, 11, 4, 5, 6, 7, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15},{12, 13, 14, 15, 4, 5, 6, 7, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15},{0, 1, 2, 3, 8, 9, 10, 11, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15},{4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15},{8, 9, 10, 11, 8, 9, 10, 11, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15},{12, 13, 14, 15, 8, 9, 10, 11, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15},{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15},{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15},{8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15},{12, 13, 14, 15, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15},{0, 1, 2, 3, 0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15},{4, 5, 6, 7, 0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15},{8, 9, 10, 11, 0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15},{12, 13, 14, 15, 0, 1, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},{0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},{4, 5, 6, 7, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},{8, 9, 10, 11, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},{12, 13, 14, 15, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15},{0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15},{4, 5, 6, 7, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15},{8, 9, 10, 11, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15},{12, 13, 14, 15, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15},{0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15},{4, 5, 6, 7, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15},{8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15},{12, 13, 14, 15, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15},{0, 1, 2, 3, 0, 1, 2, 3, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15},{4, 5, 6, 7, 0, 1, 2, 3, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15},{8, 9, 10, 11, 0, 1, 2, 3, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15},{12, 13, 14, 15, 0, 1, 2, 3, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15},{0, 1, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15},{4, 5, 6, 7, 4, 5, 6, 7, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15},{8, 9, 10, 11, 4, 5, 6, 7, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15},{12, 13, 14, 15, 4, 5, 6, 7, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15},{0, 1, 2, 3, 8, 9, 10, 11, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15},{4, 5, 6, 7, 8, 9, 10, 11, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15},{8, 9, 10, 11, 8, 9, 10, 11, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15},{12, 13, 14, 15, 8, 9, 10, 11, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{0, 1, 2, 3, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15},{0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{4, 5, 6, 7, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15},{4, 5, 6, 7, 12, 13, 14, 15, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15},{8, 9, 10, 11, 12, 13, 14, 15, 28, 29, 30, 31, 28, 29, 30, 31}}, + {{12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15},{12, 13, 14, 15, 12, 13, 14, 15, 28, 29, 30, 31, 28, 29, 30, 31}} + }; +}; + +#endif //PCSX2_SHUFFLELANES_H diff --git a/app/src/main/cpp/pcsx2/arm64/Vif_UnpackNEON.h b/app/src/main/cpp/pcsx2/arm64/Vif_UnpackNEON.h index 43c77d2..0ff47c8 100644 --- a/app/src/main/cpp/pcsx2/arm64/Vif_UnpackNEON.h +++ b/app/src/main/cpp/pcsx2/arm64/Vif_UnpackNEON.h @@ -6,7 +6,7 @@ #include "Common.h" #include "Vif_Dma.h" #include "Vif_Dynarec.h" -#include "common/arm64/AsmHelpers.h" +#include "VixlHelpers.h" #define xmmCol0 vixl::aarch64::q2 #define xmmCol1 vixl::aarch64::q3 diff --git a/app/src/main/cpp/common/arm64/AsmHelpers.cpp b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.cpp similarity index 94% rename from app/src/main/cpp/common/arm64/AsmHelpers.cpp rename to app/src/main/cpp/pcsx2/arm64/VixlHelpers.cpp index c756f23..1798667 100644 --- a/app/src/main/cpp/common/arm64/AsmHelpers.cpp +++ b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team // SPDX-License-Identifier: GPL-3.0 -#include "common/arm64/AsmHelpers.h" +#include "VixlHelpers.h" #include "common/Assertions.h" #include "common/BitUtils.h" @@ -160,7 +160,8 @@ void armEmitJmp(const void* ptr, bool force_inline) if (use_blr) { - armAsm->Mov(RXVIXLSCRATCH, reinterpret_cast(ptr)); + armAsm->Mov(RXVIXLSCRATCH, (uptr)ptr); +// armAsm->Ldr(RXVIXLSCRATCH, (uptr)ptr); armAsm->Br(RXVIXLSCRATCH); } else @@ -185,7 +186,8 @@ void armEmitCall(const void* ptr, bool force_inline) if (use_blr) { - armAsm->Mov(RXVIXLSCRATCH, reinterpret_cast(ptr)); + armAsm->Mov(RXVIXLSCRATCH, (uptr)ptr); +// armAsm->Ldr(RXVIXLSCRATCH, (uptr)ptr); armAsm->Blr(RXVIXLSCRATCH); } else @@ -275,6 +277,16 @@ void armMoveAddressToReg(const a64::Register& reg, const void* addr) } } +void armCbz(const a64::Register& reg, a64::Label* p_label) +{ + armAsm->Cbz(reg, p_label); +} + +void armCbnz(const a64::Register& reg, a64::Label* p_label) +{ + armAsm->Cbnz(reg, p_label); +} + void armLoadPtr(const a64::CPURegister& reg, const void* addr) { armMoveAddressToReg(RSCRATCHADDR, addr); @@ -997,67 +1009,17 @@ void armPMOVMSKB(const a64::Register& regDst, const a64::VRegister& regSrc) void armSHUFPS(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex) { - armShuffle(dstreg, srcreg, pIndex, true); + armAsm->Mov(RQSCRATCH3, armLoadPtrV(PTR_CPU(shuffle.data[pIndex][1])).Q()); + //// + armAsm->Mov(RQSCRATCH2, srcreg); + armAsm->Mov(RQSCRATCH, dstreg); + armAsm->Tbx(dstreg.V16B(), RQSCRATCH.V16B(), RQSCRATCH2.V16B(), RQSCRATCH3.V16B()); } void armPSHUFD(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex) { - armShuffle(dstreg, srcreg, pIndex, false); -} - -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) -{ - uint8_t lanes[16]; - int i, s, e, nIndex = 0; - - int lanesTbx = 0; - if(p_is_tbx) { - lanesTbx = 16; - } - - // 0, 4, 8, 12 - // 0 * 4 = 0, 1 * 4 = 4, 2 * 4 = 8, 3 * 4 = 12 - // lanes 16 => 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 - - s = p_a << 2; e = s + 4; - for(i=s; iMov(RQSCRATCH, p_dst); - armAsm->Mov(RQSCRATCH2, p_src); - armAsm->Tbx(p_dst.V16B(), RQSCRATCH.V16B(), RQSCRATCH2.V16B(), RQSCRATCH3.V16B()); - } else { - armAsm->Tbl(p_dst.V16B(), p_src.V16B(), RQSCRATCH3.V16B()); - } -} - -void armShuffle(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex, bool p_is_tbx) -{ - int shuffle_0 = (pIndex >> 0) & 0x3; - int shuffle_1 = (pIndex >> 2) & 0x3; - int shuffle_2 = (pIndex >> 4) & 0x3; - int shuffle_3 = (pIndex >> 6) & 0x3; - //// - armShuffleTblx(dstreg, srcreg, shuffle_0, shuffle_1, shuffle_2, shuffle_3, p_is_tbx); + armAsm->Mov(RQSCRATCH3, armLoadPtrV(PTR_CPU(shuffle.data[pIndex][0])).Q()); + armAsm->Tbl(dstreg.V16B(), srcreg.V16B(), RQSCRATCH3.V16B()); } int find_bit_pos(uint32_t p_hex_value) diff --git a/app/src/main/cpp/common/arm64/AsmHelpers.h b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h similarity index 97% rename from app/src/main/cpp/common/arm64/AsmHelpers.h rename to app/src/main/cpp/pcsx2/arm64/VixlHelpers.h index d027345..baa5d6d 100644 --- a/app/src/main/cpp/common/arm64/AsmHelpers.h +++ b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h @@ -3,14 +3,14 @@ #pragma once +#include #include "common/Pcsx2Defs.h" #include "common/HashCombine.h" +#include "cpuRegistersPack.h" #include "vixl/aarch64/constants-aarch64.h" #include "vixl/aarch64/macro-assembler-aarch64.h" -#include - namespace a64 = vixl::aarch64; #define RWARG1 a64::w0 @@ -72,6 +72,9 @@ namespace a64 = vixl::aarch64; // iopMem->Main #define RSTATE_x29 a64::x29 +// eeHw[Ps2MemSize::Hardware] +#define psHu(mem) (mem & 0xffff) + static inline s64 GetPCDisplacement(const void* current, const void* target) { return static_cast((reinterpret_cast(target) - reinterpret_cast(current)) >> 2); @@ -118,6 +121,8 @@ void armEmitCall(const void* ptr, bool force_inline = false); void armEmitCbnz(const a64::Register& reg, const void* ptr); void armEmitCondBranch(a64::Condition cond, const void* ptr); void armMoveAddressToReg(const a64::Register& reg, const void* addr); +void armCbz(const a64::Register& reg, a64::Label* p_label); +void armCbnz(const a64::Register& reg, a64::Label* p_label); void armLoadPtr(const a64::CPURegister& reg, const void* addr); void armStorePtr(const a64::CPURegister& reg, const void* addr); void armBeginStackFrame(bool save_fpr=true); @@ -252,7 +257,6 @@ void armPMOVMSKB(const a64::Register& regDst, const a64::VRegister& regSrc); void armSHUFPS(const a64::VRegister& dstreg, const a64::VRegister& srcreg, int pIndex); 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); +void armShuffleTblx(const a64::VRegister& p_dst, const a64::VRegister& p_src, int pIndex, bool p_is_tbx); int find_bit_pos(uint32_t p_hex_value); diff --git a/app/src/main/cpp/pcsx2/cpuRegistersPack.h b/app/src/main/cpp/pcsx2/arm64/cpuRegistersPack.h similarity index 87% rename from app/src/main/cpp/pcsx2/cpuRegistersPack.h rename to app/src/main/cpp/pcsx2/arm64/cpuRegistersPack.h index d4450a3..7c0c4a4 100644 --- a/app/src/main/cpp/pcsx2/cpuRegistersPack.h +++ b/app/src/main/cpp/pcsx2/arm64/cpuRegistersPack.h @@ -5,10 +5,12 @@ #ifndef PCSX2_CPUREGISTERSPACK_H #define PCSX2_CPUREGISTERSPACK_H +#include "Config.h" #include "R5900Def.h" #include "R3000ADef.h" #include "VUDef.h" #include "vtlbDef.h" +#include "arm64/ShuffleLanes.h" struct cpuRegistersPack { @@ -17,6 +19,8 @@ struct cpuRegistersPack alignas(16) psxRegisters psxRegs{}; alignas(16) VIFregisters vifRegs[2]{}; alignas(16) VURegs vuRegs[2]; + alignas(16) ShuffleLanes shuffle; + alignas(16) Pcsx2Config::CpuOptions Cpu; alignas(16) mVU_SSE4 mVUss4; alignas(32) mVU_Globals mVUglob; alignas(64) vtlb_private::MapData vtlbdata; diff --git a/app/src/main/cpp/pcsx2/vtlbDef.h b/app/src/main/cpp/pcsx2/vtlbDef.h index 5bd75a3..0eeb71c 100644 --- a/app/src/main/cpp/pcsx2/vtlbDef.h +++ b/app/src/main/cpp/pcsx2/vtlbDef.h @@ -77,7 +77,7 @@ namespace vtlb_private struct VTLBVirtual { - public: + private: uptr value; explicit VTLBVirtual(uptr value): value(value) { } public: diff --git a/app/src/main/cpp/pcsx2/x86/BaseblockEx.h b/app/src/main/cpp/pcsx2/x86/BaseblockEx.h index 396a4de..002ae6f 100644 --- a/app/src/main/cpp/pcsx2/x86/BaseblockEx.h +++ b/app/src/main/cpp/pcsx2/x86/BaseblockEx.h @@ -7,7 +7,7 @@ #include #include "common/Assertions.h" -#include "common/arm64/AsmHelpers.h" +#include "arm64/VixlHelpers.h" // Every potential jump point in the PS2's addressable memory has a BASEBLOCK // associated with it. So that means a BASEBLOCK for every 4 bytes of PS2 diff --git a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp index 525d12a..0f5b532 100644 --- a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp +++ b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp @@ -42,13 +42,15 @@ static void _setupBranchTest() // everything except the lower 10 bits away. // xMOV(eax, ptr[(&psHu32(DMAC_PCR))]); - armAsm->Ldr(EAX, armMemOperandPtr(&psHu32(DMAC_PCR))); + armAsm->Ldr(RXVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(DMAC_PCR))); + armAsm->Uxtw(EAX, RXVIXLSCRATCH); // xMOV(ecx, 0x3ff); // ECX is our 10-bit mask var armAsm->Mov(ECX, 0x3ff); // xNOT(eax); armAsm->Mvn(EAX, EAX); // xOR(eax, ptr[(&psHu32(DMAC_STAT))]); - armAsm->Orr(EAX, EAX, armLoadPtr((&psHu32(DMAC_STAT)))); + armAsm->Ldr(RXVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(DMAC_STAT))); + armAsm->Orr(EAX, EAX, a64::Operand(RXVIXLSCRATCH, a64::Extend::UXTW)); // xAND(eax, ecx); armAsm->And(EAX, EAX, ECX); // xCMP(eax, ecx); diff --git a/app/src/main/cpp/pcsx2/x86/iFPU.cpp b/app/src/main/cpp/pcsx2/x86/iFPU.cpp index 686d22c..bf2a132 100644 --- a/app/src/main/cpp/pcsx2/x86/iFPU.cpp +++ b/app/src/main/cpp/pcsx2/x86/iFPU.cpp @@ -651,7 +651,7 @@ void FPU_MUL(int regd, int regt, bool reverseOperands) // else // return 0; - alignas(16) static constexpr const u32 result[4] = { 0x3f490fda }; +// alignas(16) static constexpr const u32 result[4] = { 0x3f490fda }; // xMOVD(ecx, xRegisterSSE(reverseOperands ? regt : regd)); armAsm->Fmov(ECX, reverseOperands ? regT.S() : regD.S()); @@ -668,9 +668,9 @@ void FPU_MUL(int regd, int regt, bool reverseOperands) // u8* noHack = JNZ8(0); a64::Label noHack; - armAsm->Cbnz(EDX, &noHack); + armCbnz(EDX, &noHack); // xMOVAPS(xRegisterSSE(regd), ptr128[result]); - armAsm->Ldr(regD.Q(), armMemOperandPtr(result)); + armAsm->Ldr(regD.Q(), PTR_CPU(mVUss4.result)); // endMul = JMP8(0); armAsm->B(&endMul); // x86SetJ8(noHack); @@ -1414,7 +1414,7 @@ void recDIV_S_xmm(int info) if (EmuConfig.Cpu.FPUFPCR.bitmask != EmuConfig.Cpu.FPUDivFPCR.bitmask) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUDivFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUDivFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUDivFPCR.bitmask))); } switch (info & (PROCESS_EE_S | PROCESS_EE_T)) @@ -1491,7 +1491,7 @@ void recDIV_S_xmm(int info) if (EmuConfig.Cpu.FPUFPCR.bitmask != EmuConfig.Cpu.FPUDivFPCR.bitmask) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); } _freeXMMreg(t0reg); @@ -2213,7 +2213,7 @@ void recSQRT_S_xmm(int info) roundmode_nearest = EmuConfig.Cpu.FPUFPCR; roundmode_nearest.SetRoundMode(FPRoundMode::Nearest); // xLDMXCSR(ptr32[&roundmode_nearest.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&roundmode_nearest.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); roundmodeFlag = true; } @@ -2262,7 +2262,7 @@ void recSQRT_S_xmm(int info) if (roundmodeFlag) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); } } diff --git a/app/src/main/cpp/pcsx2/x86/iFPUd.cpp b/app/src/main/cpp/pcsx2/x86/iFPUd.cpp index da32857..0506f5f 100644 --- a/app/src/main/cpp/pcsx2/x86/iFPUd.cpp +++ b/app/src/main/cpp/pcsx2/x86/iFPUd.cpp @@ -545,7 +545,7 @@ void FPU_MUL(int info, int regd, int sreg, int treg, bool acc) // else // return 0; - alignas(16) static constexpr const u32 result[4] = { 0x3f490fda }; +// alignas(16) static constexpr const u32 result[4] = { 0x3f490fda }; // xMOVD(ecx, xRegisterSSE(sreg)); armAsm->Fmov(ECX, regS.S()); @@ -562,9 +562,9 @@ void FPU_MUL(int info, int regd, int sreg, int treg, bool acc) // u8* noHack = JNZ8(0); a64::Label noHack; - armAsm->Cbnz(EDX, &noHack); + armCbnz(EDX, &noHack); // xMOVAPS(xRegisterSSE(regd), ptr128[result]); - armAsm->Ldr(regD.Q(), armMemOperandPtr(result)); + armAsm->Ldr(regD.Q(), PTR_CPU(mVUss4.result)); // endMul = JMP32(0); armAsm->B(&endMul); // x86SetJ8(noHack); @@ -835,7 +835,7 @@ void recDIV_S_xmm(int info) if (EmuConfig.Cpu.FPUFPCR.bitmask != EmuConfig.Cpu.FPUDivFPCR.bitmask) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUDivFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUDivFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUDivFPCR.bitmask))); } int sreg, treg; @@ -852,7 +852,7 @@ void recDIV_S_xmm(int info) if (EmuConfig.Cpu.FPUFPCR.bitmask != EmuConfig.Cpu.FPUDivFPCR.bitmask) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); } _freeXMMreg(sreg); _freeXMMreg(treg); @@ -1160,7 +1160,7 @@ void recSQRT_S_xmm(int info) roundmode_nearest = EmuConfig.Cpu.FPUFPCR; roundmode_nearest.SetRoundMode(FPRoundMode::Nearest); // xLDMXCSR(ptr32[&roundmode_nearest.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&roundmode_nearest.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); roundmodeFlag = 1; } @@ -1204,7 +1204,7 @@ void recSQRT_S_xmm(int info) if (roundmodeFlag == 1) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); } _freeXMMreg(t1reg); @@ -1338,7 +1338,7 @@ void recRSQRT_S_xmm(int info) roundmode_nearest = EmuConfig.Cpu.FPUFPCR; roundmode_nearest.SetRoundMode(FPRoundMode::Nearest); // xLDMXCSR(ptr32[&roundmode_nearest.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&roundmode_nearest.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); roundmodeFlag = true; } @@ -1356,7 +1356,7 @@ void recRSQRT_S_xmm(int info) if (roundmodeFlag) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); } } diff --git a/app/src/main/cpp/pcsx2/x86/iR3000A.cpp b/app/src/main/cpp/pcsx2/x86/iR3000A.cpp index cf5ad62..25130d7 100644 --- a/app/src/main/cpp/pcsx2/x86/iR3000A.cpp +++ b/app/src/main/cpp/pcsx2/x86/iR3000A.cpp @@ -47,7 +47,7 @@ extern void psxBREAK(); u32 g_psxMaxRecMem = 0; -uptr psxRecLUT[0x10000]; +alignas(16) uptr psxRecLUT[0x10000]; u32 psxhwLUT[0x10000]; static __fi u32 HWADDR(u32 mem) { return psxhwLUT[mem >> 16] + mem; } @@ -183,9 +183,10 @@ static const void* _DynGen_JITCompile() // xJMP(ptrNative[rbx * (wordsize / 4) + rcx]); armLoad(EAX, PTR_CPU(psxRegs.pc)); - armMoveAddressToReg(RDX, &psxRecLUT); armAsm->Lsr(ECX, EAX, 16); armAsm->Lsr(EAX, EAX, 2); +// armMoveAddressToReg(RDX, &psxRecLUT); + armAsm->Mov(RDX, (uptr)&psxRecLUT); armAsm->Ldr(RCX, a64::MemOperand(RDX, RCX, a64::LSL, 3)); //// armAsm->Ldr(RAX, a64::MemOperand(RCX, RAX, a64::LSL, 3)); @@ -207,9 +208,10 @@ static const void* _DynGen_DispatcherReg() // xJMP(ptrNative[rbx * (wordsize / 4) + rcx]); armLoad(EAX, PTR_CPU(psxRegs.pc)); - armMoveAddressToReg(RDX, &psxRecLUT); armAsm->Lsr(ECX, EAX, 16); armAsm->Lsr(EAX, EAX, 2); +// armMoveAddressToReg(RDX, &psxRecLUT); + armAsm->Mov(RDX, (uptr)&psxRecLUT); armAsm->Ldr(RCX, a64::MemOperand(RDX, RCX, a64::LSL, 3)); //// armAsm->Ldr(RAX, a64::MemOperand(RCX, RAX, a64::LSL, 3)); @@ -237,8 +239,8 @@ static const void* _DynGen_EnterRecompiledCode() // xScopedStackFrame frame(false, true); armBeginStackFrame(); #endif - armMoveAddressToReg(RSTATE_x29, iopMem->Main); +// armAsm->Mov(RSTATE_CPU, (uptr)&g_cpuRegistersPack); // xJMP((void*)iopDispatcherReg); armEmitJmp(iopDispatcherReg); diff --git a/app/src/main/cpp/pcsx2/x86/iR3000A.h b/app/src/main/cpp/pcsx2/x86/iR3000A.h index 627ab95..ea146a3 100644 --- a/app/src/main/cpp/pcsx2/x86/iR3000A.h +++ b/app/src/main/cpp/pcsx2/x86/iR3000A.h @@ -20,7 +20,7 @@ static const int psxInstCycles_Load = 0; #define PSX_HI XMMGPR_HI #define PSX_LO XMMGPR_LO -extern uptr psxRecLUT[]; +alignas(16) extern uptr psxRecLUT[]; void _psxFlushConstReg(int reg); void _psxFlushConstRegs(); diff --git a/app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp b/app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp index e7a1fef..f8b9791 100644 --- a/app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp +++ b/app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp @@ -1171,7 +1171,7 @@ static void rpsxDIVsuper(int info, int sign, int process = 0) // xCMP(ecx, 0); // u8* cont3 = JNE8(0); a64::Label cont3; - armAsm->Cbnz(ECX, &cont3); + armCbnz(ECX, &cont3); //divide by zero // xMOV(edx, eax); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp index eed1dad..f2331ac 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp @@ -412,9 +412,10 @@ static const void* _DynGen_JITCompile() // xJMP(ptrNative[rbx * (wordsize / 4) + rcx]); armLoad(EAX, PTR_CPU(cpuRegs.pc)); - armMoveAddressToReg(RDX, &recLUT); armAsm->Lsr(ECX, EAX, 16); armAsm->Lsr(EAX, EAX, 2); +// armMoveAddressToReg(RDX, &recLUT); + armAsm->Mov(RDX, (uptr)&recLUT); armAsm->Ldr(RCX, a64::MemOperand(RDX, RCX, a64::LSL, 3)); //// armAsm->Ldr(RAX, a64::MemOperand(RCX, RAX, a64::LSL, 3)); @@ -440,9 +441,10 @@ static const void* _DynGen_DispatcherReg() // xJMP(ptrNative[rbx * (wordsize / 4) + rcx]); armLoad(EAX, PTR_CPU(cpuRegs.pc)); - armMoveAddressToReg(RDX, &recLUT); armAsm->Lsr(ECX, EAX, 16); armAsm->Lsr(EAX, EAX, 2); +// armMoveAddressToReg(RDX, &recLUT); + armAsm->Mov(RDX, (uptr)&recLUT); armAsm->Ldr(RCX, a64::MemOperand(RDX, RCX, a64::LSL, 3)); //// armAsm->Ldr(RAX, a64::MemOperand(RCX, RAX, a64::LSL, 3)); @@ -490,6 +492,7 @@ static const void* _DynGen_EnterRecompiledCode() // From memory to registry armMoveAddressToReg(RSTATE_PSX, &psxRegs); armMoveAddressToReg(RSTATE_CPU, &g_cpuRegistersPack); + armMoveAddressToReg(RSTATE_x26, &eeHw); if (CHECK_FASTMEM) { // xMOV(RFASTMEMBASE, ptrNative[&vtlb_private::vtlbdata.fastmem_base]); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900MultDiv.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900MultDiv.cpp index 13e713d..d7c5cd6 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900MultDiv.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900MultDiv.cpp @@ -462,7 +462,7 @@ static void recDIVsuper(int info, bool sign, bool upper, int process) // xCMP(divisor, 0); // u8* cont3 = JNE8(0); a64::Label cont3; - armAsm->Cbnz(divisor, &cont3); + armCbnz(divisor, &cont3); //divide by zero // xMOV(edx, eax); armAsm->Mov(EDX, EAX); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp index f2315e1..88650ad 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp @@ -283,7 +283,6 @@ static u8* GetIndirectDispatcherPtr(int mode, int operandsize, int sign = 0) // Generates a JS instruction that targets the appropriate templated instance of // the vtlb Indirect Dispatcher. // - template static void DynGen_HandlerTest(const GenDirectFn& gen_direct, int mode, int bits, bool sign = false) { @@ -326,6 +325,7 @@ static void DynGen_IndirectTlbDispatcher(int mode, int bits, bool sign) #else // xSUB(rsp, 8); // armAsm->Sub(a64::sp, a64::sp, 48); + armAsm->Push(a64::xzr, a64::lr); #endif // xMOVZX(eax, al); @@ -337,20 +337,17 @@ static void DynGen_IndirectTlbDispatcher(int mode, int bits, bool sign) // xSUB(arg1regd, eax); armAsm->Sub(ECX, ECX, EEX); + armAsm->Mov(RAX, RCX); // ecx is address + armAsm->Mov(RCX, RDX); // edx is data + // jump to the indirect handler, which is a C++ function. // [ecx is address, edx is data] // sptr table = (sptr)vtlbdata.RWFT[bits][mode]; // xFastCall(ptrNative[(rax * wordsize) + table], arg1reg, arg2reg); - armAsm->Mov(RXVIXLSCRATCH, reinterpret_cast(vtlbdata.RWFT[bits][mode])); + armAsm->Mov(RXVIXLSCRATCH, (sptr)vtlbdata.RWFT[bits][mode]); armAsm->Ldr(REX, a64::MemOperand(RXVIXLSCRATCH, REX, a64::LSL, 3)); - - armAsm->Mov(RAX, RCX); - armAsm->Mov(RCX, RDX); - - armAsm->Push(a64::xzr, a64::lr); armAsm->Blr(REX); - armAsm->Pop(a64::lr, a64::xzr); if (!mode) { @@ -390,6 +387,7 @@ static void DynGen_IndirectTlbDispatcher(int mode, int bits, bool sign) #else // xADD(rsp, 8); // armAsm->Add(a64::sp, a64::sp, 48); + armAsm->Pop(a64::lr, a64::xzr); #endif // xRET(); @@ -604,23 +602,28 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const, // Shortcut for the INTC_STAT register, which many games like to spin on heavily. if ((bits == 32) && !EmuConfig.Speedhacks.IntcStat && (paddr == INTC_STAT)) { +// armAsm->Ldr(RXVIXLSCRATCH, (uptr)&psHu32(INTC_STAT)); +// auto mop = a64::MemOperand(RXVIXLSCRATCH); + auto mop = armMemOperandPtr(&psHu32(INTC_STAT)); + // x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(eax), eax.GetId()); x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(EAX), EAX.GetCode()); if (!xmm) { + auto regX = a64::XRegister(x86_dest_reg); if (sign) { // xMOVSX(xRegister64(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Ldrsw(a64::XRegister(x86_dest_reg), armMemOperandPtr(&psHu32(INTC_STAT))); + armAsm->Ldrsw(regX, mop); } else { // xMOV(xRegister32(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Ldr(a64::WRegister(x86_dest_reg), armMemOperandPtr(&psHu32(INTC_STAT))); + armAsm->Ldr(regX.W(), mop); } } else { // xMOVDZX(xRegisterSSE(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Ldr(a64::QRegister(x86_dest_reg).S(), armMemOperandPtr(&psHu32(INTC_STAT))); + armAsm->Ldr(a64::QRegister(x86_dest_reg).S(), mop); } } else diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl index 43476ec..24710df 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl @@ -44,9 +44,7 @@ void mVUdispatcherAB(mV) // Load VU's MXCSR state if (mvuNeedsFPCRUpdate(mVU)) { // xLDMXCSR(ptr32[isVU0 ? &EmuConfig.Cpu.VU0FPCR.bitmask : &EmuConfig.Cpu.VU1FPCR.bitmask]); - armAsm->Msr(a64::FPCR, isVU0 - ? armLoadPtr64(&EmuConfig.Cpu.VU0FPCR.bitmask) - : armLoadPtr64(&EmuConfig.Cpu.VU1FPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(isVU0 ? PTR_CPU(Cpu.VU0FPCR.bitmask) : PTR_CPU(Cpu.VU1FPCR.bitmask))); } // Load Regs @@ -107,7 +105,7 @@ void mVUdispatcherAB(mV) // Load EE's MXCSR state if (mvuNeedsFPCRUpdate(mVU)) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); } // = The first two DWORD or smaller arguments are passed in ECX and EDX registers; @@ -144,9 +142,7 @@ void mVUdispatcherCD(mV) // Load VU's MXCSR state if (mvuNeedsFPCRUpdate(mVU)) { // xLDMXCSR(ptr32[isVU0 ? &EmuConfig.Cpu.VU0FPCR.bitmask : &EmuConfig.Cpu.VU1FPCR.bitmask]); - armAsm->Msr(a64::FPCR, isVU0 - ? armLoadPtr64(&EmuConfig.Cpu.VU0FPCR.bitmask) - : armLoadPtr64(&EmuConfig.Cpu.VU1FPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(isVU0 ? PTR_CPU(Cpu.VU0FPCR.bitmask) : PTR_CPU(Cpu.VU1FPCR.bitmask))); } mVUrestoreRegs(mVU); @@ -178,7 +174,7 @@ void mVUdispatcherCD(mV) // Load EE's MXCSR state if (mvuNeedsFPCRUpdate(mVU)) { // xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); - armAsm->Msr(a64::FPCR, armLoadPtr64(&EmuConfig.Cpu.FPUFPCR.bitmask)); + armAsm->Msr(a64::FPCR, armLoad64(PTR_CPU(Cpu.FPUFPCR.bitmask))); } armEndStackFrame(); @@ -222,7 +218,7 @@ static void mVUGenerateWaitMTVU(mV) //// // xFastCall((void*)mVUwaitMTVU); armAsm->Push(a64::xzr, a64::lr); - armAsm->Mov(RXVIXLSCRATCH, reinterpret_cast(mVUwaitMTVU)); + armAsm->Ldr(RXVIXLSCRATCH, (uptr)mVUwaitMTVU); armAsm->Blr(RXVIXLSCRATCH); armAsm->Pop(a64::lr, a64::xzr); //// @@ -325,7 +321,7 @@ static void mVUGenerateCompareState(mV) // xForwardJNZ8 exitPoint; a64::Label exitPoint; - armAsm->Cbnz(EAX, &exitPoint); + armCbnz(EAX, &exitPoint); // xMOVAPS (xmm0, ptr32[arg1reg + 0x20]); armAsm->Ldr(xmm0, a64::MemOperand(RCX, 0x20)); From ef4fe46def24369fff5e2a116cf5a897b00d32bc Mon Sep 17 00:00:00 2001 From: k2154 Date: Thu, 21 Aug 2025 00:18:25 +0900 Subject: [PATCH 09/12] Android project - Modify iCOP0.cpp, recVTLB.cpp code --- app/src/main/cpp/pcsx2/x86/iCOP0.cpp | 8 ++--- .../main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp | 31 +++++++++---------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp index 0f5b532..233982a 100644 --- a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp +++ b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp @@ -42,15 +42,15 @@ static void _setupBranchTest() // everything except the lower 10 bits away. // xMOV(eax, ptr[(&psHu32(DMAC_PCR))]); - armAsm->Ldr(RXVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(DMAC_PCR))); - armAsm->Uxtw(EAX, RXVIXLSCRATCH); + armAsm->Ldr(RWVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(DMAC_PCR))); + armAsm->Uxtw(EAX, RWVIXLSCRATCH); // xMOV(ecx, 0x3ff); // ECX is our 10-bit mask var armAsm->Mov(ECX, 0x3ff); // xNOT(eax); armAsm->Mvn(EAX, EAX); // xOR(eax, ptr[(&psHu32(DMAC_STAT))]); - armAsm->Ldr(RXVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(DMAC_STAT))); - armAsm->Orr(EAX, EAX, a64::Operand(RXVIXLSCRATCH, a64::Extend::UXTW)); + armAsm->Ldr(RWVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(DMAC_STAT))); + armAsm->Orr(EAX, EAX, a64::Operand(RWVIXLSCRATCH, a64::Extend::UXTW)); // xAND(eax, ecx); armAsm->And(EAX, EAX, ECX); // xCMP(eax, ecx); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp index 88650ad..6834f62 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp @@ -166,7 +166,6 @@ namespace vtlb_private // xSHR(eax, VTLB_PAGE_BITS); armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS); // xMOV(rax, ptrNative[xComplexAddress(arg3reg, vtlbdata.vmap, rax * wordsize)]); -// armMoveAddressToReg(RXVIXLSCRATCH, vtlbdata.vmap); armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.vmap)); armAsm->Ldr(RAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 3)); // xADD(arg1reg, rax); @@ -324,7 +323,6 @@ static void DynGen_IndirectTlbDispatcher(int mode, int bits, bool sign) xSUB(rsp, 32 + 8); #else // xSUB(rsp, 8); -// armAsm->Sub(a64::sp, a64::sp, 48); armAsm->Push(a64::xzr, a64::lr); #endif @@ -386,7 +384,6 @@ static void DynGen_IndirectTlbDispatcher(int mode, int bits, bool sign) xADD(rsp, 32 + 8); #else // xADD(rsp, 8); -// armAsm->Add(a64::sp, a64::sp, 48); armAsm->Pop(a64::lr, a64::xzr); #endif @@ -470,7 +467,8 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea const u8* codeStart; // const xAddressReg x86addr(addr_reg); - a64::MemOperand x86addr = a64::MemOperand(RFASTMEMBASE, a64::XRegister(addr_reg)); + const a64::XRegister x86addr(addr_reg); + auto mop = a64::MemOperand(RFASTMEMBASE, x86addr); if (!xmm) { @@ -485,19 +483,19 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea { case 8: // sign ? xMOVSX(x86reg, ptr8[RFASTMEMBASE + x86addr]) : xMOVZX(xRegister32(x86reg), ptr8[RFASTMEMBASE + x86addr]); - sign ? armAsm->Ldrsb(x86reg, x86addr) : armAsm->Ldrb(x86reg.W(), x86addr); + sign ? armAsm->Ldrsb(x86reg, mop) : armAsm->Ldrb(x86reg.W(), mop); break; case 16: // sign ? xMOVSX(x86reg, ptr16[RFASTMEMBASE + x86addr]) : xMOVZX(xRegister32(x86reg), ptr16[RFASTMEMBASE + x86addr]); - sign ? armAsm->Ldrsh(x86reg, x86addr) : armAsm->Ldrh(x86reg.W(), x86addr); + sign ? armAsm->Ldrsh(x86reg, mop) : armAsm->Ldrh(x86reg.W(), mop); break; case 32: // sign ? xMOVSX(x86reg, ptr32[RFASTMEMBASE + x86addr]) : xMOV(xRegister32(x86reg), ptr32[RFASTMEMBASE + x86addr]); - sign ? armAsm->Ldrsw(x86reg, x86addr) : armAsm->Ldr(x86reg.W(), x86addr); + sign ? armAsm->Ldrsw(x86reg, mop) : armAsm->Ldr(x86reg.W(), mop); break; case 64: // xMOV(x86reg, ptr64[RFASTMEMBASE + x86addr]); - armAsm->Ldr(x86reg, x86addr); + armAsm->Ldr(x86reg, mop); break; jNO_DEFAULT @@ -512,7 +510,7 @@ int vtlb_DynGenReadNonQuad(u32 bits, bool sign, bool xmm, int addr_reg, vtlb_Rea // const xRegisterSSE xmmreg(x86_dest_reg); const a64::QRegister xmmreg(x86_dest_reg); // xMOVSSZX(xmmreg, ptr32[RFASTMEMBASE + x86addr]); - armAsm->Ldr(xmmreg.S(), x86addr); + armAsm->Ldr(xmmreg.S(), mop); } // vtlb_AddLoadStoreInfo((uptr)codeStart, static_cast(x86Ptr - codeStart), @@ -602,9 +600,7 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const, // Shortcut for the INTC_STAT register, which many games like to spin on heavily. if ((bits == 32) && !EmuConfig.Speedhacks.IntcStat && (paddr == INTC_STAT)) { -// armAsm->Ldr(RXVIXLSCRATCH, (uptr)&psHu32(INTC_STAT)); -// auto mop = a64::MemOperand(RXVIXLSCRATCH); - auto mop = armMemOperandPtr(&psHu32(INTC_STAT)); + armAsm->Ldr(RWVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(INTC_STAT))); // x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(eax), eax.GetId()); x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(EAX), EAX.GetCode()); @@ -613,17 +609,18 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const, auto regX = a64::XRegister(x86_dest_reg); if (sign) { // xMOVSX(xRegister64(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Ldrsw(regX, mop); + armAsm->Sxtw(regX, RWVIXLSCRATCH); } else { // xMOV(xRegister32(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Ldr(regX.W(), mop); + armAsm->Uxtw(regX.W(), RWVIXLSCRATCH); } } else { // xMOVDZX(xRegisterSSE(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Ldr(a64::QRegister(x86_dest_reg).S(), mop); + armAsm->Uxtw(RWVIXLSCRATCH, RWVIXLSCRATCH); + armAsm->Fmov(a64::QRegister(x86_dest_reg).S(), RWVIXLSCRATCH); } } else @@ -831,7 +828,8 @@ void vtlb_DynGenWrite(u32 sz, bool xmm, int addr_reg, int value_reg) const u8* codeStart = armGetCurrentCodePointer(); // const xAddressReg vaddr_reg(addr_reg); - const a64::MemOperand mop = a64::MemOperand(RFASTMEMBASE, a64::XRegister(addr_reg)); + const a64::XRegister vaddr_reg(addr_reg); + auto mop = a64::MemOperand(RFASTMEMBASE, vaddr_reg); if (!xmm) { @@ -1090,7 +1088,6 @@ void vtlb_DynV2P() // xSHR(eax, VTLB_PAGE_BITS); armAsm->Lsr(EAX, EAX, VTLB_PAGE_BITS); // xMOV(eax, ptr[xComplexAddress(rdx, vtlbdata.ppmap, rax * 4)]); -// armMoveAddressToReg(RDX, vtlbdata.ppmap); armAsm->Ldr(RXVIXLSCRATCH, PTR_CPU(vtlbdata.ppmap)); armAsm->Ldr(EAX, a64::MemOperand(RXVIXLSCRATCH, RAX, a64::LSL, 2)); From 92860d99994f3e3bd75fae22d5f6f2e134e387e5 Mon Sep 17 00:00:00 2001 From: k2154 Date: Thu, 21 Aug 2025 01:09:28 +0900 Subject: [PATCH 10/12] Android project - Modifying recompiler related code --- app/src/main/cpp/pcsx2/arm64/VixlHelpers.cpp | 6 ++ app/src/main/cpp/pcsx2/arm64/VixlHelpers.h | 1 + .../main/cpp/pcsx2/x86/microVU_Execute.inl | 66 ++++++++++--------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/app/src/main/cpp/pcsx2/arm64/VixlHelpers.cpp b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.cpp index 1798667..a3bb71e 100644 --- a/app/src/main/cpp/pcsx2/arm64/VixlHelpers.cpp +++ b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.cpp @@ -596,6 +596,12 @@ a64::VRegister armLoadPtrV(const void* addr) return RQSCRATCH; } +a64::VRegister armLoadPtrM(const a64::MemOperand offset) +{ + armAsm->Ldr(RQSCRATCH, offset); + return RQSCRATCH; +} + a64::VRegister armLoadPtrM(a64::Register regRs, int64_t offset) { armAsm->Ldr(RQSCRATCH, a64::MemOperand(regRs, offset)); diff --git a/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h index baa5d6d..2985666 100644 --- a/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h +++ b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h @@ -196,6 +196,7 @@ void armLoadPtr(const a64::CPURegister& regRt, a64::Register regRs, int64_t offs void armLoadPtr(uint64_t imm, const void* addr, const a64::Register& reg=EEX); void armLoadPtr(uint64_t imm, a64::Register regRs, int64_t offset, const a64::Register& regRt=EEX); a64::VRegister armLoadPtrV(const void* addr); +a64::VRegister armLoadPtrM(const a64::MemOperand offset); a64::VRegister armLoadPtrM(a64::Register regRs, int64_t offset=0); void armStorePtr(const a64::CPURegister& reg, const void* addr, int64_t offset); void armStorePtr(const a64::CPURegister& regRt, a64::Register regRs, int64_t offset); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl index 24710df..ff11195 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Execute.inl @@ -255,33 +255,34 @@ static void mVUGenerateCopyPipelineState(mV) { mVU.copyPLState = armStartBlock(); { -// xMOVAPS(xmm0, ptr[rax]); - armAsm->Ldr(xmm0, a64::MemOperand(RAX)); -// xMOVAPS(xmm1, ptr[rax + 16u]); - armAsm->Ldr(xmm1, a64::MemOperand(RAX, 16u)); -// xMOVAPS(xmm2, ptr[rax + 32u]); - armAsm->Ldr(xmm2, a64::MemOperand(RAX, 32u)); -// xMOVAPS(xmm3, ptr[rax + 48u]); - armAsm->Ldr(xmm3, a64::MemOperand(RAX, 48u)); -// xMOVAPS(xmm4, ptr[rax + 64u]); - armAsm->Ldr(xmm4, a64::MemOperand(RAX, 64u)); -// xMOVAPS(xmm5, ptr[rax + 80u]); - armAsm->Ldr(xmm5, a64::MemOperand(RAX, 80u)); + auto mop_rax = a64::MemOperand(RAX); + auto mop_lpState = PTR_MVU(microVU[mVU.index].prog.lpState); - a64::MemOperand mop = PTR_MVU(microVU[mVU.index].prog.lpState); +// xMOVAPS(xmm0, ptr[rax]); + armAsm->Ldr(xmm0, mop_rax); +// xMOVAPS(xmm1, ptr[rax + 16u]); + armAsm->Ldr(xmm1, armOffsetMemOperand(mop_rax, 16u)); +// xMOVAPS(xmm2, ptr[rax + 32u]); + armAsm->Ldr(xmm2, armOffsetMemOperand(mop_rax, 32u)); +// xMOVAPS(xmm3, ptr[rax + 48u]); + armAsm->Ldr(xmm3, armOffsetMemOperand(mop_rax, 48u)); +// xMOVAPS(xmm4, ptr[rax + 64u]); + armAsm->Ldr(xmm4, armOffsetMemOperand(mop_rax, 64u)); +// xMOVAPS(xmm5, ptr[rax + 80u]); + armAsm->Ldr(xmm5, armOffsetMemOperand(mop_rax, 80u)); // xMOVUPS(ptr[reinterpret_cast(&mVU.prog.lpState)], xmm0); - armAsm->Str(xmm0, mop); + armAsm->Str(xmm0, mop_lpState); // xMOVUPS(ptr[reinterpret_cast(&mVU.prog.lpState) + 16u], xmm1); - armAsm->Str(xmm1, armOffsetMemOperand(mop, 16u)); + armAsm->Str(xmm1, armOffsetMemOperand(mop_lpState, 16u)); // xMOVUPS(ptr[reinterpret_cast(&mVU.prog.lpState) + 32u], xmm2); - armAsm->Str(xmm2, armOffsetMemOperand(mop, 32u)); + armAsm->Str(xmm2, armOffsetMemOperand(mop_lpState, 32u)); // xMOVUPS(ptr[reinterpret_cast(&mVU.prog.lpState) + 48u], xmm3); - armAsm->Str(xmm3, armOffsetMemOperand(mop, 48u)); + armAsm->Str(xmm3, armOffsetMemOperand(mop_lpState, 48u)); // xMOVUPS(ptr[reinterpret_cast(&mVU.prog.lpState) + 64u], xmm4); - armAsm->Str(xmm4, armOffsetMemOperand(mop, 64u)); + armAsm->Str(xmm4, armOffsetMemOperand(mop_lpState, 64u)); // xMOVUPS(ptr[reinterpret_cast(&mVU.prog.lpState) + 80u], xmm5); - armAsm->Str(xmm5, armOffsetMemOperand(mop, 80u)); + armAsm->Str(xmm5, armOffsetMemOperand(mop_lpState, 80u)); } // xRET(); @@ -303,14 +304,17 @@ static void mVUGenerateCompareState(mV) { mVU.compareStateF = armStartBlock(); { + auto mop_arg1reg = a64::MemOperand(RCX); + auto mop_arg2reg = a64::MemOperand(RDX); + // xMOVAPS (xmm0, ptr32[arg1reg]); - armAsm->Ldr(xmm0, a64::MemOperand(RCX)); + armAsm->Ldr(xmm0, mop_arg1reg); // xPCMP.EQD(xmm0, ptr32[arg2reg]); - armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RDX).V4S()); + armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(mop_arg2reg).V4S()); // xMOVAPS (xmm1, ptr32[arg1reg + 0x10]); - armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x10)); + armAsm->Ldr(xmm1, armOffsetMemOperand(mop_arg1reg, 0x10)); // xPCMP.EQD(xmm1, ptr32[arg2reg + 0x10]); - armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x10).V4S()); + armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(armOffsetMemOperand(mop_arg2reg, 0x10)).V4S()); // xPAND (xmm0, xmm1); armAsm->And(xmm0.V16B(), xmm0.V16B(), xmm1.V16B()); @@ -324,24 +328,24 @@ static void mVUGenerateCompareState(mV) armCbnz(EAX, &exitPoint); // xMOVAPS (xmm0, ptr32[arg1reg + 0x20]); - armAsm->Ldr(xmm0, a64::MemOperand(RCX, 0x20)); + armAsm->Ldr(xmm0, armOffsetMemOperand(mop_arg1reg, 0x20)); // xPCMP.EQD(xmm0, ptr32[arg2reg + 0x20]); - armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(RDX, 0x20).V4S()); + armAsm->Cmeq(xmm0.V4S(), xmm0.V4S(), armLoadPtrM(armOffsetMemOperand(mop_arg2reg, 0x20)).V4S()); // xMOVAPS (xmm1, ptr32[arg1reg + 0x30]); - armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x30)); + armAsm->Ldr(xmm1, armOffsetMemOperand(mop_arg1reg, 0x30)); // xPCMP.EQD(xmm1, ptr32[arg2reg + 0x30]); - armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x30).V4S()); + armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(armOffsetMemOperand(mop_arg2reg, 0x30)).V4S()); // xPAND (xmm0, xmm1); armAsm->And(xmm0.V16B(), xmm0.V16B(), xmm1.V16B()); // xMOVAPS (xmm1, ptr32[arg1reg + 0x40]); - armAsm->Ldr(xmm1, a64::MemOperand(RCX, 0x40)); + armAsm->Ldr(xmm1, armOffsetMemOperand(mop_arg1reg, 0x40)); // xPCMP.EQD(xmm1, ptr32[arg2reg + 0x40]); - armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(RDX, 0x40).V4S()); + armAsm->Cmeq(xmm1.V4S(), xmm1.V4S(), armLoadPtrM(armOffsetMemOperand(mop_arg2reg, 0x40)).V4S()); // xMOVAPS (xmm2, ptr32[arg1reg + 0x50]); - armAsm->Ldr(xmm2, a64::MemOperand(RCX, 0x50)); + armAsm->Ldr(xmm2, armOffsetMemOperand(mop_arg1reg, 0x50)); // xPCMP.EQD(xmm2, ptr32[arg2reg + 0x50]); - armAsm->Cmeq(xmm2.V4S(), xmm2.V4S(), armLoadPtrM(RDX, 0x50).V4S()); + armAsm->Cmeq(xmm2.V4S(), xmm2.V4S(), armLoadPtrM(armOffsetMemOperand(mop_arg2reg, 0x50)).V4S()); // xPAND (xmm1, xmm2); armAsm->And(xmm1.V16B(), xmm1.V16B(), xmm2.V16B()); // xPAND (xmm0, xmm1); From 489684a58a265a6c17f9af16b37cf4168c0b684b Mon Sep 17 00:00:00 2001 From: pontos2024 Date: Thu, 21 Aug 2025 04:06:04 +0900 Subject: [PATCH 11/12] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2414731..ac195df 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,6 @@ * It is still unfinished because I made it while studying due to my lack of experience with assembler. * I think it would be good to look at it for reference. -* https://www.youtube.com/watch?v=ACxMJufB1EM +* [https://www.youtube.com/watch?v=ACxMJufB1EM](https://youtu.be/hNc3k3wPyTM) ![Image](https://github.com/user-attachments/assets/534405ee-c622-4726-876b-31f398bbb46d) From 24191b6bb801a9e52ed75dee2e9afa4006e908b6 Mon Sep 17 00:00:00 2001 From: k2154 Date: Thu, 21 Aug 2025 08:46:57 +0900 Subject: [PATCH 12/12] Android project - Modifying recompiler related code --- app/src/main/cpp/pcsx2/arm64/VixlHelpers.h | 3 ++- .../main/cpp/pcsx2/arm64/cpuRegistersPack.h | 2 +- app/src/main/cpp/pcsx2/x86/BaseblockEx.h | 2 +- app/src/main/cpp/pcsx2/x86/iCOP0.cpp | 6 ++--- app/src/main/cpp/pcsx2/x86/iR3000A.cpp | 24 +++++++++---------- app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp | 2 +- app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp | 22 ++++++++--------- .../main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp | 9 ++++--- 8 files changed, 34 insertions(+), 36 deletions(-) diff --git a/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h index 2985666..f86bf47 100644 --- a/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h +++ b/app/src/main/cpp/pcsx2/arm64/VixlHelpers.h @@ -58,6 +58,7 @@ namespace a64 = vixl::aarch64; // fastmem #define RFASTMEMBASE a64::x25 +// iopMem->Main #define RSTATE_x26 a64::x26 // CPU(iR5900), PSX(iR3000A), FPU(iFPU, iFPUd) @@ -69,7 +70,7 @@ namespace a64 = vixl::aarch64; #define RSTATE_MVU a64::x28 #define PTR_MVU(field) a64::MemOperand(RSTATE_MVU, offsetof(vuRegistersPack, field)) -// iopMem->Main +// recLUT, psxRecLUT #define RSTATE_x29 a64::x29 // eeHw[Ps2MemSize::Hardware] diff --git a/app/src/main/cpp/pcsx2/arm64/cpuRegistersPack.h b/app/src/main/cpp/pcsx2/arm64/cpuRegistersPack.h index 7c0c4a4..d8f38a2 100644 --- a/app/src/main/cpp/pcsx2/arm64/cpuRegistersPack.h +++ b/app/src/main/cpp/pcsx2/arm64/cpuRegistersPack.h @@ -10,7 +10,7 @@ #include "R3000ADef.h" #include "VUDef.h" #include "vtlbDef.h" -#include "arm64/ShuffleLanes.h" +#include "ShuffleLanes.h" struct cpuRegistersPack { diff --git a/app/src/main/cpp/pcsx2/x86/BaseblockEx.h b/app/src/main/cpp/pcsx2/x86/BaseblockEx.h index 002ae6f..06b0d48 100644 --- a/app/src/main/cpp/pcsx2/x86/BaseblockEx.h +++ b/app/src/main/cpp/pcsx2/x86/BaseblockEx.h @@ -229,7 +229,7 @@ public: } }; -#define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (x) * (sizeof(BASEBLOCK) / 4))) +#define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (x) * (sizeof(BASEBLOCK) >> 2))) // (sizeof(BASEBLOCK) / 4) /** * Add a page to the recompiler lookup table diff --git a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp index 233982a..3bdc914 100644 --- a/app/src/main/cpp/pcsx2/x86/iCOP0.cpp +++ b/app/src/main/cpp/pcsx2/x86/iCOP0.cpp @@ -42,15 +42,13 @@ static void _setupBranchTest() // everything except the lower 10 bits away. // xMOV(eax, ptr[(&psHu32(DMAC_PCR))]); - armAsm->Ldr(RWVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(DMAC_PCR))); - armAsm->Uxtw(EAX, RWVIXLSCRATCH); + armAsm->Mov(EAX, psHu32(DMAC_PCR)); // xMOV(ecx, 0x3ff); // ECX is our 10-bit mask var armAsm->Mov(ECX, 0x3ff); // xNOT(eax); armAsm->Mvn(EAX, EAX); // xOR(eax, ptr[(&psHu32(DMAC_STAT))]); - armAsm->Ldr(RWVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(DMAC_STAT))); - armAsm->Orr(EAX, EAX, a64::Operand(RWVIXLSCRATCH, a64::Extend::UXTW)); + armAsm->Orr(EAX, EAX, armLoadPtr(&psHu32(DMAC_STAT))); // xAND(eax, ecx); armAsm->And(EAX, EAX, ECX); // xCMP(eax, ecx); diff --git a/app/src/main/cpp/pcsx2/x86/iR3000A.cpp b/app/src/main/cpp/pcsx2/x86/iR3000A.cpp index 25130d7..c0209b6 100644 --- a/app/src/main/cpp/pcsx2/x86/iR3000A.cpp +++ b/app/src/main/cpp/pcsx2/x86/iR3000A.cpp @@ -183,13 +183,13 @@ static const void* _DynGen_JITCompile() // xJMP(ptrNative[rbx * (wordsize / 4) + rcx]); armLoad(EAX, PTR_CPU(psxRegs.pc)); - armAsm->Lsr(ECX, EAX, 16); - armAsm->Lsr(EAX, EAX, 2); -// armMoveAddressToReg(RDX, &psxRecLUT); - armAsm->Mov(RDX, (uptr)&psxRecLUT); - armAsm->Ldr(RCX, a64::MemOperand(RDX, RCX, a64::LSL, 3)); //// + armAsm->Lsr(ECX, EAX, 16); + armAsm->Ldr(RCX, a64::MemOperand(RSTATE_x29, RCX, a64::LSL, 3)); + //// + armAsm->Lsr(EAX, EAX, 2); armAsm->Ldr(RAX, a64::MemOperand(RCX, RAX, a64::LSL, 3)); + //// armAsm->Br(RAX); return retval; @@ -208,13 +208,13 @@ static const void* _DynGen_DispatcherReg() // xJMP(ptrNative[rbx * (wordsize / 4) + rcx]); armLoad(EAX, PTR_CPU(psxRegs.pc)); - armAsm->Lsr(ECX, EAX, 16); - armAsm->Lsr(EAX, EAX, 2); -// armMoveAddressToReg(RDX, &psxRecLUT); - armAsm->Mov(RDX, (uptr)&psxRecLUT); - armAsm->Ldr(RCX, a64::MemOperand(RDX, RCX, a64::LSL, 3)); //// + armAsm->Lsr(ECX, EAX, 16); + armAsm->Ldr(RCX, a64::MemOperand(RSTATE_x29, RCX, a64::LSL, 3)); + //// + armAsm->Lsr(EAX, EAX, 2); armAsm->Ldr(RAX, a64::MemOperand(RCX, RAX, a64::LSL, 3)); + //// armAsm->Br(RAX); return retval; @@ -239,8 +239,8 @@ static const void* _DynGen_EnterRecompiledCode() // xScopedStackFrame frame(false, true); armBeginStackFrame(); #endif - armMoveAddressToReg(RSTATE_x29, iopMem->Main); -// armAsm->Mov(RSTATE_CPU, (uptr)&g_cpuRegistersPack); + armMoveAddressToReg(RSTATE_x26, iopMem->Main); + armMoveAddressToReg(RSTATE_x29, &psxRecLUT); // xJMP((void*)iopDispatcherReg); armEmitJmp(iopDispatcherReg); diff --git a/app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp b/app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp index f8b9791..28fec30 100644 --- a/app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp +++ b/app/src/main/cpp/pcsx2/x86/iR3000Atables.cpp @@ -1403,7 +1403,7 @@ static void rpsxLoad(int size, bool sign) armAsm->And(EAX, EAX, 0x1fffff); // auto addr = xComplexAddress(rax, iopMem->Main, arg1reg); - const auto addr = a64::MemOperand(RSTATE_x29, RAX); + const auto addr = a64::MemOperand(RSTATE_x26, RAX); switch (size) { case 8: diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp index f2331ac..b5cc385 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp @@ -412,13 +412,13 @@ static const void* _DynGen_JITCompile() // xJMP(ptrNative[rbx * (wordsize / 4) + rcx]); armLoad(EAX, PTR_CPU(cpuRegs.pc)); - armAsm->Lsr(ECX, EAX, 16); - armAsm->Lsr(EAX, EAX, 2); -// armMoveAddressToReg(RDX, &recLUT); - armAsm->Mov(RDX, (uptr)&recLUT); - armAsm->Ldr(RCX, a64::MemOperand(RDX, RCX, a64::LSL, 3)); //// + armAsm->Lsr(ECX, EAX, 16); + armAsm->Ldr(RCX, a64::MemOperand(RSTATE_x29, RCX, a64::LSL, 3)); + //// + armAsm->Lsr(EAX, EAX, 2); armAsm->Ldr(RAX, a64::MemOperand(RCX, RAX, a64::LSL, 3)); + //// armAsm->Br(RAX); return retval; @@ -441,13 +441,13 @@ static const void* _DynGen_DispatcherReg() // xJMP(ptrNative[rbx * (wordsize / 4) + rcx]); armLoad(EAX, PTR_CPU(cpuRegs.pc)); - armAsm->Lsr(ECX, EAX, 16); - armAsm->Lsr(EAX, EAX, 2); -// armMoveAddressToReg(RDX, &recLUT); - armAsm->Mov(RDX, (uptr)&recLUT); - armAsm->Ldr(RCX, a64::MemOperand(RDX, RCX, a64::LSL, 3)); //// + armAsm->Lsr(ECX, EAX, 16); + armAsm->Ldr(RCX, a64::MemOperand(RSTATE_x29, RCX, a64::LSL, 3)); + //// + armAsm->Lsr(EAX, EAX, 2); armAsm->Ldr(RAX, a64::MemOperand(RCX, RAX, a64::LSL, 3)); + //// armAsm->Br(RAX); return retval; @@ -492,7 +492,7 @@ static const void* _DynGen_EnterRecompiledCode() // From memory to registry armMoveAddressToReg(RSTATE_PSX, &psxRegs); armMoveAddressToReg(RSTATE_CPU, &g_cpuRegistersPack); - armMoveAddressToReg(RSTATE_x26, &eeHw); + armMoveAddressToReg(RSTATE_x29, &recLUT); if (CHECK_FASTMEM) { // xMOV(RFASTMEMBASE, ptrNative[&vtlb_private::vtlbdata.fastmem_base]); diff --git a/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp b/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp index 6834f62..755f7bc 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/recVTLB.cpp @@ -600,7 +600,7 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const, // Shortcut for the INTC_STAT register, which many games like to spin on heavily. if ((bits == 32) && !EmuConfig.Speedhacks.IntcStat && (paddr == INTC_STAT)) { - armAsm->Ldr(RWVIXLSCRATCH, a64::MemOperand(RSTATE_x26, psHu(INTC_STAT))); + auto mop = armMemOperandPtr(&psHu32(INTC_STAT)); // x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(eax), eax.GetId()); x86_dest_reg = dest_reg_alloc ? dest_reg_alloc() : (_freeX86reg(EAX), EAX.GetCode()); @@ -609,18 +609,17 @@ int vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, bool xmm, u32 addr_const, auto regX = a64::XRegister(x86_dest_reg); if (sign) { // xMOVSX(xRegister64(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Sxtw(regX, RWVIXLSCRATCH); + armAsm->Ldr(regX, mop); } else { // xMOV(xRegister32(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Uxtw(regX.W(), RWVIXLSCRATCH); + armAsm->Ldr(regX.W(), mop); } } else { // xMOVDZX(xRegisterSSE(x86_dest_reg), ptr32[&psHu32(INTC_STAT)]); - armAsm->Uxtw(RWVIXLSCRATCH, RWVIXLSCRATCH); - armAsm->Fmov(a64::QRegister(x86_dest_reg).S(), RWVIXLSCRATCH); + armAsm->Ldr(a64::QRegister(x86_dest_reg).S(), mop); } } else