Fix EFB reads in fastmem mode by removing the EFB mapping (forces it to go through the right handlers). Enable fastmem mode in x64. 1-2% speed boost overall maybe :p

Disable the Redundant MOV warning in release mode, it's only enabled in debug builds now.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4870 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2010-01-17 21:28:39 +00:00
parent 3e01152793
commit 53408a695f
6 changed files with 35 additions and 23 deletions

View file

@ -927,8 +927,10 @@ void XEmitter::OR (int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(t
void XEmitter::XOR (int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(this, bits, nrmXOR, a1, a2);} void XEmitter::XOR (int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(this, bits, nrmXOR, a1, a2);}
void XEmitter::MOV (int bits, const OpArg &a1, const OpArg &a2) void XEmitter::MOV (int bits, const OpArg &a1, const OpArg &a2)
{ {
_assert_msg_(DYNA_REC, !a1.IsSimpleReg() || !a2.IsSimpleReg() || a1.GetSimpleReg() != a2.GetSimpleReg(), "Redundant MOV @ %p", #ifdef _DEBUG
_assert_msg_(DYNA_REC, !a1.IsSimpleReg() || !a2.IsSimpleReg() || a1.GetSimpleReg() != a2.GetSimpleReg(), "Redundant MOV @ %p - bug in JIT?",
code); code);
#endif
WriteNormalOp(this, bits, nrmMOV, a1, a2); WriteNormalOp(this, bits, nrmMOV, a1, a2);
} }
void XEmitter::TEST(int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(this, bits, nrmTEST, a1, a2);} void XEmitter::TEST(int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(this, bits, nrmTEST, a1, a2);}

View file

@ -78,7 +78,6 @@ bool m_IsInitialized = false; // Save the Init(), Shutdown() state
// 64-bit: Pointers to low-mem (sub-0x10000000) mirror // 64-bit: Pointers to low-mem (sub-0x10000000) mirror
// 32-bit: Same as the corresponding physical/virtual pointers. // 32-bit: Same as the corresponding physical/virtual pointers.
u8 *m_pRAM; u8 *m_pRAM;
u8 *m_pEFB;
u8 *m_pL1Cache; u8 *m_pL1Cache;
u8 *m_pEXRAM; u8 *m_pEXRAM;
u8 *m_pFakeVMEM; u8 *m_pFakeVMEM;
@ -329,7 +328,9 @@ static const MemoryView views[] =
{NULL, &m_pVirtualCachedRAM, 0x80000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, {NULL, &m_pVirtualCachedRAM, 0x80000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
{NULL, &m_pVirtualUncachedRAM, 0xC0000000, RAM_SIZE, MV_MIRROR_PREVIOUS}, {NULL, &m_pVirtualUncachedRAM, 0xC0000000, RAM_SIZE, MV_MIRROR_PREVIOUS},
{&m_pEFB, &m_pVirtualEFB, 0xC8000000, EFB_SIZE, 0}, // Don't map any memory for the EFB. We want all access to this area to go
// through the hardware access handlers.
// {&m_pEFB, &m_pVirtualEFB, 0xC8000000, EFB_SIZE, 0},
{&m_pL1Cache, &m_pVirtualL1Cache, 0xE0000000, L1_CACHE_SIZE, 0}, {&m_pL1Cache, &m_pVirtualL1Cache, 0xE0000000, L1_CACHE_SIZE, 0},
{&m_pFakeVMEM, &m_pVirtualFakeVMEM, 0x7E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM}, {&m_pFakeVMEM, &m_pVirtualFakeVMEM, 0x7E000000, FAKEVMEM_SIZE, MV_FAKE_VMEM},
@ -390,8 +391,6 @@ void Clear()
memset(m_pRAM, 0, RAM_SIZE); memset(m_pRAM, 0, RAM_SIZE);
if (m_pL1Cache) if (m_pL1Cache)
memset(m_pL1Cache, 0, L1_CACHE_SIZE); memset(m_pL1Cache, 0, L1_CACHE_SIZE);
if (m_pEFB)
memset(m_pEFB, 0, EFB_SIZE);
if (Core::GetStartupParameter().bWii && m_pEXRAM) if (Core::GetStartupParameter().bWii && m_pEXRAM)
memset(m_pEXRAM, 0, EXRAM_SIZE); memset(m_pEXRAM, 0, EXRAM_SIZE);
} }
@ -777,7 +776,8 @@ u8 *GetPointer(const u32 _Address)
return 0; return 0;
case 0xC8: case 0xC8:
return m_pEFB + (_Address & 0xFFFFFF); return 0; // EFB. We don't want to return a pointer here since we have no memory mapped for it.
case 0xCC: case 0xCC:
case 0xCD: case 0xCD:
_dbg_assert_msg_(MEMMAP, 0, "Memory", "GetPointer from IO Bridge doesnt work"); _dbg_assert_msg_(MEMMAP, 0, "Memory", "GetPointer from IO Bridge doesnt work");

View file

@ -135,9 +135,12 @@ u32 Read_U32(const u32 _Address);
u64 Read_U64(const u32 _Address); u64 Read_U64(const u32 _Address);
// used by JIT. Return zero-extended 32bit values // used by JIT. Return zero-extended 32bit values
u32 Read_U8_ZX(const u32 _Address); u32 Read_U8_ZX(const u32 _Address);
u32 Read_U16_ZX(const u32 _Address); u32 Read_U16_ZX(const u32 _Address);
// used by JIT (Jit64::lXz)
u32 EFB_Read(const u32 addr);
void Write_U8(const u8 _Data, const u32 _Address); void Write_U8(const u8 _Data, const u32 _Address);
void Write_U16(const u16 _Data, const u32 _Address); void Write_U16(const u16 _Data, const u32 _Address);
void Write_U32(const u32 _Data, const u32 _Address); void Write_U32(const u32 _Data, const u32 _Address);

View file

@ -125,6 +125,26 @@ inline void hwWriteIOBridge(u16 var, u32 addr) {WII_IOBridge::Write16(var, addr)
inline void hwWriteIOBridge(u32 var, u32 addr) {WII_IOBridge::Write32(var, addr);} inline void hwWriteIOBridge(u32 var, u32 addr) {WII_IOBridge::Write32(var, addr);}
inline void hwWriteIOBridge(u64 var, u32 addr) {PanicAlert("hwWriteIOBridge: There's no 64-bit HW write. %08x", addr);} inline void hwWriteIOBridge(u64 var, u32 addr) {PanicAlert("hwWriteIOBridge: There's no 64-bit HW write. %08x", addr);}
// Nasty but necessary. Super Mario Galaxy pointer relies on this stuff.
u32 EFB_Read(const u32 addr)
{
u32 var = 0;
// Convert address to coordinates. It's possible that this should be done
// differently depending on color depth, especially regarding PEEK_COLOR.
int x = (addr & 0xfff) >> 2;
int y = (addr >> 12) & 0x3ff;
if (addr & 0x00400000) {
var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(PEEK_Z, x, y);
DEBUG_LOG(MEMMAP, "EFB Z Read @ %i, %i\t= 0x%08x", x, y, var);
} else {
var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(PEEK_COLOR, x, y);
DEBUG_LOG(MEMMAP, "EFB Color Read @ %i, %i\t= 0x%08x", x, y, var);
}
return var;
}
template <class T> template <class T>
inline void ReadFromHardware(T &_var, u32 em_address, u32 effective_address, Memory::XCheckTLBFlag flag) inline void ReadFromHardware(T &_var, u32 em_address, u32 effective_address, Memory::XCheckTLBFlag flag)
{ {
@ -132,17 +152,7 @@ inline void ReadFromHardware(T &_var, u32 em_address, u32 effective_address, Mem
if ((em_address & 0xC8000000) == 0xC8000000) if ((em_address & 0xC8000000) == 0xC8000000)
{ {
if (em_address < 0xcc000000) if (em_address < 0xcc000000)
{ _var = EFB_Read(em_address);
int x = (em_address & 0xfff) >> 2;
int y = (em_address >> 12) & 0x3ff;
if (em_address & 0x00400000) {
_var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(PEEK_Z, x, y);
DEBUG_LOG(MEMMAP, "EFB Z Read @ %i, %i\t= 0x%08x", x, y, _var);
} else {
_var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(PEEK_COLOR, x, y);
DEBUG_LOG(MEMMAP, "EFB Color Read @ %i, %i\t= 0x%08x", x, y, _var);
}
}
else if (em_address <= 0xcc009000) else if (em_address <= 0xcc009000)
hwRead(_var, em_address); hwRead(_var, em_address);
/* WIIMODE */ /* WIIMODE */
@ -356,7 +366,6 @@ u32 Read_U32(const u32 _Address)
return _var; return _var;
} }
u64 Read_U64(const u32 _Address) u64 Read_U64(const u32 _Address)
{ {
u64 _var = 0; u64 _var = 0;

View file

@ -405,8 +405,6 @@ void fresx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
// #define USE_ACCURATE_FRSQRTEX
void frsqrtex(UGeckoInstruction _inst) void frsqrtex(UGeckoInstruction _inst)
{ {
double b = rPS0(_inst.FB); double b = rPS0(_inst.FB);
@ -417,7 +415,7 @@ void frsqrtex(UGeckoInstruction _inst)
} }
else else
{ {
#ifdef USE_ACCURATE_FRSQRTEX #ifdef VERY_ACCURATE_FP
if (b == 0.0) { if (b == 0.0) {
SetFPException(FPSCR_ZX); SetFPException(FPSCR_ZX);
riPS0(_inst.FD) = 0x7ff0000000000000; riPS0(_inst.FD) = 0x7ff0000000000000;

View file

@ -193,7 +193,7 @@ void Jit64::lXz(UGeckoInstruction inst)
} }
//Still here? Do regular path. //Still here? Do regular path.
#if defined(_M_X64) && 0 // This is disabled, it's unaccurate #if defined(_M_X64)
if (accessSize == 8 || accessSize == 16 || !jo.enableFastMem) { if (accessSize == 8 || accessSize == 16 || !jo.enableFastMem) {
#else #else
if (true) { if (true) {