Undo TLB caching + minor improvements

This commit is contained in:
SimoneN64
2024-10-15 21:05:33 +02:00
parent a0d46ca24e
commit cf5b1def4f
8 changed files with 81 additions and 125 deletions

View File

@@ -293,13 +293,7 @@ static FORCE_INLINE u64 getVPN(const u64 addr, const u64 pageMask) {
return vpn & ~mask;
}
TLBEntry *Cop0::TLBTryMatch(const u64 vaddr, int* index) {
if (tlbCache.contains(vaddr)) {
if (index)
*index = tlbCache[vaddr].index;
return tlbCache[vaddr].entry;
}
TLBEntry *Cop0::TLBTryMatch(const u64 vaddr, int &index) const {
for (int i = 0; i < 32; i++) {
if (TLBEntry *entry = &regs.cop0.tlb[i]; entry->initialized) {
const u64 entry_vpn = getVPN(entry->entryHi.raw, entry->pageMask.raw);
@@ -309,10 +303,7 @@ TLBEntry *Cop0::TLBTryMatch(const u64 vaddr, int* index) {
if (const bool asid_match = entry->global || regs.cop0.entryHi.asid == entry->entryHi.asid;
vpn_match && asid_match) {
tlbCache[vaddr].entry = entry;
tlbCache[vaddr].index = i;
if (index)
*index = i;
index = i;
return entry;
}
}
@@ -321,44 +312,47 @@ TLBEntry *Cop0::TLBTryMatch(const u64 vaddr, int* index) {
return nullptr;
}
bool Cop0::ProbeTLB(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
const TLBEntry *entry = TLBTryMatch(vaddr, nullptr);
TLBEntry *Cop0::TLBTryMatch(const u64 vaddr) const {
for (auto &i : regs.cop0.tlb) {
if (TLBEntry *entry = &i; entry->initialized) {
const u64 entry_vpn = getVPN(entry->entryHi.raw, entry->pageMask.raw);
const u64 vaddr_vpn = getVPN(vaddr, entry->pageMask.raw);
const bool vpn_match = entry_vpn == vaddr_vpn;
if (const bool asid_match = entry->global || regs.cop0.entryHi.asid == entry->entryHi.asid;
vpn_match && asid_match) {
return entry;
}
}
}
return nullptr;
}
bool Cop0::ProbeTLB(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) const {
const TLBEntry *entry = TLBTryMatch(vaddr);
if (!entry) {
regs.cop0.tlbError = MISS;
return false;
}
const u32 mask = entry->pageMask.mask << 12 | 0xFFF;
const u32 odd = vaddr & (mask + 1);
u32 pfn;
const u32 odd = vaddr & mask + 1;
if (!odd) {
if (!entry->entryLo0.v) {
regs.cop0.tlbError = INVALID;
return false;
}
const EntryLo entryLo = odd ? entry->entryLo1 : entry->entryLo0;
if (accessType == STORE && !entry->entryLo0.d) {
regs.cop0.tlbError = MODIFICATION;
return false;
}
pfn = entry->entryLo0.pfn;
} else {
if (!entry->entryLo1.v) {
regs.cop0.tlbError = INVALID;
return false;
}
if (accessType == STORE && !entry->entryLo1.d) {
regs.cop0.tlbError = MODIFICATION;
return false;
}
pfn = entry->entryLo1.pfn;
if (!entryLo.v) {
regs.cop0.tlbError = INVALID;
return false;
}
paddr = pfn << 12 | vaddr & mask;
if (accessType == STORE && !entryLo.d) {
regs.cop0.tlbError = MODIFICATION;
return false;
}
paddr = entryLo.pfn << 12 | vaddr & mask;
return true;
}
@@ -559,10 +553,10 @@ bool Cop0::UserMapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &
}
bool Cop0::MapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
switch (u32(vaddr) >> 29 & 7) {
switch (static_cast<u32>(vaddr) >> 29 & 7) {
case 0 ... 3:
case 7:
return ProbeTLB(accessType, s64(s32(vaddr)), paddr);
return ProbeTLB(accessType, static_cast<s32>(vaddr), paddr);
case 4 ... 5:
paddr = vaddr & 0x1FFFFFFF;
return true;