Merge pull request #10010 from AdmiralCurtiss/jit-cache-translate-address-cleanup

PowerPC: Minor cleanup around JitCache_TranslateAddress().
This commit is contained in:
Tilka 2021-08-09 17:33:46 +01:00 committed by GitHub
commit 128e1029dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 35 deletions

View File

@ -96,10 +96,10 @@ void JitBaseBlockCache::RunOnBlocks(std::function<void(const JitBlock&)> f)
JitBlock* JitBaseBlockCache::AllocateBlock(u32 em_address) JitBlock* JitBaseBlockCache::AllocateBlock(u32 em_address)
{ {
u32 physicalAddress = PowerPC::JitCache_TranslateAddress(em_address).address; const u32 physical_address = PowerPC::JitCache_TranslateAddress(em_address).address;
JitBlock& b = block_map.emplace(physicalAddress, JitBlock())->second; JitBlock& b = block_map.emplace(physical_address, JitBlock())->second;
b.effectiveAddress = em_address; b.effectiveAddress = em_address;
b.physicalAddress = physicalAddress; b.physicalAddress = physical_address;
b.msrBits = MSR.Hex & JIT_CACHE_MSR_MASK; b.msrBits = MSR.Hex & JIT_CACHE_MSR_MASK;
b.linkData.clear(); b.linkData.clear();
b.fast_block_map_index = 0; b.fast_block_map_index = 0;
@ -185,25 +185,25 @@ const u8* JitBaseBlockCache::Dispatch()
void JitBaseBlockCache::InvalidateICache(u32 address, u32 length, bool forced) void JitBaseBlockCache::InvalidateICache(u32 address, u32 length, bool forced)
{ {
auto translated = PowerPC::JitCache_TranslateAddress(address); const auto translated = PowerPC::JitCache_TranslateAddress(address);
if (!translated.valid) if (!translated.valid)
return; return;
u32 pAddr = translated.address; const u32 physical_address = translated.address;
// Optimize the common case of length == 32 which is used by Interpreter::dcb* // Optimize the common case of length == 32 which is used by Interpreter::dcb*
bool destroy_block = true; bool destroy_block = true;
if (length == 32) if (length == 32)
{ {
if (!valid_block.Test(pAddr / 32)) if (!valid_block.Test(physical_address / 32))
destroy_block = false; destroy_block = false;
else else
valid_block.Clear(pAddr / 32); valid_block.Clear(physical_address / 32);
} }
if (destroy_block) if (destroy_block)
{ {
// destroy JIT blocks // destroy JIT blocks
ErasePhysicalRange(pAddr, length); ErasePhysicalRange(physical_address, length);
// If the code was actually modified, we need to clear the relevant entries from the // If the code was actually modified, we need to clear the relevant entries from the
// FIFO write address cache, so we don't end up with FIFO checks in places they shouldn't // FIFO write address cache, so we don't end up with FIFO checks in places they shouldn't

View File

@ -99,18 +99,25 @@ static bool IsNoExceptionFlag(XCheckTLBFlag flag)
return flag == XCheckTLBFlag::NoException || flag == XCheckTLBFlag::OpcodeNoException; return flag == XCheckTLBFlag::NoException || flag == XCheckTLBFlag::OpcodeNoException;
} }
struct TranslateAddressResult enum class TranslateAddressResultEnum : u8
{ {
enum
{
BAT_TRANSLATED, BAT_TRANSLATED,
PAGE_TABLE_TRANSLATED, PAGE_TABLE_TRANSLATED,
DIRECT_STORE_SEGMENT, DIRECT_STORE_SEGMENT,
PAGE_FAULT PAGE_FAULT,
} result; };
struct TranslateAddressResult
{
u32 address; u32 address;
TranslateAddressResultEnum result;
bool wi; // Set to true if the view of memory is either write-through or cache-inhibited bool wi; // Set to true if the view of memory is either write-through or cache-inhibited
bool Success() const { return result <= PAGE_TABLE_TRANSLATED; }
TranslateAddressResult(TranslateAddressResultEnum result_, u32 address_, bool wi_ = false)
: address(address_), result(result_), wi(wi_)
{
}
bool Success() const { return result <= TranslateAddressResultEnum::PAGE_TABLE_TRANSLATED; }
}; };
template <const XCheckTLBFlag flag> template <const XCheckTLBFlag flag>
static TranslateAddressResult TranslateAddress(u32 address); static TranslateAddressResult TranslateAddress(u32 address);
@ -444,7 +451,7 @@ TryReadInstResult TryReadInstruction(u32 address)
else else
{ {
address = tlb_addr.address; address = tlb_addr.address;
from_bat = tlb_addr.result == TranslateAddressResult::BAT_TRANSLATED; from_bat = tlb_addr.result == TranslateAddressResultEnum::BAT_TRANSLATED;
} }
} }
@ -1023,14 +1030,14 @@ void ClearCacheLine(u32 address)
if (MSR.DR) if (MSR.DR)
{ {
auto translated_address = TranslateAddress<XCheckTLBFlag::Write>(address); auto translated_address = TranslateAddress<XCheckTLBFlag::Write>(address);
if (translated_address.result == TranslateAddressResult::DIRECT_STORE_SEGMENT) if (translated_address.result == TranslateAddressResultEnum::DIRECT_STORE_SEGMENT)
{ {
// dcbz to direct store segments is ignored. This is a little // dcbz to direct store segments is ignored. This is a little
// unintuitive, but this is consistent with both console and the PEM. // unintuitive, but this is consistent with both console and the PEM.
// Advance Game Port crashes if we don't emulate this correctly. // Advance Game Port crashes if we don't emulate this correctly.
return; return;
} }
if (translated_address.result == TranslateAddressResult::PAGE_FAULT) if (translated_address.result == TranslateAddressResultEnum::PAGE_FAULT)
{ {
// If translation fails, generate a DSI. // If translation fails, generate a DSI.
GenerateDSIException(address, true); GenerateDSIException(address, true);
@ -1090,17 +1097,15 @@ bool IsOptimizableGatherPipeWrite(u32 address)
TranslateResult JitCache_TranslateAddress(u32 address) TranslateResult JitCache_TranslateAddress(u32 address)
{ {
if (!MSR.IR) if (!MSR.IR)
return TranslateResult{true, true, address}; return TranslateResult{address};
// TODO: We shouldn't use FLAG_OPCODE if the caller is the debugger. // TODO: We shouldn't use FLAG_OPCODE if the caller is the debugger.
auto tlb_addr = TranslateAddress<XCheckTLBFlag::Opcode>(address); const auto tlb_addr = TranslateAddress<XCheckTLBFlag::Opcode>(address);
if (!tlb_addr.Success()) if (!tlb_addr.Success())
{ return TranslateResult{};
return TranslateResult{false, false, 0};
}
bool from_bat = tlb_addr.result == TranslateAddressResult::BAT_TRANSLATED; const bool from_bat = tlb_addr.result == TranslateAddressResultEnum::BAT_TRANSLATED;
return TranslateResult{true, from_bat, tlb_addr.address}; return TranslateResult{from_bat, tlb_addr.address};
} }
// ********************************************************************************* // *********************************************************************************
@ -1343,12 +1348,13 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
u32 translatedAddress = 0; u32 translatedAddress = 0;
TLBLookupResult res = LookupTLBPageAddress(flag, address, &translatedAddress, wi); TLBLookupResult res = LookupTLBPageAddress(flag, address, &translatedAddress, wi);
if (res == TLBLookupResult::Found) if (res == TLBLookupResult::Found)
return TranslateAddressResult{TranslateAddressResult::PAGE_TABLE_TRANSLATED, translatedAddress}; return TranslateAddressResult{TranslateAddressResultEnum::PAGE_TABLE_TRANSLATED,
translatedAddress};
u32 sr = PowerPC::ppcState.sr[EA_SR(address)]; u32 sr = PowerPC::ppcState.sr[EA_SR(address)];
if (sr & 0x80000000) if (sr & 0x80000000)
return TranslateAddressResult{TranslateAddressResult::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.
@ -1356,7 +1362,7 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
if ((flag == XCheckTLBFlag::Opcode || flag == XCheckTLBFlag::OpcodeNoException) && if ((flag == XCheckTLBFlag::Opcode || flag == XCheckTLBFlag::OpcodeNoException) &&
(sr & 0x10000000)) (sr & 0x10000000))
{ {
return TranslateAddressResult{TranslateAddressResult::PAGE_FAULT, 0}; return TranslateAddressResult{TranslateAddressResultEnum::PAGE_FAULT, 0};
} }
u32 offset = EA_Offset(address); // 12 bit u32 offset = EA_Offset(address); // 12 bit
@ -1418,12 +1424,12 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
*wi = (PTE2.WIMG & 0b1100) != 0; *wi = (PTE2.WIMG & 0b1100) != 0;
return TranslateAddressResult{TranslateAddressResult::PAGE_TABLE_TRANSLATED, return TranslateAddressResult{TranslateAddressResultEnum::PAGE_TABLE_TRANSLATED,
(PTE2.RPN << 12) | offset}; (PTE2.RPN << 12) | offset};
} }
} }
} }
return TranslateAddressResult{TranslateAddressResult::PAGE_FAULT, 0}; return TranslateAddressResult{TranslateAddressResultEnum::PAGE_FAULT, 0};
} }
static void UpdateBATs(BatTable& bat_table, u32 base_spr) static void UpdateBATs(BatTable& bat_table, u32 base_spr)
@ -1583,7 +1589,7 @@ static TranslateAddressResult TranslateAddress(u32 address)
bool wi = false; bool wi = false;
if (TranslateBatAddess(IsOpcodeFlag(flag) ? ibat_table : dbat_table, &address, &wi)) if (TranslateBatAddess(IsOpcodeFlag(flag) ? ibat_table : dbat_table, &address, &wi))
return TranslateAddressResult{TranslateAddressResult::BAT_TRANSLATED, address, wi}; return TranslateAddressResult{TranslateAddressResultEnum::BAT_TRANSLATED, address, wi};
return TranslatePageAddress(address, flag, &wi); return TranslatePageAddress(address, flag, &wi);
} }

View File

@ -189,9 +189,17 @@ bool IsOptimizableGatherPipeWrite(u32 address);
struct TranslateResult struct TranslateResult
{ {
bool valid; bool valid = false;
bool from_bat; bool translated = false;
u32 address; bool from_bat = false;
u32 address = 0;
TranslateResult() = default;
explicit TranslateResult(u32 address_) : valid(true), address(address_) {}
TranslateResult(bool from_bat_, u32 address_)
: valid(true), translated(true), from_bat(from_bat_), address(address_)
{
}
}; };
TranslateResult JitCache_TranslateAddress(u32 address); TranslateResult JitCache_TranslateAddress(u32 address);