From 8f6bcc1c0bdc7007c8f5245b687b5747a2bd3e20 Mon Sep 17 00:00:00 2001 From: k2154 Date: Sun, 24 Aug 2025 04:55:16 +0900 Subject: [PATCH] Android project - Modifying recompiler related code --- app/src/main/cpp/pcsx2/vtlb.cpp | 11 ++- app/src/main/cpp/pcsx2/x86/BaseblockEx.h | 67 ++++++++-------- app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp | 78 ++++++++++++------- .../main/cpp/pcsx2/x86/microVU_Compile.inl | 13 +++- 4 files changed, 100 insertions(+), 69 deletions(-) diff --git a/app/src/main/cpp/pcsx2/vtlb.cpp b/app/src/main/cpp/pcsx2/vtlb.cpp index ee2c044..5fbf386 100644 --- a/app/src/main/cpp/pcsx2/vtlb.cpp +++ b/app/src/main/cpp/pcsx2/vtlb.cpp @@ -854,10 +854,11 @@ void vtlb_Mirror(u32 new_region, u32 start, u32 size) __fi void* vtlb_GetPhyPtr(u32 paddr) { - if (paddr >= VTLB_PMAP_SZ || vtlbdata.pmap[paddr >> VTLB_PAGE_BITS].isHandler()) - return NULL; - else - return reinterpret_cast(vtlbdata.pmap[paddr >> VTLB_PAGE_BITS].assumePtr() + (paddr & VTLB_PAGE_MASK)); + auto pmap_value = vtlbdata.pmap[paddr >> VTLB_PAGE_BITS]; + if (paddr >= VTLB_PMAP_SZ || pmap_value.isHandler()) + return NULL; + else + return reinterpret_cast(pmap_value.assumePtr() + (paddr & VTLB_PAGE_MASK)); } __fi u32 vtlb_V2P(u32 vaddr) @@ -1523,10 +1524,12 @@ void mmap_MarkCountedRamPage(u32 paddr) if (m_PageProtectInfo[rampage].Mode == ProtMode_Write) return; // skip town if we're already protected. +#ifdef PCSX2_DEVBUILD eeRecPerfLog.Write((m_PageProtectInfo[rampage].Mode == ProtMode_Manual) ? "Re-protecting page @ 0x%05x" : "Protected page @ 0x%05x", paddr >> __pageshift); +#endif m_PageProtectInfo[rampage].Mode = ProtMode_Write; HostSys::MemProtect(&eeMem->Main[rampage << __pageshift], __pagesize, PageAccess_ReadOnly()); diff --git a/app/src/main/cpp/pcsx2/x86/BaseblockEx.h b/app/src/main/cpp/pcsx2/x86/BaseblockEx.h index 06b0d48..29d4233 100644 --- a/app/src/main/cpp/pcsx2/x86/BaseblockEx.h +++ b/app/src/main/cpp/pcsx2/x86/BaseblockEx.h @@ -37,53 +37,56 @@ struct BASEBLOCKEX class BaseBlockArray { - s32 _Reserved; - s32 _Size; + s32 mReserved; + s32 mSize; BASEBLOCKEX* blocks; __fi void resize(s32 size) { pxAssert(size > 0); - BASEBLOCKEX* newMem = new BASEBLOCKEX[size]; + auto* newMem = new BASEBLOCKEX[size]; if (blocks) { - memcpy(newMem, blocks, _Reserved * sizeof(BASEBLOCKEX)); + memcpy(newMem, blocks, mReserved * sizeof(BASEBLOCKEX)); delete[] blocks; + blocks = nullptr; } blocks = newMem; pxAssert(blocks != NULL); } - void reserve(u32 size) + void reserve(s32 size) { resize(size); - _Reserved = size; + mReserved = size; } public: ~BaseBlockArray() { - if (blocks) - delete[] blocks; + if (blocks) { + delete[] blocks; + blocks = nullptr; + } } - BaseBlockArray(s32 size) - : _Reserved(0) - , _Size(0) - , blocks(NULL) + explicit BaseBlockArray(s32 size) + : mReserved(0) + , mSize(0) + , blocks(nullptr) { reserve(size); } BASEBLOCKEX* insert(u32 startpc, uptr fnptr) { - if (_Size + 1 >= _Reserved) + if (mSize + 1 >= mReserved) { - reserve(_Reserved + 0x2000); // some games requires even more! + reserve(mReserved + 0x2000); // some games requires even more! } // Insert the the new BASEBLOCKEX by startpc order - int imin = 0, imax = _Size, imid; + int imin = 0, imax = mSize, imid; while (imin < imax) { @@ -95,19 +98,19 @@ public: imin = imid + 1; } - pxAssert(imin == _Size || blocks[imin].startpc > startpc); + pxAssert(imin == mSize || blocks[imin].startpc > startpc); - if (imin < _Size) + if (imin < mSize) { // make a hole for a new block. - memmove(blocks + imin + 1, blocks + imin, (_Size - imin) * sizeof(BASEBLOCKEX)); + memmove(blocks + imin + 1, blocks + imin, (mSize - imin) * sizeof(BASEBLOCKEX)); } memset((blocks + imin), 0, sizeof(BASEBLOCKEX)); blocks[imin].startpc = startpc; blocks[imin].fnptr = fnptr; - _Size++; + mSize++; return &blocks[imin]; } @@ -118,24 +121,24 @@ public: void clear() { - _Size = 0; + mSize = 0; } - __fi u32 size() const + [[nodiscard]] __fi u32 size() const { - return _Size; + return mSize; } __fi void erase(s32 first, s32 last) { int range = last - first; - if (last < _Size) + if (last < mSize) { - memmove(blocks + first, blocks + last, (_Size - last) * sizeof(BASEBLOCKEX)); + memmove(blocks + first, blocks + last, (mSize - last) * sizeof(BASEBLOCKEX)); } - _Size -= range; + mSize -= range; } }; @@ -162,15 +165,17 @@ public: } BASEBLOCKEX* New(u32 startpc, uptr fnptr); - int LastIndex(u32 startpc) const; + [[nodiscard]] int LastIndex(u32 startpc) const; //BASEBLOCKEX* GetByX86(uptr ip); - __fi int Index(u32 startpc) const + [[nodiscard]] __fi int Index(u32 startpc) const { int idx = LastIndex(startpc); + u32 block_startpc = blocks[idx].startpc; + u32 block_size = (blocks[idx].size); - if ((idx == -1) || (startpc < blocks[idx].startpc) || - ((blocks[idx].size) && (startpc >= blocks[idx].startpc + blocks[idx].size * 4))) + if ((idx == -1) || (startpc < block_startpc) || + (block_size && (startpc >= block_startpc + block_size << 2))) // blocks[idx].size * 4 return -1; else return idx; @@ -179,7 +184,7 @@ public: __fi BASEBLOCKEX* operator[](int idx) { if (idx < 0 || idx >= (int)blocks.size()) - return 0; + return nullptr; return &blocks[idx]; } @@ -198,7 +203,7 @@ public: pxAssert(idx <= last); //u32 startpc = blocks[idx].startpc; - std::pair range = links.equal_range(blocks[idx].startpc); + auto range = links.equal_range(blocks[idx].startpc); for (auto i = range.first; i != range.second; ++i) { // *(u32 *) i->second = recompiler - (i->second + 4); armEmitJmpPtr((void*)i->second, (void*)recompiler, true); 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 b5cc385..21ec511 100644 --- a/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp +++ b/app/src/main/cpp/pcsx2/x86/ix86-32/iR5900.cpp @@ -490,9 +490,9 @@ static const void* _DynGen_EnterRecompiledCode() #endif // From memory to registry + armMoveAddressToReg(RSTATE_x29, &recLUT); armMoveAddressToReg(RSTATE_PSX, &psxRegs); armMoveAddressToReg(RSTATE_CPU, &g_cpuRegistersPack); - armMoveAddressToReg(RSTATE_x29, &recLUT); if (CHECK_FASTMEM) { // xMOV(RFASTMEMBASE, ptrNative[&vtlb_private::vtlbdata.fastmem_base]); @@ -802,14 +802,16 @@ void recClear(u32 addr, u32 size) { if ((addr) >= maxrecmem || !(recLUT[(addr) >> 16] + (addr & ~0xFFFFUL))) return; + addr = HWADDR(addr); - int blockidx = recBlocks.LastIndex(addr + size * 4 - 4); + u32 addr_size = addr + (size << 2); // // size * 4 + int blockidx = recBlocks.LastIndex(addr_size - 4); if (blockidx == -1) return; - u32 lowerextent = static_cast(-1), upperextent = 0, ceiling = static_cast(-1); + u32 lowerextent = 0xFFFFFFFF, upperextent = 0, ceiling = 0xFFFFFFFF; // 0xFFFFFFFF == -1 BASEBLOCKEX* pexblock = recBlocks[blockidx + 1]; if (pexblock) @@ -817,11 +819,12 @@ void recClear(u32 addr, u32 size) int toRemoveLast = blockidx; + u32 blockstart, blockend; while ((pexblock = recBlocks[blockidx])) { - u32 blockstart = pexblock->startpc; - u32 blockend = pexblock->startpc + pexblock->size * 4; - BASEBLOCK* pblock = PC_GETBLOCK(blockstart); + blockstart = pexblock->startpc; + blockend = pexblock->startpc + (pexblock->size << 2); // pexblock->size * 4 + BASEBLOCK* pblock = PC_GETBLOCK(blockstart); if (pblock == s_pCurBlock) { @@ -853,12 +856,12 @@ void recClear(u32 addr, u32 size) upperextent = std::min(upperextent, ceiling); - for (int i = 0; (pexblock = recBlocks[i]); i++) + for (int i = 0; (pexblock = recBlocks[i]); ++i) { if (s_pCurBlock == PC_GETBLOCK(pexblock->startpc)) continue; - u32 blockend = pexblock->startpc + pexblock->size * 4; - if ((pexblock->startpc >= addr && pexblock->startpc < addr + size * 4) || (pexblock->startpc < addr && blockend > addr)) [[unlikely]] + blockend = pexblock->startpc + (pexblock->size << 2); // pexblock->size * 4 + if ((pexblock->startpc >= addr && pexblock->startpc < addr_size) || (pexblock->startpc < addr && blockend > addr)) [[unlikely]] { Console.Error("[EE] Impossible block clearing failure"); pxFail("[EE] Impossible block clearing failure"); @@ -2118,7 +2121,9 @@ static void PreBlockCheck(u32 blockpc) // less likely, self-modifying code) void dyna_block_discard(u32 start, u32 sz) { +#ifdef PCSX2_DEVBUILD eeRecPerfLog.Write(Color_StrongGray, "Clearing Manual Block @ 0x%08X [size=%d]", start, sz * 4); +#endif recClear(start, sz); } @@ -2135,11 +2140,12 @@ void dyna_page_reset(u32 start, u32 sz) static void memory_protect_recompiled_code(u32 startpc, u32 size) { u32 inpage_ptr = HWADDR(startpc); - const u32 inpage_sz = size * 4; + const u32 inpage_sz = size << 2; // size * 4 // The kernel context register is stored @ 0x800010C0-0x80001300 // The EENULL thread context register is stored @ 0x81000-.... - const bool contains_thread_stack = ((startpc >> 12) == 0x81) || ((startpc >> 12) == 0x80001); + u32 startpc_lsr_12 = (startpc >> 12); + const bool contains_thread_stack = (startpc_lsr_12 == 0x81) || (startpc_lsr_12 == 0x80001); // note: blocks are guaranteed to reside within the confines of a single page. const vtlb_ProtectionMode PageType = contains_thread_stack ? ProtMode_Manual : mmap_GetRamPageInfo(inpage_ptr); @@ -2159,16 +2165,24 @@ static void memory_protect_recompiled_code(u32 startpc, u32 size) // xMOV(arg1regd, inpage_ptr); armAsm->Mov(EAX, inpage_ptr); // xMOV(arg2regd, inpage_sz / 4); - armAsm->Mov(ECX, inpage_sz / 4); + armAsm->Mov(ECX, inpage_sz >> 2); //xMOV( eax, startpc ); // uncomment this to access startpc (as eax) in dyna_block_discard + u32 lpc_addr; u32 lpc = inpage_ptr; u32 stg = inpage_sz; + armAsm->Ldr(RSCRATCHADDR, PTR_CPU(vtlbdata.pmap)); + while (stg > 0) { // xCMP(ptr32[PSM(lpc)], *(u32*)PSM(lpc)); - armAsm->Cmp(armLoadPtr(PSM(lpc)), *(u32*)PSM(lpc)); + + lpc_addr = lpc & 0x1fffffff; + armAsm->Add(RXVIXLSCRATCH, RSCRATCHADDR, lpc_addr); + armAsm->Ldr(EDX, a64::MemOperand(RXVIXLSCRATCH)); + armAsm->Cmp(EDX, *(u32*)vtlb_GetPhyPtr(lpc_addr)); + // xJNE(DispatchBlockDiscard); armEmitCondBranch(a64::Condition::ne, DispatchBlockDiscard); @@ -2207,15 +2221,19 @@ static void memory_protect_recompiled_code(u32 startpc, u32 size) // xJC(DispatchPageReset); armEmitCondBranch(a64::Condition::cs, DispatchPageReset); +#ifdef PCSX2_DEVBUILD // note: clearcnt is measured per-page, not per-block! eeRecPerfLog.Write("Manual block @ %08X : size =%3d page/offs = 0x%05X/0x%03X inpgsz = %d clearcnt = %d", startpc, size, inpage_ptr >> 12, inpage_ptr & 0xfff, inpage_sz, manual_counter[inpage_ptr >> 12]); +#endif } +#ifdef PCSX2_DEVBUILD else { eeRecPerfLog.Write("Uncounted Manual block @ 0x%08X : size =%3d page/offs = 0x%05X/0x%03X inpgsz = %d", startpc, size, inpage_ptr >> 12, inpage_ptr & 0xfff, inpage_sz); } +#endif break; } } @@ -2462,7 +2480,7 @@ static void recRecompile(const u32 startpc) const int n = std::max(n1, n2); if (n != 0) { - s_nEndBlock = i + n * 4; + s_nEndBlock = i + (n << 2); // n * 4 goto StartRecomp; } @@ -2484,7 +2502,9 @@ static void recRecompile(const u32 startpc) willbranch3 = 1; s_nEndBlock = i; +#ifdef PCSX2_DEVBUILD eeRecPerfLog.Write("Pagesplit @ %08X : size=%d insts", startpc, (i - startpc) / 4); +#endif break; } @@ -2541,7 +2561,7 @@ static void recRecompile(const u32 startpc) if (_Rt_ < 4 || (_Rt_ >= 16 && _Rt_ < 20)) { // branches - s_branchTo = _Imm_ * 4 + i + 4; + s_branchTo = (_Imm_ << 2) + i + 4; // _Imm_ * 4 if (s_branchTo > startpc && s_branchTo < i) s_nEndBlock = s_branchTo; else @@ -2566,7 +2586,7 @@ static void recRecompile(const u32 startpc) case 21: case 22: case 23: - s_branchTo = _Imm_ * 4 + i + 4; + s_branchTo = (_Imm_ << 2) + i + 4; // _Imm_ * 4 if (s_branchTo > startpc && s_branchTo < i) s_nEndBlock = s_branchTo; else @@ -2592,7 +2612,7 @@ static void recRecompile(const u32 startpc) { // BC1F, BC1T, BC1FL, BC1TL // BC2F, BC2T, BC2FL, BC2TL - s_branchTo = _Imm_ * 4 + i + 4; + s_branchTo = (_Imm_ << 2) + i + 4; // _Imm_ * 4 if (s_branchTo > startpc && s_branchTo < i) s_nEndBlock = s_branchTo; else @@ -2698,10 +2718,11 @@ StartRecomp: // rec info // bool has_cop2_instructions = false; { - if (s_nInstCacheSize < (s_nEndBlock - startpc) / 4 + 1) + u32 block_offset = (s_nEndBlock - startpc) >> 2; // (s_nEndBlock - startpc) / 4 + if (s_nInstCacheSize < block_offset + 1) { - const u32 required_size = (s_nEndBlock - startpc) / 4 + 10; - const u32 new_size = std::max(required_size, s_nInstCacheSize * 2); + const u32 required_size = block_offset + 10; + const u32 new_size = std::max(required_size, s_nInstCacheSize << 1); // s_nInstCacheSize * 2 EEINST* new_cache = (EEINST*)malloc(sizeof(EEINST) * new_size); if (!new_cache) @@ -2717,7 +2738,7 @@ StartRecomp: s_nInstCacheSize = new_size; } - EEINST* pcur = s_pInstCache + (s_nEndBlock - startpc) / 4; + EEINST* pcur = s_pInstCache + block_offset; _recClearInst(pcur); pcur->info = 0; @@ -2811,29 +2832,26 @@ StartRecomp: if (HWADDR(pc) <= Ps2MemSize::ExposedRam) { BASEBLOCKEX* oldBlock; - int i; - - i = recBlocks.LastIndex(HWADDR(pc) - 4); - while ((oldBlock = recBlocks[i--])) + int ii = recBlocks.LastIndex(HWADDR(pc) - 4); + while ((oldBlock = recBlocks[ii--])) { if (oldBlock == s_pCurBlockEx) continue; if (oldBlock->startpc >= HWADDR(pc)) continue; - if ((oldBlock->startpc + oldBlock->size * 4) <= HWADDR(startpc)) + if ((oldBlock->startpc + (oldBlock->size << 2)) <= HWADDR(startpc)) // oldBlock->size * 4 break; - if (memcmp(&recRAMCopy[oldBlock->startpc / 4], PSM(oldBlock->startpc), - oldBlock->size * 4)) + if (memcmp(&recRAMCopy[oldBlock->startpc >> 2], PSM(oldBlock->startpc), oldBlock->size << 2)) // oldBlock->startpc / 4, oldBlock->size * 4 { - recClear(startpc, (pc - startpc) / 4); + recClear(startpc, (pc - startpc) >> 2); // (pc - startpc) / 4 s_pCurBlockEx = recBlocks.Get(HWADDR(startpc)); pxAssert(s_pCurBlockEx->startpc == HWADDR(startpc)); break; } } - memcpy(&recRAMCopy[HWADDR(startpc) / 4], PSM(startpc), pc - startpc); + memcpy(&recRAMCopy[HWADDR(startpc) >> 2], PSM(startpc), pc - startpc); // HWADDR(startpc) / 4 } s_pCurBlock->SetFnptr((uptr)recPtr); diff --git a/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl b/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl index 52fa537..bcc6e10 100644 --- a/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl +++ b/app/src/main/cpp/pcsx2/x86/microVU_Compile.inl @@ -973,14 +973,19 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState) mVUsetupBranch(mVU, mFC); // Make sure we save the current state so it can come back to it - u32* cpS = (u32*)&mVUregs; - u32* lpS = (u32*)&mVU.prog.lpState; +// u32* cpS = (u32*)&mVUregs; +// u32* lpS = (u32*)&mVU.prog.lpState; + + auto cpS = armMemOperandPtr((u32*)&mVUregs); + auto lpS = armMemOperandPtr((u32*)&mVU.prog.lpState); + size_t i, e = (sizeof(microRegInfo) - 4) >> 2; // sizeof(microRegInfo) - 4 - for (i = 0; i < e; ++i, ++lpS, ++cpS) + for (i = 0; i < e; ++i) { // xMOV(ptr32[lpS], cpS[0]); - armStorePtr(cpS[0], lpS); + armAsm->Str(armOffsetMemOperand(cpS, 1).GetRegisterOffset(), armOffsetMemOperand(lpS, 1)); } + incPC(2); mVUsetupRange(mVU, xPC, false); if (EmuConfig.Gamefixes.VUSyncHack || EmuConfig.Gamefixes.FullVU0SyncHack) {