MMU: Get rid of pointer casts
These sort of casts invoke undefined behavior (u8, u16, u32, and u64 all have completely different alignment requirements).
This commit is contained in:
parent
9cfc671c69
commit
a58d5fa8ee
|
@ -211,26 +211,34 @@ static T ReadFromHardware(u32 em_address)
|
|||
// Handle RAM; the masking intentionally discards bits (essentially creating
|
||||
// mirrors of memory).
|
||||
// TODO: Only the first REALRAM_SIZE is supposed to be backed by actual memory.
|
||||
return bswap((*(const T*)&Memory::m_pRAM[em_address & Memory::RAM_MASK]));
|
||||
T value;
|
||||
std::memcpy(&value, &Memory::m_pRAM[em_address & Memory::RAM_MASK], sizeof(T));
|
||||
return bswap(value);
|
||||
}
|
||||
|
||||
if (Memory::m_pEXRAM && (em_address >> 28) == 0x1 &&
|
||||
(em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE)
|
||||
{
|
||||
return bswap((*(const T*)&Memory::m_pEXRAM[em_address & 0x0FFFFFFF]));
|
||||
T value;
|
||||
std::memcpy(&value, &Memory::m_pEXRAM[em_address & 0x0FFFFFFF], sizeof(T));
|
||||
return bswap(value);
|
||||
}
|
||||
|
||||
// Locked L1 technically doesn't have a fixed address, but games all use 0xE0000000.
|
||||
if ((em_address >> 28) == 0xE && (em_address < (0xE0000000 + Memory::L1_CACHE_SIZE)))
|
||||
{
|
||||
return bswap((*(const T*)&Memory::m_pL1Cache[em_address & 0x0FFFFFFF]));
|
||||
T value;
|
||||
std::memcpy(&value, &Memory::m_pL1Cache[em_address & 0x0FFFFFFF], sizeof(T));
|
||||
return bswap(value);
|
||||
}
|
||||
// In Fake-VMEM mode, we need to map the memory somewhere into
|
||||
// physical memory for BAT translation to work; we currently use
|
||||
// [0x7E000000, 0x80000000).
|
||||
if (Memory::m_pFakeVMEM && ((em_address & 0xFE000000) == 0x7E000000))
|
||||
{
|
||||
return bswap(*(T*)&Memory::m_pFakeVMEM[em_address & Memory::RAM_MASK]);
|
||||
T value;
|
||||
std::memcpy(&value, &Memory::m_pFakeVMEM[em_address & Memory::RAM_MASK], sizeof(T));
|
||||
return bswap(value);
|
||||
}
|
||||
|
||||
if (flag == FLAG_READ && (em_address & 0xF8000000) == 0x08000000)
|
||||
|
@ -292,21 +300,24 @@ static void WriteToHardware(u32 em_address, const T data)
|
|||
// Handle RAM; the masking intentionally discards bits (essentially creating
|
||||
// mirrors of memory).
|
||||
// TODO: Only the first REALRAM_SIZE is supposed to be backed by actual memory.
|
||||
*(T*)&Memory::m_pRAM[em_address & Memory::RAM_MASK] = bswap(data);
|
||||
const T swapped_data = bswap(data);
|
||||
std::memcpy(&Memory::m_pRAM[em_address & Memory::RAM_MASK], &swapped_data, sizeof(T));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Memory::m_pEXRAM && (em_address >> 28) == 0x1 &&
|
||||
(em_address & 0x0FFFFFFF) < Memory::EXRAM_SIZE)
|
||||
{
|
||||
*(T*)&Memory::m_pEXRAM[em_address & 0x0FFFFFFF] = bswap(data);
|
||||
const T swapped_data = bswap(data);
|
||||
std::memcpy(&Memory::m_pEXRAM[em_address & 0x0FFFFFFF], &swapped_data, sizeof(T));
|
||||
return;
|
||||
}
|
||||
|
||||
// Locked L1 technically doesn't have a fixed address, but games all use 0xE0000000.
|
||||
if ((em_address >> 28 == 0xE) && (em_address < (0xE0000000 + Memory::L1_CACHE_SIZE)))
|
||||
{
|
||||
*(T*)&Memory::m_pL1Cache[em_address & 0x0FFFFFFF] = bswap(data);
|
||||
const T swapped_data = bswap(data);
|
||||
std::memcpy(&Memory::m_pL1Cache[em_address & 0x0FFFFFFF], &swapped_data, sizeof(T));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -315,7 +326,8 @@ static void WriteToHardware(u32 em_address, const T data)
|
|||
// [0x7E000000, 0x80000000).
|
||||
if (Memory::m_pFakeVMEM && ((em_address & 0xFE000000) == 0x7E000000))
|
||||
{
|
||||
*(T*)&Memory::m_pFakeVMEM[em_address & Memory::RAM_MASK] = bswap(data);
|
||||
const T swapped_data = bswap(data);
|
||||
std::memcpy(&Memory::m_pFakeVMEM[em_address & Memory::RAM_MASK], &swapped_data, sizeof(T));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -399,7 +411,7 @@ TryReadInstResult TryReadInstruction(u32 address)
|
|||
// TODO: Refactor this. This icache implementation is totally wrong if used with the fake vmem.
|
||||
if (Memory::m_pFakeVMEM && ((address & 0xFE000000) == 0x7E000000))
|
||||
{
|
||||
hex = bswap(*(const u32*)&Memory::m_pFakeVMEM[address & Memory::FAKEVMEM_MASK]);
|
||||
hex = Common::swap32(&Memory::m_pFakeVMEM[address & Memory::FAKEVMEM_MASK]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -666,7 +678,7 @@ void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks)
|
|||
{
|
||||
for (u32 i = 0; i < 32 * numBlocks; i += 4)
|
||||
{
|
||||
u32 data = bswap(*(u32*)(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF)));
|
||||
const u32 data = Common::swap32(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF));
|
||||
EFB_Write(data, memAddr + i);
|
||||
}
|
||||
return;
|
||||
|
@ -678,7 +690,7 @@ void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks)
|
|||
{
|
||||
for (u32 i = 0; i < 32 * numBlocks; i += 4)
|
||||
{
|
||||
u32 data = bswap(*(u32*)(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF)));
|
||||
const u32 data = Common::swap32(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF));
|
||||
Memory::mmio_mapping->Write(memAddr + i, data);
|
||||
}
|
||||
return;
|
||||
|
@ -703,8 +715,8 @@ void DMA_MemoryToLC(const u32 cacheAddr, const u32 memAddr, const u32 numBlocks)
|
|||
{
|
||||
for (u32 i = 0; i < 32 * numBlocks; i += 4)
|
||||
{
|
||||
u32 data = EFB_Read(memAddr + i);
|
||||
*(u32*)(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF)) = bswap(data);
|
||||
const u32 data = Common::swap32(EFB_Read(memAddr + i));
|
||||
std::memcpy(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF), &data, sizeof(u32));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -715,8 +727,8 @@ void DMA_MemoryToLC(const u32 cacheAddr, const u32 memAddr, const u32 numBlocks)
|
|||
{
|
||||
for (u32 i = 0; i < 32 * numBlocks; i += 4)
|
||||
{
|
||||
u32 data = Memory::mmio_mapping->Read<u32>(memAddr + i);
|
||||
*(u32*)(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF)) = bswap(data);
|
||||
const u32 data = Common::swap32(Memory::mmio_mapping->Read<u32>(memAddr + i));
|
||||
std::memcpy(Memory::m_pL1Cache + ((cacheAddr + i) & 0x3FFFF), &data, sizeof(u32));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1073,7 +1085,7 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
|
|||
|
||||
// hash function no 1 "xor" .360
|
||||
u32 hash = (VSID ^ page_index);
|
||||
u32 pte1 = bswap((VSID << 7) | api | PTE1_V);
|
||||
u32 pte1 = Common::swap32((VSID << 7) | api | PTE1_V);
|
||||
|
||||
for (int hash_func = 0; hash_func < 2; hash_func++)
|
||||
{
|
||||
|
@ -1089,10 +1101,13 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
|
|||
|
||||
for (int i = 0; i < 8; i++, pteg_addr += 8)
|
||||
{
|
||||
if (pte1 == *(u32*)&Memory::physical_base[pteg_addr])
|
||||
u32 pteg;
|
||||
std::memcpy(&pteg, &Memory::physical_base[pteg_addr], sizeof(u32));
|
||||
|
||||
if (pte1 == pteg)
|
||||
{
|
||||
UPTE2 PTE2;
|
||||
PTE2.Hex = bswap((*(u32*)&Memory::physical_base[pteg_addr + 4]));
|
||||
PTE2.Hex = Common::swap32(&Memory::physical_base[pteg_addr + 4]);
|
||||
|
||||
// set the access bits
|
||||
switch (flag)
|
||||
|
@ -1113,7 +1128,10 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
|
|||
}
|
||||
|
||||
if (!IsNoExceptionFlag(flag))
|
||||
*(u32*)&Memory::physical_base[pteg_addr + 4] = bswap(PTE2.Hex);
|
||||
{
|
||||
const u32 swapped_pte2 = Common::swap32(PTE2.Hex);
|
||||
std::memcpy(&Memory::physical_base[pteg_addr + 4], &swapped_pte2, sizeof(u32));
|
||||
}
|
||||
|
||||
// We already updated the TLB entry if this was caused by a C bit.
|
||||
if (res != TLB_UPDATE_C)
|
||||
|
|
Loading…
Reference in New Issue