2012-12-19 09:30:18 +00:00
|
|
|
/****************************************************************************
|
|
|
|
* *
|
|
|
|
* Project 64 - A Nintendo 64 emulator. *
|
|
|
|
* http://www.pj64-emu.com/ *
|
|
|
|
* Copyright (C) 2012 Project64. All rights reserved. *
|
|
|
|
* *
|
|
|
|
* License: *
|
|
|
|
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
|
|
|
* *
|
|
|
|
****************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
class CCodeSection;
|
2010-05-25 09:15:19 +00:00
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
class CRecompilerOps :
|
2013-03-22 05:47:20 +00:00
|
|
|
protected CDebugSettings,
|
2010-06-04 06:25:07 +00:00
|
|
|
protected CX86Ops,
|
2010-07-23 10:45:35 +00:00
|
|
|
protected CSystemRegisters,
|
2010-10-29 03:20:25 +00:00
|
|
|
protected CN64SystemSettings,
|
2012-11-29 11:23:35 +00:00
|
|
|
protected CRecompilerSettings
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
protected:
|
|
|
|
enum BRANCH_TYPE
|
|
|
|
{
|
|
|
|
BranchTypeCop1, BranchTypeRs, BranchTypeRsRt
|
|
|
|
};
|
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
typedef void ( * BranchFunction )();
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** Branch functions ************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void Compile_Branch ( BranchFunction CompareFunc, BRANCH_TYPE BranchType, BOOL Link);
|
|
|
|
static void Compile_BranchLikely ( BranchFunction CompareFunc, BOOL Link);
|
|
|
|
static void BNE_Compare ( void );
|
|
|
|
static void BEQ_Compare ( void );
|
|
|
|
static void BGTZ_Compare ( void );
|
|
|
|
static void BLEZ_Compare ( void );
|
|
|
|
static void BLTZ_Compare ( void );
|
|
|
|
static void BGEZ_Compare ( void );
|
|
|
|
static void COP1_BCF_Compare ( void );
|
|
|
|
static void COP1_BCT_Compare ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************* OpCode functions *************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void J ( void );
|
|
|
|
static void JAL ( void );
|
|
|
|
static void ADDI ( void );
|
|
|
|
static void ADDIU ( void );
|
|
|
|
static void SLTI ( void );
|
|
|
|
static void SLTIU ( void );
|
|
|
|
static void ANDI ( void );
|
|
|
|
static void ORI ( void );
|
|
|
|
static void XORI ( void );
|
|
|
|
static void LUI ( void );
|
|
|
|
static void DADDIU ( void );
|
2010-05-31 00:21:08 +00:00
|
|
|
// static void LDL ( void );
|
|
|
|
// static void LDR ( void );
|
|
|
|
// static void LB ( void );
|
|
|
|
// static void LH ( void );
|
|
|
|
// static void LWL ( void );
|
|
|
|
// static void LW ( void );
|
|
|
|
// static void LBU ( void );
|
|
|
|
// static void LHU ( void );
|
|
|
|
// static void LWR ( void );
|
|
|
|
// static void LWU ( void ); //added by Witten
|
|
|
|
// static void SB ( void );
|
|
|
|
// static void SH ( void );
|
|
|
|
// static void SWL ( void );
|
|
|
|
// static void SW ( void );
|
|
|
|
// static void SWR ( void );
|
|
|
|
// static void SDL ( void );
|
|
|
|
// static void SDR ( void );
|
2010-05-30 01:54:42 +00:00
|
|
|
static void CACHE ( void );
|
2013-02-19 18:31:10 +00:00
|
|
|
// static void LL ( void );
|
2010-05-31 00:21:08 +00:00
|
|
|
// static void LWC1 ( void );
|
|
|
|
// static void LDC1 ( void );
|
|
|
|
// static void LD ( void );
|
2013-02-19 18:31:10 +00:00
|
|
|
// static void SC ( void );
|
2010-05-31 00:21:08 +00:00
|
|
|
// static void SWC1 ( void );
|
|
|
|
// static void SDC1 ( void );
|
|
|
|
// static void SD ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/********************** R4300i OpCodes: Special **********************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void SPECIAL_SLL ( void );
|
|
|
|
static void SPECIAL_SRL ( void );
|
|
|
|
static void SPECIAL_SRA ( void );
|
|
|
|
static void SPECIAL_SLLV ( void );
|
|
|
|
static void SPECIAL_SRLV ( void );
|
|
|
|
static void SPECIAL_SRAV ( void );
|
|
|
|
static void SPECIAL_JR ( void );
|
|
|
|
static void SPECIAL_JALR ( void );
|
|
|
|
static void SPECIAL_SYSCALL( void );
|
|
|
|
static void SPECIAL_MFLO ( void );
|
|
|
|
static void SPECIAL_MTLO ( void );
|
|
|
|
static void SPECIAL_MFHI ( void );
|
|
|
|
static void SPECIAL_MTHI ( void );
|
|
|
|
static void SPECIAL_DSLLV ( void );
|
|
|
|
static void SPECIAL_DSRLV ( void );
|
|
|
|
static void SPECIAL_DSRAV ( void );
|
|
|
|
static void SPECIAL_MULT ( void );
|
|
|
|
static void SPECIAL_MULTU ( void );
|
|
|
|
static void SPECIAL_DIV ( void );
|
|
|
|
static void SPECIAL_DIVU ( void );
|
|
|
|
static void SPECIAL_DMULT ( void );
|
|
|
|
static void SPECIAL_DMULTU ( void );
|
|
|
|
static void SPECIAL_DDIV ( void );
|
|
|
|
static void SPECIAL_DDIVU ( void );
|
|
|
|
static void SPECIAL_ADD ( void );
|
|
|
|
static void SPECIAL_ADDU ( void );
|
|
|
|
static void SPECIAL_SUB ( void );
|
|
|
|
static void SPECIAL_SUBU ( void );
|
|
|
|
static void SPECIAL_AND ( void );
|
|
|
|
static void SPECIAL_OR ( void );
|
|
|
|
static void SPECIAL_XOR ( void );
|
|
|
|
static void SPECIAL_NOR ( void );
|
|
|
|
static void SPECIAL_SLT ( void );
|
|
|
|
static void SPECIAL_SLTU ( void );
|
|
|
|
static void SPECIAL_DADD ( void );
|
|
|
|
static void SPECIAL_DADDU ( void );
|
|
|
|
static void SPECIAL_DSUB ( void );
|
|
|
|
static void SPECIAL_DSUBU ( void );
|
|
|
|
static void SPECIAL_DSLL ( void );
|
|
|
|
static void SPECIAL_DSRL ( void );
|
|
|
|
static void SPECIAL_DSRA ( void );
|
|
|
|
static void SPECIAL_DSLL32 ( void );
|
|
|
|
static void SPECIAL_DSRL32 ( void );
|
|
|
|
static void SPECIAL_DSRA32 ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** COP0 functions **************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void COP0_MF ( void );
|
|
|
|
static void COP0_MT ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** COP0 CO functions ***********************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void COP0_CO_TLBR ( void );
|
|
|
|
static void COP0_CO_TLBWI ( void );
|
|
|
|
static void COP0_CO_TLBWR ( void );
|
|
|
|
static void COP0_CO_TLBP ( void );
|
|
|
|
static void COP0_CO_ERET ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** COP1 functions **************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void COP1_MF ( void );
|
|
|
|
static void COP1_DMF ( void );
|
|
|
|
static void COP1_CF ( void );
|
|
|
|
static void COP1_MT ( void );
|
|
|
|
static void COP1_DMT ( void );
|
|
|
|
static void COP1_CT ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** COP1: S functions ************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void COP1_S_ADD ( void );
|
|
|
|
static void COP1_S_SUB ( void );
|
|
|
|
static void COP1_S_MUL ( void );
|
|
|
|
static void COP1_S_DIV ( void );
|
|
|
|
static void COP1_S_ABS ( void );
|
|
|
|
static void COP1_S_NEG ( void );
|
|
|
|
static void COP1_S_SQRT ( void );
|
|
|
|
static void COP1_S_MOV ( void );
|
|
|
|
static void COP1_S_TRUNC_L ( void );
|
|
|
|
static void COP1_S_CEIL_L ( void ); //added by Witten
|
|
|
|
static void COP1_S_FLOOR_L ( void ); //added by Witten
|
|
|
|
static void COP1_S_ROUND_W ( void );
|
|
|
|
static void COP1_S_TRUNC_W ( void );
|
|
|
|
static void COP1_S_CEIL_W ( void ); //added by Witten
|
|
|
|
static void COP1_S_FLOOR_W ( void );
|
|
|
|
static void COP1_S_CVT_D ( void );
|
|
|
|
static void COP1_S_CVT_W ( void );
|
|
|
|
static void COP1_S_CVT_L ( void );
|
|
|
|
static void COP1_S_CMP ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** COP1: D functions ************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void COP1_D_ADD ( void );
|
|
|
|
static void COP1_D_SUB ( void );
|
|
|
|
static void COP1_D_MUL ( void );
|
|
|
|
static void COP1_D_DIV ( void );
|
|
|
|
static void COP1_D_ABS ( void );
|
|
|
|
static void COP1_D_NEG ( void );
|
|
|
|
static void COP1_D_SQRT ( void );
|
|
|
|
static void COP1_D_MOV ( void );
|
|
|
|
static void COP1_D_TRUNC_L ( void ); //added by Witten
|
|
|
|
static void COP1_D_CEIL_L ( void ); //added by Witten
|
|
|
|
static void COP1_D_FLOOR_L ( void ); //added by Witten
|
|
|
|
static void COP1_D_ROUND_W ( void );
|
|
|
|
static void COP1_D_TRUNC_W ( void );
|
|
|
|
static void COP1_D_CEIL_W ( void ); //added by Witten
|
|
|
|
static void COP1_D_FLOOR_W ( void ); //added by Witten
|
|
|
|
static void COP1_D_CVT_S ( void );
|
|
|
|
static void COP1_D_CVT_W ( void );
|
|
|
|
static void COP1_D_CVT_L ( void );
|
|
|
|
static void COP1_D_CMP ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** COP1: W functions ************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void COP1_W_CVT_S ( void );
|
|
|
|
static void COP1_W_CVT_D ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** COP1: L functions ************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void COP1_L_CVT_S ( void );
|
|
|
|
static void COP1_L_CVT_D ( void );
|
2010-05-25 09:15:19 +00:00
|
|
|
|
|
|
|
/************************** Other functions **************************/
|
2010-05-30 01:54:42 +00:00
|
|
|
static void UnknownOpcode ( void );
|
|
|
|
|
2010-05-31 00:21:08 +00:00
|
|
|
|
2010-06-14 21:14:58 +00:00
|
|
|
static void BeforeCallDirect ( CRegInfo & RegSet );
|
|
|
|
static void AfterCallDirect ( CRegInfo & RegSet );
|
2010-06-07 02:23:58 +00:00
|
|
|
static void EnterCodeBlock ( void );
|
|
|
|
static void ExitCodeBlock ( void );
|
2012-10-25 08:38:58 +00:00
|
|
|
static void CompileReadTLBMiss (DWORD VirtualAddress, x86Reg LookUpReg );
|
2012-09-29 07:58:16 +00:00
|
|
|
static void CompileReadTLBMiss (x86Reg AddressReg, x86Reg LookUpReg );
|
2012-12-31 07:02:54 +00:00
|
|
|
static void CompileWriteTLBMiss (DWORD VirtualAddress, x86Reg LookUpReg );
|
2012-09-29 07:58:16 +00:00
|
|
|
static void CompileWriteTLBMiss (x86Reg AddressReg, x86Reg LookUpReg );
|
2012-09-25 05:58:06 +00:00
|
|
|
static void UpdateSyncCPU (CRegInfo & RegSet, DWORD Cycles);
|
2010-05-30 01:54:42 +00:00
|
|
|
static void UpdateCounters (CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false );
|
2012-10-14 01:05:52 +00:00
|
|
|
static void CompileSystemCheck ( DWORD TargetPC, const CRegInfo & RegSet );
|
2010-06-04 06:25:07 +00:00
|
|
|
static void ChangeDefaultRoundingModel ( void );
|
2012-09-26 00:38:29 +00:00
|
|
|
static void OverflowDelaySlot ( BOOL TestTimer );
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static STEP_TYPE m_NextInstruction;
|
|
|
|
static DWORD m_CompilePC;
|
|
|
|
static OPCODE m_Opcode;
|
|
|
|
static CRegInfo m_RegWorkingSet;
|
2010-06-04 06:25:07 +00:00
|
|
|
static DWORD m_BranchCompare;
|
2010-05-30 01:54:42 +00:00
|
|
|
static CCodeSection * m_Section;
|
|
|
|
|
|
|
|
/********* Helper Functions *********/
|
|
|
|
typedef CRegInfo::REG_STATE REG_STATE;
|
|
|
|
|
2012-11-06 08:19:22 +00:00
|
|
|
static inline REG_STATE GetMipsRegState ( int Reg ) { return m_RegWorkingSet.GetMipsRegState(Reg); }
|
|
|
|
static inline unsigned __int64 GetMipsReg ( int Reg ) { return m_RegWorkingSet.GetMipsReg(Reg); }
|
|
|
|
static inline __int64 GetMipsReg_S ( int Reg ) { return m_RegWorkingSet.GetMipsReg_S(Reg); }
|
2012-11-03 01:18:08 +00:00
|
|
|
static inline DWORD GetMipsRegLo ( int Reg ) { return m_RegWorkingSet.GetMipsRegLo(Reg); }
|
|
|
|
static inline long GetMipsRegLo_S ( int Reg ) { return m_RegWorkingSet.GetMipsRegLo_S(Reg); }
|
|
|
|
static inline DWORD GetMipsRegHi ( int Reg ) { return m_RegWorkingSet.GetMipsRegHi(Reg); }
|
|
|
|
static inline long GetMipsRegHi_S ( int Reg ) { return m_RegWorkingSet.GetMipsRegHi_S(Reg); }
|
|
|
|
static inline CX86Ops::x86Reg GetMipsRegMapLo ( int Reg ) { return m_RegWorkingSet.GetMipsRegMapLo(Reg); }
|
|
|
|
static inline CX86Ops::x86Reg GetMipsRegMapHi ( int Reg ) { return m_RegWorkingSet.GetMipsRegMapHi(Reg); }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
static inline bool IsKnown ( int Reg ) { return m_RegWorkingSet.IsKnown(Reg); }
|
|
|
|
static inline bool IsUnknown ( int Reg ) { return m_RegWorkingSet.IsUnknown(Reg); }
|
|
|
|
static inline bool IsMapped ( int Reg ) { return m_RegWorkingSet.IsMapped(Reg); }
|
|
|
|
static inline bool IsConst ( int Reg ) { return m_RegWorkingSet.IsConst(Reg); }
|
|
|
|
static inline bool IsSigned ( int Reg ) { return m_RegWorkingSet.IsSigned(Reg); }
|
|
|
|
static inline bool IsUnsigned ( int Reg ) { return m_RegWorkingSet.IsUnsigned(Reg); }
|
|
|
|
static inline bool Is32Bit ( int Reg ) { return m_RegWorkingSet.Is32Bit(Reg); }
|
|
|
|
static inline bool Is64Bit ( int Reg ) { return m_RegWorkingSet.Is64Bit(Reg); }
|
|
|
|
static inline bool Is32BitMapped ( int Reg ) { return m_RegWorkingSet.Is32BitMapped(Reg); }
|
|
|
|
static inline bool Is64BitMapped ( int Reg ) { return m_RegWorkingSet.Is64BitMapped(Reg); }
|
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
static inline void FixRoundModel ( CRegInfo::FPU_ROUND RoundMethod )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.FixRoundModel(RoundMethod);
|
|
|
|
}
|
|
|
|
static inline void ChangeFPURegFormat ( int Reg, CRegInfo::FPU_STATE OldFormat, CRegInfo::FPU_STATE NewFormat, CRegInfo::FPU_ROUND RoundingModel )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(Reg,OldFormat,NewFormat,RoundingModel);
|
|
|
|
}
|
|
|
|
static inline void Load_FPR_ToTop ( int Reg, int RegToLoad, CRegInfo::FPU_STATE Format)
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(Reg,RegToLoad,Format);
|
|
|
|
}
|
|
|
|
static inline BOOL RegInStack ( int Reg, CRegInfo::FPU_STATE Format )
|
|
|
|
{
|
|
|
|
return m_RegWorkingSet.RegInStack(Reg,Format);
|
|
|
|
}
|
|
|
|
static inline x86FpuValues StackPosition ( int Reg )
|
|
|
|
{
|
|
|
|
return m_RegWorkingSet.StackPosition(Reg);
|
|
|
|
}
|
|
|
|
static inline void UnMap_AllFPRs ( void )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.UnMap_AllFPRs();
|
|
|
|
}
|
|
|
|
static inline void UnMap_FPR ( DWORD Reg, bool WriteBackValue )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.UnMap_FPR(Reg,WriteBackValue);
|
|
|
|
}
|
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
static inline x86Reg FreeX86Reg ( void )
|
|
|
|
{
|
|
|
|
return m_RegWorkingSet.FreeX86Reg();
|
|
|
|
}
|
|
|
|
static inline x86Reg Free8BitX86Reg ( void )
|
|
|
|
{
|
|
|
|
return m_RegWorkingSet.Free8BitX86Reg();
|
|
|
|
}
|
2012-10-22 10:36:57 +00:00
|
|
|
static inline void Map_GPR_32bit ( int Reg, bool SignValue, int MipsRegToLoad )
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
|
|
|
m_RegWorkingSet.Map_GPR_32bit(Reg,SignValue,MipsRegToLoad);
|
|
|
|
}
|
|
|
|
static inline void Map_GPR_64bit ( int Reg, int MipsRegToLoad )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.Map_GPR_64bit(Reg,MipsRegToLoad);
|
|
|
|
}
|
2010-10-29 03:20:25 +00:00
|
|
|
static inline x86Reg Get_MemoryStack ( void )
|
2010-07-23 10:45:35 +00:00
|
|
|
{
|
2010-10-29 03:20:25 +00:00
|
|
|
return m_RegWorkingSet.Get_MemoryStack();
|
|
|
|
}
|
|
|
|
static inline x86Reg Map_MemoryStack ( x86Reg Reg, bool bMapRegister, bool LoadValue = true )
|
|
|
|
{
|
|
|
|
return m_RegWorkingSet.Map_MemoryStack(Reg,bMapRegister,LoadValue);
|
2010-07-23 10:45:35 +00:00
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
static inline x86Reg Map_TempReg ( x86Reg Reg, int MipsReg, BOOL LoadHiWord )
|
|
|
|
{
|
|
|
|
return m_RegWorkingSet.Map_TempReg(Reg,MipsReg,LoadHiWord);
|
|
|
|
}
|
|
|
|
static inline void ProtectGPR ( DWORD Reg )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.ProtectGPR(Reg);
|
|
|
|
}
|
2010-05-31 00:21:08 +00:00
|
|
|
static inline void UnProtectGPR ( DWORD Reg )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.UnProtectGPR(Reg);
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
static inline void ResetX86Protection ( void )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.ResetX86Protection();
|
|
|
|
}
|
|
|
|
static inline x86Reg UnMap_TempReg ( void )
|
|
|
|
{
|
|
|
|
return m_RegWorkingSet.UnMap_TempReg();
|
|
|
|
}
|
|
|
|
static inline void UnMap_GPR ( DWORD Reg, bool WriteBackValue )
|
|
|
|
{
|
|
|
|
m_RegWorkingSet.UnMap_GPR(Reg,WriteBackValue);
|
|
|
|
}
|
|
|
|
static inline bool UnMap_X86reg ( x86Reg Reg )
|
|
|
|
{
|
|
|
|
return m_RegWorkingSet.UnMap_X86reg(Reg);
|
|
|
|
}
|
2010-05-25 09:15:19 +00:00
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
public:
|
|
|
|
static DWORD CompilePC ( void ) { return m_CompilePC; }
|
2015-01-31 19:27:27 +00:00
|
|
|
};
|