MMU: Make use of UPTE_Lo and UReg_SR in TranslatePageAddress()

Allows us to get rid of a bit of masking in exchange for stating the
bits being accessed or written to directly.
This commit is contained in:
Lioncash 2021-08-31 10:52:49 -04:00
parent e687569e02
commit ee40b640d3
1 changed files with 19 additions and 14 deletions

View File

@ -1308,34 +1308,39 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
// TLB cache // TLB cache
// This catches 99%+ of lookups in practice, so the actual page table entry code below doesn't // This catches 99%+ of lookups in practice, so the actual page table entry code below doesn't
// benefit much from optimization. // benefit much from optimization.
u32 translatedAddress = 0; u32 translated_address = 0;
TLBLookupResult res = LookupTLBPageAddress(flag, address, &translatedAddress, wi); const TLBLookupResult res = LookupTLBPageAddress(flag, address, &translated_address, wi);
if (res == TLBLookupResult::Found) if (res == TLBLookupResult::Found)
{
return TranslateAddressResult{TranslateAddressResultEnum::PAGE_TABLE_TRANSLATED, return TranslateAddressResult{TranslateAddressResultEnum::PAGE_TABLE_TRANSLATED,
translatedAddress}; translated_address};
}
u32 sr = PowerPC::ppcState.sr[EA_SR(address)]; const auto sr = UReg_SR{ppcState.sr[EA_SR(address)]};
if (sr & 0x80000000) if (sr.T != 0)
return TranslateAddressResult{TranslateAddressResultEnum::DIRECT_STORE_SEGMENT, 0}; return TranslateAddressResult{TranslateAddressResultEnum::DIRECT_STORE_SEGMENT, 0};
// TODO: Handle KS/KP segment register flags. // TODO: Handle KS/KP segment register flags.
// No-execute segment register flag. // No-execute segment register flag.
if ((flag == XCheckTLBFlag::Opcode || flag == XCheckTLBFlag::OpcodeNoException) && if ((flag == XCheckTLBFlag::Opcode || flag == XCheckTLBFlag::OpcodeNoException) && sr.N != 0)
(sr & 0x10000000))
{ {
return TranslateAddressResult{TranslateAddressResultEnum::PAGE_FAULT, 0}; return TranslateAddressResult{TranslateAddressResultEnum::PAGE_FAULT, 0};
} }
u32 offset = EA_Offset(address); // 12 bit const u32 offset = EA_Offset(address); // 12 bit
u32 page_index = EA_PageIndex(address); // 16 bit const u32 page_index = EA_PageIndex(address); // 16 bit
u32 VSID = SR_VSID(sr); // 24 bit const u32 VSID = sr.VSID; // 24 bit
u32 api = EA_API(address); // 6 bit (part of page_index) const u32 api = EA_API(address); // 6 bit (part of page_index)
// hash function no 1 "xor" .360 // hash function no 1 "xor" .360
u32 hash = (VSID ^ page_index); u32 hash = (VSID ^ page_index);
u32 pte1 = (VSID << 7) | api | PTE1_V;
UPTE_Lo pte1;
pte1.VSID = VSID;
pte1.API = api;
pte1.V = 1;
for (int hash_func = 0; hash_func < 2; hash_func++) for (int hash_func = 0; hash_func < 2; hash_func++)
{ {
@ -1343,7 +1348,7 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
if (hash_func == 1) if (hash_func == 1)
{ {
hash = ~hash; hash = ~hash;
pte1 |= PTE1_H; pte1.H = 1;
} }
u32 pteg_addr = u32 pteg_addr =
@ -1353,7 +1358,7 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
{ {
const u32 pteg = Memory::Read_U32(pteg_addr); const u32 pteg = Memory::Read_U32(pteg_addr);
if (pte1 == pteg) if (pte1.Hex == pteg)
{ {
UPTE_Hi pte2(Memory::Read_U32(pteg_addr + 4)); UPTE_Hi pte2(Memory::Read_U32(pteg_addr + 4));