mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-30 01:29:42 -06:00
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:
@ -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"
|
||||
>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace HW
|
||||
{
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void DoState(ChunkFile &f);
|
||||
void DoState(PointerWrap &p);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define _SERIALINTERFACE_DEVICES_H
|
||||
|
||||
#include "Common.h"
|
||||
class ChunkFile;
|
||||
class PointerWrap;
|
||||
|
||||
class ISIDevice
|
||||
{
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define _STREAMADPCM_H
|
||||
|
||||
#include "Common.h"
|
||||
class ChunkFile;
|
||||
class PointerWrap;
|
||||
|
||||
#define ONE_BLOCK_SIZE 32
|
||||
#define SAMPLES_PER_BLOCK 28
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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}},
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
||||
|
75
Source/Core/Core/Src/PowerPC/Profiler.cpp
Normal file
75
Source/Core/Core/Src/PowerPC/Profiler.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
30
Source/Core/Core/Src/PowerPC/Profiler.h
Normal file
30
Source/Core/Core/Src/PowerPC/Profiler.h
Normal 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
|
@ -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",
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user