drkIIRaziel reversed engineered the frsqrte instruction providing hardware accurate emulation.

The algorithm and lookup table are 99% accurate which is far better than the approximation that Dolphin had previously.

The frsqrte instruction is used for a lot of 3D graphics functions so this change may help fix graphics glitches.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4864 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
skidau 2010-01-17 04:29:44 +00:00
parent 703cb0bdb8
commit 59e7c19380
5 changed files with 21933 additions and 2 deletions

View File

@ -939,6 +939,14 @@
RelativePath=".\Src\PowerPC\Gekko.h" RelativePath=".\Src\PowerPC\Gekko.h"
> >
</File> </File>
<File
RelativePath=".\Src\PowerPC\LUT_frsqrtex.cpp"
>
</File>
<File
RelativePath=".\Src\PowerPC\LUT_frsqrtex.h"
>
</File>
<File <File
RelativePath=".\Src\PowerPC\PowerPC.cpp" RelativePath=".\Src\PowerPC\PowerPC.cpp"
> >
@ -1029,6 +1037,14 @@
AssemblerOutput="4" AssemblerOutput="4"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Debug_JITIL|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\Src\PowerPC\Interpreter\Interpreter_FPUtils.h" RelativePath=".\Src\PowerPC\Interpreter\Interpreter_FPUtils.h"

View File

@ -36,6 +36,7 @@
#include "Interpreter.h" #include "Interpreter.h"
#include "MathUtil.h" #include "MathUtil.h"
#include "Interpreter_FPUtils.h" #include "Interpreter_FPUtils.h"
#include "../LUT_frsqrtex.h"
using namespace MathUtil; using namespace MathUtil;
@ -414,8 +415,27 @@ void frsqrtex(UGeckoInstruction _inst)
} }
else else
{ {
if (b == 0.0) SetFPException(FPSCR_ZX); if (b == 0.0) {
rPS0(_inst.FD) = ForceDouble(1.0 / sqrt(b)); SetFPException(FPSCR_ZX);
riPS0(_inst.FD) = 0x7ff0000000000000;
}
else
{
u32 fsa = Common::swap32(Common::swap64(riPS0(_inst.FB)));
u32 fsb = Common::swap32(Common::swap64(riPS0(_inst.FB)) >> 32);
u32 idx=(fsa >> 5) % (sizeof(frsqrtex_lut) / sizeof(frsqrtex_lut[0]));
s32 e = fsa >> (32-12);
e &= 2047;
e -= 1023;
s32 oe =- ((e + 1) / 2);
oe -= ((e + 1) & 1);
u32 outb = frsqrtex_lut[idx] << 20;
u32 outa = ((oe + 1023) & 2047) << 20;
outa |= frsqrtex_lut[idx] >> 12;
riPS0(_inst.FD) = ((u64)outa << 32) + (u64)outb;
}
} }
UpdateFPRF(rPS0(_inst.FD)); UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
// Gekko related unions, structs, ...
//
#ifndef _LUT_frsqrtex_h_
#define _LUT_frsqrtex_h_
extern const unsigned int frsqrtex_lut[65536];
#endif //_LUT_frsqrtex_h_

View File

@ -73,6 +73,7 @@ files = ["ActionReplay.cpp",
"PowerPC/PowerPC.cpp", "PowerPC/PowerPC.cpp",
"PowerPC/PPCAnalyst.cpp", "PowerPC/PPCAnalyst.cpp",
"PowerPC/PPCTables.cpp", "PowerPC/PPCTables.cpp",
"PowerPC/LUT_frsqrtex.cpp",
"PowerPC/PPCCache.cpp", "PowerPC/PPCCache.cpp",
"PowerPC/Profiler.cpp", "PowerPC/Profiler.cpp",
"PowerPC/SignatureDB.cpp", "PowerPC/SignatureDB.cpp",