Cleaning up XK's mess, added a simple profiler, minor disasm fix. Too lazy to split it up into individual changes. Savestates not yet working.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@381 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2008-08-30 12:11:25 +00:00
parent 838f37112e
commit ff0a613427
68 changed files with 421 additions and 1018 deletions

View File

@ -775,10 +775,6 @@
RelativePath="..\..\PluginSpecs\PluginSpecs.h"
>
</File>
<File
RelativePath="..\..\PluginSpecs\pluginspecs_compiler.h"
>
</File>
<File
RelativePath="..\..\PluginSpecs\pluginspecs_dsp.h"
>
@ -824,6 +820,14 @@
RelativePath=".\Src\PowerPC\PPCTables.h"
>
</File>
<File
RelativePath=".\Src\PowerPC\Profiler.cpp"
>
</File>
<File
RelativePath=".\Src\PowerPC\Profiler.h"
>
</File>
<File
RelativePath=".\Src\PowerPC\SignatureDB.cpp"
>

View File

@ -71,16 +71,14 @@ void UnregisterAllEvents()
event_types.clear();
}
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
externalEventSection.Enter();
f.Descend("TIME");
f.Do(downcount);
f.Do(slicelength);
f.Do(maxSliceLength);
f.Do(globalTimer);
f.Do(idledCycles);
f.Ascend();
p.Do(downcount);
p.Do(slicelength);
p.Do(maxSliceLength);
p.Do(globalTimer);
p.Do(idledCycles);
externalEventSection.Leave();
}

View File

@ -35,7 +35,7 @@ typedef void (*TimedCallback)(u64 userdata, int cyclesLate);
u64 GetTicks();
u64 GetIdleTicks();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
// The int that the callbacks get is how many cycles late it was.
// So to schedule a new event on a regular basis:
// inside callback:

View File

@ -94,15 +94,13 @@ static int g_SampleRate = 32000;
static int g_DSPSampleRate = 32000;
static u64 g_CPUCyclesPerSample = 0xFFFFFFFFFFFULL;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("AI ");
f.Do(g_AudioRegister);
f.Do(g_LastCPUTime);
f.Do(g_SampleRate);
f.Do(g_DSPSampleRate);
f.Do(g_CPUCyclesPerSample);
f.Ascend();
p.Do(g_AudioRegister);
p.Do(g_LastCPUTime);
p.Do(g_SampleRate);
p.Do(g_DSPSampleRate);
p.Do(g_CPUCyclesPerSample);
}
void GenerateAudioInterrupt();

View File

@ -20,14 +20,14 @@
#ifndef _AUDIOINTERFACE_H
#define _AUDIOINTERFACE_H
class ChunkFile;
class PointerWrap;
namespace AudioInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Update();

View File

@ -105,19 +105,17 @@ u16 m_tokenReg;
CPFifo fifo; //This one is shared between gfx thread and emulator thread
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("CP ");
f.Do(m_CPStatusReg);
f.Do(m_CPCtrlReg);
f.Do(m_CPClearReg);
f.Do(m_bboxleft);
f.Do(m_bboxtop);
f.Do(m_bboxright);
f.Do(m_bboxbottom);
f.Do(m_tokenReg);
f.Do(fifo);
f.Ascend();
p.Do(m_CPStatusReg);
p.Do(m_CPCtrlReg);
p.Do(m_CPClearReg);
p.Do(m_bboxleft);
p.Do(m_bboxtop);
p.Do(m_bboxright);
p.Do(m_bboxbottom);
p.Do(m_tokenReg);
p.Do(fifo);
}
// function

View File

@ -19,7 +19,7 @@
#define _COMMANDPROCESSOR_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
#ifdef _WIN32
#include <windows.h>
@ -82,7 +82,7 @@ extern CPFifo fifo;
// Init
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
// Read
void HWCALL Read16(u16& _rReturnValue, const u32 _Address);

View File

@ -175,16 +175,14 @@ u16 g_AR_MODE = 0x43; // 0x23 -> Zelda standard mode (standard ARAM access ??)
// 0x43 -> written by OSAudioInit at the UCode upload (upload UCode)
// 0x63 -> ARCheckSize Mode (access AR-registers ??) or no exception ??
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("DSP ");
f.Do(g_ARAM, ARAM_SIZE);
f.Do(g_dspState);
f.Do(g_audioDMA);
f.Do(g_arDMA);
f.Do(g_AR_READY_FLAG);
f.Do(g_AR_MODE);
f.Ascend();
p.DoArray(g_ARAM, ARAM_SIZE);
p.Do(g_dspState);
p.Do(g_audioDMA);
p.Do(g_arDMA);
p.Do(g_AR_READY_FLAG);
p.Do(g_AR_MODE);
}

View File

@ -19,7 +19,7 @@
#define _DSPINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace DSP
{
@ -33,7 +33,7 @@ enum DSPInterruptType
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void GenerateDSPInterrupt(DSPInterruptType _DSPInterruptType, bool _bSet = true);
void GenerateDSPInterruptFromPlugin(DSPInterruptType _DSPInterruptType, bool _bSet = true);

View File

@ -178,13 +178,11 @@ DVDMemStruct dvdMem;
u32 g_ErrorCode = 0x00;
bool g_bDiscInside = true;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("DI ");
f.Do(dvdMem);
f.Do(g_ErrorCode);
f.Do(g_bDiscInside);
f.Ascend();
p.Do(dvdMem);
p.Do(g_ErrorCode);
p.Do(g_bDiscInside);
}
void UpdateInterrupts();

View File

@ -19,14 +19,14 @@
#define _DVDINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace DVDInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void SetDiscInside(bool _DiscInside);

View File

@ -53,11 +53,9 @@ void Shutdown()
g_Channels = 0;
}
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("EXI ");
// TODO: descend all the devices recursively.
f.Ascend();
}
void Update()

View File

@ -18,14 +18,14 @@
#define _EXIINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace ExpansionInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Update();
void UpdateInterrupts();

View File

@ -44,12 +44,10 @@ u8 GC_ALIGNED32(m_gatherPipe[GATHER_PIPE_SIZE*16]); //more room, for the fastmod
// pipe counter
u32 m_gatherPipeCount = 0;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("FIFO");
f.Do(m_gatherPipe);
f.Do(m_gatherPipeCount);
f.Ascend();
p.Do(m_gatherPipe);
p.Do(m_gatherPipeCount);
}
void Init()

View File

@ -19,7 +19,7 @@
#define _GPFIFO_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace GPFifo
{
@ -36,7 +36,7 @@ extern u32 m_gatherPipeCount;
// Init
void Init();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
// ResetGatherPipe
void ResetGatherPipe();

View File

@ -87,21 +87,19 @@ namespace HW
CoreTiming::UnregisterAllEvents();
}
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("HWst");
PixelEngine::DoState(f);
CommandProcessor::DoState(f);
VideoInterface::DoState(f);
SerialInterface::DoState(f);
CPeripheralInterface::DoState(f);
DSP::DoState(f);
DVDInterface::DoState(f);
GPFifo::DoState(f);
ExpansionInterface::DoState(f);
AudioInterface::DoState(f);
CoreTiming::DoState(f);
WII_IPCInterface::DoState(f);
f.Ascend();
PixelEngine::DoState(p);
CommandProcessor::DoState(p);
VideoInterface::DoState(p);
SerialInterface::DoState(p);
CPeripheralInterface::DoState(p);
DSP::DoState(p);
DVDInterface::DoState(p);
GPFifo::DoState(p);
ExpansionInterface::DoState(p);
AudioInterface::DoState(p);
CoreTiming::DoState(p);
WII_IPCInterface::DoState(p);
}
}

View File

@ -25,7 +25,7 @@ namespace HW
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
}
#endif

View File

@ -21,7 +21,7 @@
#include "Common.h"
class ChunkFile;
class PointerWrap;
typedef void (HWCALL *writeFn8 )(const u8, const u32);
typedef void (HWCALL *writeFn16)(const u16,const u32);
@ -65,7 +65,7 @@ namespace Memory
bool IsInitialized();
bool Init();
bool Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Clear();
bool AreMemoryBreakpointsActivated();

View File

@ -50,11 +50,9 @@ struct MIMemStruct
// STATE_TO_SAVE
static MIMemStruct miMem;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("MI ");
f.Do(miMem);
f.Ascend();
p.Do(miMem);
}
void Read16(u16& _uReturnValue, const u32 _iAddress)

View File

@ -18,11 +18,11 @@
#define _MEMORYINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace MemoryInterface
{
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);

View File

@ -33,15 +33,13 @@ u32 CPeripheralInterface::Fifo_CPUBase;
u32 CPeripheralInterface::Fifo_CPUEnd;
u32 CPeripheralInterface::Fifo_CPUWritePointer;
void CPeripheralInterface::DoState(ChunkFile &f)
void CPeripheralInterface::DoState(PointerWrap &p)
{
f.Descend("PI ");
f.Do(m_InterruptMask);
f.Do(m_InterruptCause);
f.Do(Fifo_CPUBase);
f.Do(Fifo_CPUEnd);
f.Do(Fifo_CPUWritePointer);
f.Ascend();
p.Do(m_InterruptMask);
p.Do(m_InterruptCause);
p.Do(Fifo_CPUBase);
p.Do(Fifo_CPUEnd);
p.Do(Fifo_CPUWritePointer);
}
void CPeripheralInterface::Init()

View File

@ -19,7 +19,7 @@
#define _PERIPHERALINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
//
// PERIPHERALINTERFACE
@ -98,7 +98,7 @@ public:
static u32 Fifo_CPUWritePointer;
static void Init();
static void DoState(ChunkFile &f);
static void DoState(PointerWrap &p);
static void SetInterrupt(InterruptCause _causemask, bool _bSet=true);

View File

@ -63,14 +63,12 @@ static bool g_bSignalFinishInterrupt;
int et_SetTokenOnMainThread;
int et_SetFinishOnMainThread;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("PE ");
f.Do(g_ctrlReg);
f.Do(g_token);
f.Do(g_bSignalTokenInterrupt);
f.Do(g_bSignalFinishInterrupt);
f.Ascend();
p.Do(g_ctrlReg);
p.Do(g_token);
p.Do(g_bSignalTokenInterrupt);
p.Do(g_bSignalFinishInterrupt);
}
void UpdateInterrupts();

View File

@ -18,12 +18,12 @@
#define _PIXELENGINE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace PixelEngine
{
void Init();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
// Read
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);

View File

@ -218,16 +218,14 @@ static USIStatusReg g_StatusReg;
static USIEXIClockCount g_EXIClockCount;
static u8 g_SIBuffer[128];
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("SI ");
f.Do(g_Channel);
f.Do(g_Poll);
f.Do(g_ComCSR);
f.Do(g_StatusReg);
f.Do(g_EXIClockCount);
f.Do(g_SIBuffer);
f.Ascend();
p.Do(g_Channel);
p.Do(g_Poll);
p.Do(g_ComCSR);
p.Do(g_StatusReg);
p.Do(g_EXIClockCount);
p.Do(g_SIBuffer);
}
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt);

View File

@ -19,14 +19,14 @@
#define _SERIALINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace SerialInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void UpdateDevices();

View File

@ -19,7 +19,7 @@
#define _SERIALINTERFACE_DEVICES_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
class ISIDevice
{

View File

@ -12,7 +12,7 @@
#define _STREAMADPCM_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
#define ONE_BLOCK_SIZE 32
#define SAMPLES_PER_BLOCK 28

View File

@ -104,20 +104,18 @@ static u32 TicksPerFrame = 0;
static u32 LineCount = 0;
static u64 LastTime = 0;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("VI ");
f.Do(m_VIDisplayControlRegister);
f.Do(m_FrameBuffer1);
f.Do(m_FrameBuffer2);
f.Do(m_VIInterruptRegister);
f.Do(m_UVIUnknownRegs, 0x1000);
f.Do(HorizontalBeamPos);
f.Do(VerticalBeamPos);
f.Do(TicksPerFrame);
f.Do(LineCount);
f.Do(LastTime);
f.Ascend();
p.Do(m_VIDisplayControlRegister);
p.Do(m_FrameBuffer1);
p.Do(m_FrameBuffer2);
p.Do(m_VIInterruptRegister);
p.DoArray(m_UVIUnknownRegs, 0x1000);
p.Do(HorizontalBeamPos);
p.Do(VerticalBeamPos);
p.Do(TicksPerFrame);
p.Do(LineCount);
p.Do(LastTime);
}
void Init()

View File

@ -18,7 +18,7 @@
#define _VIDEOINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace VideoInterface
{
@ -31,7 +31,7 @@ namespace VideoInterface
};
void Init();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void HWCALL Read16(u16& _uReturnValue, const u32 _uAddress);
void HWCALL Read32(u32& _uReturnValue, const u32 _uAddress);

View File

@ -18,14 +18,14 @@
#define _WII_IOBRIDGE_H_
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace WII_IOBridge
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Update();

View File

@ -93,16 +93,14 @@ u32 g_Address = 0;
u32 g_Reply = 0;
u32 g_SensorBarPower = 0;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("WIPC");
f.Do(g_IPC_Status);
f.Do(g_IPC_Config);
f.Do(g_IPC_Control);
f.Do(g_Address);
f.Do(g_Reply);
f.Do(g_SensorBarPower);
f.Ascend();
p.Do(g_IPC_Status);
p.Do(g_IPC_Config);
p.Do(g_IPC_Control);
p.Do(g_Address);
p.Do(g_Reply);
p.Do(g_SensorBarPower);
}
void UpdateInterrupts();

View File

@ -18,14 +18,14 @@
#define _WII_IPC_H_
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace WII_IPCInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Update();
bool IsReady();

View File

@ -32,10 +32,8 @@ typedef void (__cdecl* TVideo_SendFifoData)(BYTE*);
typedef void (__cdecl* TVideo_UpdateXFB)(BYTE*, DWORD, DWORD);
typedef BOOL (__cdecl* TVideo_Screenshot)(TCHAR*);
typedef void (__cdecl* TVideo_EnterLoop)();
typedef void (__cdecl* TVideo_AddMessage)(const char* pstr, unsigned int milliseconds);
typedef void (__cdecl* TVideo_DoState)(ChunkFile &f);
typedef void (__cdecl* TVideo_DoState)(unsigned char **ptr, int mode);
//! Function Pointer
TGetDllInfo g_GetDllInfo = 0;
@ -49,7 +47,7 @@ TVideo_UpdateXFB g_Video_UpdateXFB = 0;
TVideo_Screenshot g_Video_Screenshot = 0;
TVideo_EnterLoop g_Video_EnterLoop = 0;
TVideo_AddMessage g_Video_AddMessage = 0;
TVideo_DoState g_Video_DoState = 0;
TVideo_DoState g_Video_DoState = 0;
//! Library Instance
DynamicLibrary plugin;
@ -91,7 +89,7 @@ bool LoadPlugin(const char *_Filename)
g_Video_Screenshot = reinterpret_cast<TVideo_Screenshot> (plugin.Get("Video_Screenshot"));
g_Video_EnterLoop = reinterpret_cast<TVideo_EnterLoop> (plugin.Get("Video_EnterLoop"));
g_Video_AddMessage = reinterpret_cast<TVideo_AddMessage> (plugin.Get("Video_AddMessage"));
g_Video_DoState = reinterpret_cast<TVideo_DoState> (plugin.Get("Video_DoState"));
g_Video_DoState = reinterpret_cast<TVideo_DoState> (plugin.Get("Video_DoState"));
if ((g_GetDllInfo != 0) &&
(g_DllAbout != 0) &&
@ -176,8 +174,8 @@ void Video_AddMessage(const char* pstr, unsigned int milliseconds)
g_Video_AddMessage(pstr,milliseconds);
}
void Video_DoState(ChunkFile &f) {
g_Video_DoState(f);
void Video_DoState(unsigned char **ptr, int mode) {
g_Video_DoState(ptr, mode);
}
} // end of namespace PluginVideo

View File

@ -44,7 +44,7 @@ void Video_UpdateXFB(BYTE* _pXFB, DWORD _dwHeight, DWORD _dwWidth);
bool Video_Screenshot(TCHAR* _szFilename);
void Video_AddMessage(const char* pstr, unsigned int milliseconds);
void Video_DoState(ChunkFile &f);
void Video_DoState(unsigned char **ptr, int mode);
} // end of namespace PluginVideo

View File

@ -317,15 +317,8 @@ void orcx(UGeckoInstruction _inst)
void slwx(UGeckoInstruction _inst)
{
// TODO(ector): wtf is this code?
/* u32 amount = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (amount&0x20) ? 0 : m_GPR[_inst.RS] << amount;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
*/
u32 nBits = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (nBits < 32) ? m_GPR[_inst.RS] << nBits : 0;
u32 amount = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : m_GPR[_inst.RS] << amount;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
@ -393,7 +386,7 @@ void srawix(UGeckoInstruction _inst)
void srwx(UGeckoInstruction _inst)
{
u32 amount = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> amount);
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> (amount & 0x1f));
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}

View File

@ -25,6 +25,7 @@
#include "../../Core.h"
#include "../../CoreTiming.h"
#include "../PowerPC.h"
#include "../Profiler.h"
#include "../PPCTables.h"
#include "../PPCAnalyst.h"
#include "../../HW/Memmap.h"
@ -375,6 +376,7 @@ namespace Jit64
PPCAnalyst::CodeOp *ops = PPCAnalyst::Flatten(emaddress, size, js.st, js.gpa, js.fpa);
const u8 *start = AlignCode4(); //TODO: Test if this or AlignCode16 make a difference from GetCodePtr
b.checkedEntry = start;
b.runCount = 0;
FixupBranch skip = J_CC(CC_NBE);
MOV(32, M(&PC), Imm32(js.blockStart));
JMP(Asm::doTiming, true);
@ -393,6 +395,10 @@ namespace Jit64
SetJumpTarget(b1);
}
if (Profiler::g_ProfileBlocks) {
ADD(32, M(&b.runCount), Imm8(1));
}
//Start up the register allocators
//They use the information in gpa/fpa to preload commonly used registers.
gpr.Start(js.gpa);

View File

@ -186,14 +186,8 @@ void Generate()
enterCode = AlignCode16();
ABI_PushAllCalleeSavedRegsAndAdjustStack();
// INT3();
MOV(64, R(RBX), Imm64((u64)Memory::base));
// if ((u64)GetCodePointers() > 0x80000000ULL) {
// PanicAlert("Code Pointers are above the limit! %p",
// GetCodePointers());
//}
MOV(64, R(R15), Imm64((u64)GetCodePointers())); //It's below 2GB so 32 bits are good enough
const u8 *outerLoop = GetCodePtr();
@ -224,7 +218,7 @@ void Generate()
ADD(32, M(&PowerPC::ppcState.DebugCount), Imm8(1));
}
//grab from list and jump to it
JMPptr(MComplex(R15,RAX,8,0));
JMPptr(MComplex(R15, RAX, 8, 0));
SetJumpTarget(notfound);
//Ok, no block, let's jit

View File

@ -37,8 +37,9 @@ namespace Jit64
u32 originalAddress;
u32 originalFirstOpcode; //to be able to restore
u32 codeSize;
u32 codeSize;
u32 originalSize;
int runCount; // for profiling.
const u8 *checkedEntry;
bool invalid;
};

View File

@ -90,8 +90,8 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size)
int numInternalBranches = 0;
while (true)
{
func.size++;
if (func.size > 1024*16) //weird
func.size += 4;
if (func.size > 1024*16*4) //weird
return false;
UGeckoInstruction instr = (UGeckoInstruction)Memory::ReadUnchecked_U32(addr);
@ -118,7 +118,6 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size)
//a final blr!
//We're done! Looks like we have a neat valid function. Perfect.
//Let's calc the checksum and get outta here
func.size *= 4; // into bytes
func.address = startAddr;
func.analyzed = 1;
func.hash = SignatureDB::ComputeCodeChecksum(startAddr, addr);

View File

@ -238,7 +238,7 @@ GekkoOPTemplate table4_2[] =
{23, Interpreter::ps_sel, Jit64::ps_sel, {"ps_sel", OPTYPE_PS, 0}},
{24, Interpreter::ps_res, Jit64::Default, {"ps_res", OPTYPE_PS, 0}},
{25, Interpreter::ps_mul, Jit64::ps_arith, {"ps_mul", OPTYPE_PS, 0}},
{26, Interpreter::ps_rsqrte, Jit64::ps_rsqrte, {"ps_rsqrte", OPTYPE_PS, 0}},
{26, Interpreter::ps_rsqrte, Jit64::ps_rsqrte, {"ps_rsqrte", OPTYPE_PS, 0, 1}},
{28, Interpreter::ps_msub, Jit64::ps_maddXX, {"ps_msub", OPTYPE_PS, 0}},
{29, Interpreter::ps_madd, Jit64::ps_maddXX, {"ps_madd", OPTYPE_PS, 0}},
{30, Interpreter::ps_nmsub, Jit64::ps_maddXX, {"ps_nmsub", OPTYPE_PS, 0}},

View File

@ -41,12 +41,10 @@ namespace PowerPC
static CoreMode mode;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("PPC ");
f.Do(ppcState);
f.Do(state);
f.Ascend();
p.Do(ppcState);
p.Do(state);
}
void ResetRegisters()

View File

@ -28,7 +28,7 @@
#include "Common.h"
#include "Gekko.h"
class ChunkFile;
class PointerWrap;
namespace PowerPC
{
@ -80,7 +80,7 @@ namespace PowerPC
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void SetMode(CoreMode _coreType);

View File

@ -0,0 +1,75 @@
// Copyright (C) 2003-2008 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/
#include "Jit64/Jit.h"
#include <vector>
#include <algorithm>
#include "SymbolDB.h"
namespace Profiler
{
bool g_ProfileBlocks;
bool g_ProfileInstructions;
struct BlockStat
{
BlockStat(int bn, int c) : blockNum(bn), cost(c) {}
int blockNum;
int cost;
bool operator <(const BlockStat &other) const {
return cost > other.cost;
}
};
void WriteProfileResults(const char *filename) {
std::vector<BlockStat> stats;
stats.reserve(Jit64::GetNumBlocks());
u64 cost_sum = 0;
for (int i = 0; i < Jit64::GetNumBlocks(); i++)
{
const Jit64::JitBlock *block = Jit64::GetBlock(i);
int cost = (block->originalSize / 4) * block->runCount; // rough heuristic. mem instructions should cost more.
if (block->runCount >= 1) { // Todo: tweak.
stats.push_back(BlockStat(i, cost));
}
cost_sum += cost;
}
sort(stats.begin(), stats.end());
FILE *f = fopen(filename, "w");
if (!f) {
PanicAlert("failed to open %s", filename);
return;
}
fprintf(f, "Profile\n");
for (int i = 0; i < stats.size(); i++)
{
const Jit64::JitBlock *block = Jit64::GetBlock(stats[i].blockNum);
if (block) {
std::string name = g_symbolDB.GetDescription(block->originalAddress);
double percent = 100 * (double)stats[i].cost / (double)cost_sum;
fprintf(f, "%08x - %s - %i (%f%%)\n", block->originalAddress, name.c_str(), stats[i].cost, percent);
}
}
fclose(f);
}
}

View File

@ -0,0 +1,30 @@
// Copyright (C) 2003-2008 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/
#ifndef _PROFILER_H
#define _PROFILER_H
namespace Profiler
{
extern bool g_ProfileBlocks;
extern bool g_ProfileInstructions;
void WriteProfileResults(const char *filename);
}
#endif // _PROFILER_H

View File

@ -57,6 +57,7 @@ files = ["Console.cpp",
"PowerPC/PowerPC.cpp",
"PowerPC/PPCAnalyst.cpp",
"PowerPC/PPCTables.cpp",
"PowerPC/Profiler.cpp",
"PowerPC/SignatureDB.cpp",
"PowerPC/SymbolDB.cpp",
"PowerPC/Interpreter/Interpreter.cpp",

View File

@ -4,35 +4,53 @@
#include "CoreTiming.h"
#include "HW/HW.h"
#include "PowerPC/PowerPC.h"
#include "Plugins/Plugin_Video.h"
#include <string>
#include "Plugins/Plugin_Video.h"
#include <string>
static int ev_Save;
static int ev_Load;
static std::string cur_filename;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("DOLP");
PowerPC::DoState(f);
HW::DoState(f);
PluginVideo::Video_DoState(f);
f.Ascend();
PowerPC::DoState(p);
HW::DoState(p);
PluginVideo::Video_DoState(p.GetPPtr(), p.GetMode());
}
void SaveStateCallback(u64 userdata, int cyclesLate)
{
ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_WRITE);
DoState(f);
u8 *ptr = 0;
PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
DoState(p);
int sz = (int)(u64)ptr;
u8 *buffer = new u8[sz];
ptr = buffer;
p.SetMode(PointerWrap::MODE_WRITE);
DoState(p);
FILE *f = fopen(cur_filename.c_str(), "wb");
fwrite(buffer, sz, 1, f);
fclose(f);
delete [] buffer;
}
void LoadStateCallback(u64 userdata, int cyclesLate)
{
ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_READ);
DoState(f);
// ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_READ);
FILE *f = fopen(cur_filename.c_str(), "r");
fseek(f, 0, SEEK_END);
int sz = ftell(f);
fseek(f, 0, SEEK_SET);
u8 *buffer = new u8[sz];
fread(buffer, sz, 1, f);
fclose(f);
u8 *ptr;
PointerWrap p(&ptr, PointerWrap::MODE_READ);
DoState(p);
}
void State_Init()
@ -56,4 +74,4 @@ void State_Load(const char *filename)
{
cur_filename = filename;
CoreTiming::ScheduleEvent_Threadsafe(0, ev_Load);
}
}