mirror of
https://github.com/libretro/Play-.git
synced 2024-11-27 10:40:41 +00:00
209 lines
3.4 KiB
C++
209 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include "Types.h"
|
|
#include "MemoryMap.h"
|
|
#include "MipsExecutor.h"
|
|
#include "MIPSArchitecture.h"
|
|
#include "MIPSCoprocessor.h"
|
|
#include "MIPSAnalysis.h"
|
|
#include "MIPSTags.h"
|
|
#include "uint128.h"
|
|
#include <set>
|
|
|
|
struct REGISTER_PIPELINE
|
|
{
|
|
uint32 counter;
|
|
uint32 heldValue;
|
|
};
|
|
|
|
enum
|
|
{
|
|
//Must be a power of 2
|
|
FLAG_PIPELINE_SLOTS = 8,
|
|
};
|
|
|
|
//Invariants:
|
|
//- Pipe times are sorted when iterating from index to index + PIPELINE_SLOTS
|
|
//- The value at index - 1 is the latest value
|
|
struct FLAG_PIPELINE
|
|
{
|
|
uint32 index;
|
|
uint32 values[FLAG_PIPELINE_SLOTS];
|
|
uint32 pipeTimes[FLAG_PIPELINE_SLOTS];
|
|
};
|
|
|
|
enum
|
|
{
|
|
MIPS_EXCEPTION_NONE = 0,
|
|
MIPS_EXCEPTION_SYSCALL,
|
|
MIPS_EXCEPTION_CHECKPENDINGINT,
|
|
MIPS_EXCEPTION_IDLE,
|
|
MIPS_EXCEPTION_RETURNFROMEXCEPTION,
|
|
MIPS_EXCEPTION_CALLMS,
|
|
MIPS_EXCEPTION_BREAKPOINT,
|
|
};
|
|
|
|
#define MIPS_EXECUTION_STATUS_QUOTADONE 0x80
|
|
|
|
struct MIPSSTATE
|
|
{
|
|
uint32 nPC;
|
|
uint32 nDelayedJumpAddr;
|
|
uint32 nHasException;
|
|
int32 cycleQuota;
|
|
|
|
#ifdef _WIN32
|
|
__declspec(align(16))
|
|
#else
|
|
__attribute__((aligned(16)))
|
|
#endif
|
|
uint128 nGPR[32];
|
|
|
|
uint32 nHI[2];
|
|
uint32 nLO[2];
|
|
uint32 nHI1[2];
|
|
uint32 nLO1[2];
|
|
uint32 nSA;
|
|
|
|
//COP0
|
|
uint32 nCOP0[32];
|
|
|
|
uint32 cop0_pccr;
|
|
uint32 cop0_pcr[2];
|
|
|
|
//COP1
|
|
uint32 nCOP1[32];
|
|
uint32 nCOP1A;
|
|
uint32 nFCSR;
|
|
|
|
//COP2
|
|
#ifdef _WIN32
|
|
__declspec(align(16))
|
|
#else
|
|
__attribute__((aligned(16)))
|
|
#endif
|
|
uint128 nCOP2[33];
|
|
|
|
uint128 nCOP2A;
|
|
|
|
uint128 nCOP2VF_PreUp;
|
|
uint128 nCOP2VF_UpRes;
|
|
|
|
uint32 nCOP2Q;
|
|
uint32 nCOP2I;
|
|
uint32 nCOP2P;
|
|
uint32 nCOP2R;
|
|
uint32 nCOP2CF; //Mirror of CLIP flag (computed with values from pipeClip)
|
|
uint32 nCOP2MF; //Mirror of MACflag (computed with values from pipeMac)
|
|
uint32 nCOP2SF; //Sticky values of sign and zero MACflag (ie.: SxSySzSw ZxZyZzZw)
|
|
uint32 nCOP2DF; //Division by 0 flag from DIV operations
|
|
uint32 nCOP2T;
|
|
|
|
uint32 nCOP2VI[16];
|
|
|
|
REGISTER_PIPELINE pipeQ;
|
|
REGISTER_PIPELINE pipeP;
|
|
FLAG_PIPELINE pipeMac;
|
|
FLAG_PIPELINE pipeClip;
|
|
|
|
uint32 pipeTime;
|
|
|
|
uint32 cmsar0;
|
|
uint32 callMsEnabled;
|
|
uint32 callMsAddr;
|
|
|
|
uint32 savedIntReg;
|
|
uint32 savedIntRegTemp;
|
|
uint32 xgkickAddress;
|
|
};
|
|
|
|
#define MIPS_INVALID_PC (0x00000001)
|
|
#define MIPS_PAGE_SIZE (0x1000)
|
|
|
|
class CMIPS
|
|
{
|
|
public:
|
|
typedef uint32 (*AddressTranslator)(CMIPS*, uint32);
|
|
typedef std::set<uint32> BreakpointSet;
|
|
|
|
CMIPS(MEMORYMAP_ENDIANESS, bool usePageTable = false);
|
|
~CMIPS();
|
|
void ToggleBreakpoint(uint32);
|
|
bool IsBranch(uint32);
|
|
static int32 GetBranch(uint16);
|
|
static uint32 TranslateAddress64(CMIPS*, uint32);
|
|
|
|
void Reset();
|
|
|
|
bool CanGenerateInterrupt() const;
|
|
bool GenerateInterrupt(uint32);
|
|
bool GenerateException(uint32);
|
|
|
|
void MapPages(uint32, uint32, uint8*);
|
|
|
|
MIPSSTATE m_State;
|
|
|
|
void* m_vuMem = nullptr;
|
|
void** m_pageLookup = nullptr;
|
|
|
|
std::function<void(CMIPS*)> m_emptyBlockHandler;
|
|
|
|
CMIPSArchitecture* m_pArch = nullptr;
|
|
CMIPSCoprocessor* m_pCOP[4];
|
|
CMemoryMap* m_pMemoryMap = nullptr;
|
|
std::unique_ptr<CMipsExecutor> m_executor;
|
|
BreakpointSet m_breakpoints;
|
|
|
|
CMIPSAnalysis* m_analysis = nullptr;
|
|
CMIPSTags m_Comments;
|
|
CMIPSTags m_Functions;
|
|
|
|
AddressTranslator m_pAddrTranslator = nullptr;
|
|
|
|
enum REGISTER
|
|
{
|
|
R0 = 0,
|
|
AT,
|
|
V0,
|
|
V1,
|
|
A0,
|
|
A1,
|
|
A2,
|
|
A3,
|
|
T0,
|
|
T1,
|
|
T2,
|
|
T3,
|
|
T4,
|
|
T5,
|
|
T6,
|
|
T7,
|
|
S0,
|
|
S1,
|
|
S2,
|
|
S3,
|
|
S4,
|
|
S5,
|
|
S6,
|
|
S7,
|
|
T8,
|
|
T9,
|
|
K0,
|
|
K1,
|
|
GP,
|
|
SP,
|
|
FP,
|
|
RA
|
|
};
|
|
|
|
enum
|
|
{
|
|
STATUS_IE = (1 << 0),
|
|
STATUS_EXL = (1 << 1),
|
|
STATUS_ERL = (1 << 2),
|
|
STATUS_EIE = (1 << 16), //PS2 EE specific
|
|
};
|
|
|
|
static const char* m_sGPRName[];
|
|
};
|