mirror of
https://github.com/izzy2lost/PSX2.git
synced 2026-07-05 15:18:36 -07:00
Android project - Modifying recompiler related code
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user