Android project - Modifying recompiler related code

This commit is contained in:
k2154
2025-08-24 04:55:16 +09:00
parent 0d62372708
commit 8f6bcc1c0b
4 changed files with 100 additions and 69 deletions
+7 -4
View File
@@ -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<void*>(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<void*>(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());
+36 -31
View File
@@ -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<linkiter_t, linkiter_t> 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);
+48 -30
View File
@@ -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<u32>(-1), upperextent = 0, ceiling = static_cast<u32>(-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<int>(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);
@@ -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) {