project64/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h

393 lines
14 KiB
C++

/****************************************************************************
* *
* Project64 - 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
#include <Project64-core/N64System/Mips/RegisterClass.h>
#include <Project64-core/N64System/Mips/OpCode.h>
#include <Project64-core/N64System/Recompiler/ExitInfo.h>
#include <Project64-core/N64System/Recompiler/RegInfo.h>
#include <Project64-core/N64System/Recompiler/x86/x86ops.h>
#include <Project64-core/N64System/Recompiler/JumpInfo.h>
#include <Project64-core/Settings/DebugSettings.h>
#include <Project64-core/Settings/N64SystemSettings.h>
#include <Project64-core/Settings/RecompilerSettings.h>
class CCodeBlock;
class CCodeSection;
class CRecompilerOps :
protected CDebugSettings,
protected CX86Ops,
protected CSystemRegisters,
protected CN64SystemSettings,
protected CRecompilerSettings
{
public:
enum BRANCH_TYPE
{
BranchTypeCop1,
BranchTypeRs,
BranchTypeRsRt
};
enum BRANCH_COMPARE
{
CompareTypeBEQ,
CompareTypeBNE,
CompareTypeBLTZ,
CompareTypeBLEZ,
CompareTypeBGTZ,
CompareTypeBGEZ,
CompareTypeCOP1BCF,
CompareTypeCOP1BCT,
};
/************************** Branch functions ************************/
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);
void Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link);
void BNE_Compare();
void BEQ_Compare();
void BGTZ_Compare();
void BLEZ_Compare();
void BLTZ_Compare();
void BGEZ_Compare();
void COP1_BCF_Compare();
void COP1_BCT_Compare();
/************************* OpCode functions *************************/
void J ();
void JAL ();
void ADDI ();
void ADDIU ();
void SLTI ();
void SLTIU ();
void ANDI ();
void ORI ();
void XORI ();
void LUI ();
void DADDIU ();
void LDL ();
void LDR ();
void LB ();
void LH ();
void LWL ();
void LW ();
void LBU ();
void LHU ();
void LWR ();
void LWU ();
void SB ();
void SH ();
void SWL ();
void SW ();
void SWR ();
void SDL ();
void SDR ();
void CACHE ();
void LL ();
void LWC1 ();
void LDC1 ();
void LD ();
void SC ();
void SWC1 ();
void SDC1 ();
void SD ();
/********************** R4300i OpCodes: Special **********************/
void SPECIAL_SLL ();
void SPECIAL_SRL ();
void SPECIAL_SRA ();
void SPECIAL_SLLV ();
void SPECIAL_SRLV ();
void SPECIAL_SRAV ();
void SPECIAL_JR ();
void SPECIAL_JALR ();
void SPECIAL_SYSCALL();
void SPECIAL_MFLO ();
void SPECIAL_MTLO ();
void SPECIAL_MFHI ();
void SPECIAL_MTHI ();
void SPECIAL_DSLLV ();
void SPECIAL_DSRLV ();
void SPECIAL_DSRAV ();
void SPECIAL_MULT ();
void SPECIAL_MULTU ();
void SPECIAL_DIV ();
void SPECIAL_DIVU ();
void SPECIAL_DMULT ();
void SPECIAL_DMULTU ();
void SPECIAL_DDIV ();
void SPECIAL_DDIVU ();
void SPECIAL_ADD ();
void SPECIAL_ADDU ();
void SPECIAL_SUB ();
void SPECIAL_SUBU ();
void SPECIAL_AND ();
void SPECIAL_OR ();
void SPECIAL_XOR ();
void SPECIAL_NOR ();
void SPECIAL_SLT ();
void SPECIAL_SLTU ();
void SPECIAL_DADD ();
void SPECIAL_DADDU ();
void SPECIAL_DSUB ();
void SPECIAL_DSUBU ();
void SPECIAL_DSLL ();
void SPECIAL_DSRL ();
void SPECIAL_DSRA ();
void SPECIAL_DSLL32 ();
void SPECIAL_DSRL32 ();
void SPECIAL_DSRA32 ();
/************************** COP0 functions **************************/
void COP0_MF ();
void COP0_MT ();
/************************** COP0 CO functions ***********************/
void COP0_CO_TLBR ();
void COP0_CO_TLBWI ();
void COP0_CO_TLBWR ();
void COP0_CO_TLBP ();
void COP0_CO_ERET ();
/************************** COP1 functions **************************/
void COP1_MF ();
void COP1_DMF ();
void COP1_CF ();
void COP1_MT ();
void COP1_DMT ();
void COP1_CT ();
/************************** COP1: S functions ************************/
void COP1_S_ADD ();
void COP1_S_SUB ();
void COP1_S_MUL ();
void COP1_S_DIV ();
void COP1_S_ABS ();
void COP1_S_NEG ();
void COP1_S_SQRT ();
void COP1_S_MOV ();
void COP1_S_ROUND_L ();
void COP1_S_TRUNC_L ();
void COP1_S_CEIL_L ();
void COP1_S_FLOOR_L ();
void COP1_S_ROUND_W ();
void COP1_S_TRUNC_W ();
void COP1_S_CEIL_W ();
void COP1_S_FLOOR_W ();
void COP1_S_CVT_D ();
void COP1_S_CVT_W ();
void COP1_S_CVT_L ();
void COP1_S_CMP ();
/************************** COP1: D functions ************************/
void COP1_D_ADD ();
void COP1_D_SUB ();
void COP1_D_MUL ();
void COP1_D_DIV ();
void COP1_D_ABS ();
void COP1_D_NEG ();
void COP1_D_SQRT ();
void COP1_D_MOV ();
void COP1_D_ROUND_L ();
void COP1_D_TRUNC_L ();
void COP1_D_CEIL_L ();
void COP1_D_FLOOR_L ();
void COP1_D_ROUND_W ();
void COP1_D_TRUNC_W ();
void COP1_D_CEIL_W ();
void COP1_D_FLOOR_W ();
void COP1_D_CVT_S ();
void COP1_D_CVT_W ();
void COP1_D_CVT_L ();
void COP1_D_CMP ();
/************************** COP1: W functions ************************/
void COP1_W_CVT_S ();
void COP1_W_CVT_D ();
/************************** COP1: L functions ************************/
void COP1_L_CVT_S ();
void COP1_L_CVT_D ();
/************************** Other functions **************************/
void UnknownOpcode ();
static void EnterCodeBlock();
static void ExitCodeBlock();
void CompileExitCode();
void CompileCop1Test();
void CompileInPermLoop(CRegInfo & RegSet, uint32_t ProgramCounter);
void SyncRegState(const CRegInfo & SyncTo);
bool SetupRegisterForLoop(CCodeBlock * BlockInfo, const CRegInfo & RegSet);
CRegInfo & GetRegWorkingSet(void);
static void BeforeCallDirect(CRegInfo & RegSet);
static void AfterCallDirect(CRegInfo & RegSet);
void SetRegWorkingSet(const CRegInfo & RegInfo);
bool InheritParentInfo();
void LinkJump(CJumpInfo & JumpInfo, uint32_t SectionID = -1, uint32_t FromSectionID = -1);
void JumpToSection(CCodeSection * Section);
void JumpToUnknown(CJumpInfo * JumpInfo);
void SetCurrentPC(uint32_t ProgramCounter);
uint32_t GetCurrentPC(void);
void SetCurrentSection(CCodeSection * section);
void SetNextStepType(STEP_TYPE StepType);
STEP_TYPE GetNextStepType( void );
const OPCODE & GetOpcode ( void ) const;
void PreCompileOpcode(void);
void PostCompileOpcode ( void );
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason, bool CompileNow);
void CompileReadTLBMiss(uint32_t VirtualAddress, x86Reg LookUpReg);
void CompileReadTLBMiss(x86Reg AddressReg, x86Reg LookUpReg);
void CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg);
static void UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles);
static void UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false);
static void CompileSystemCheck(uint32_t TargetPC, const CRegInfo & RegSet);
static void ChangeDefaultRoundingModel();
static void OverflowDelaySlot(bool TestTimer);
/********* Helper Functions *********/
typedef CRegInfo::REG_STATE REG_STATE;
static REG_STATE GetMipsRegState ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegState(Reg); }
static uint64_t GetMipsReg ( int32_t Reg ) { return m_RegWorkingSet.GetMipsReg(Reg); }
static int64_t GetMipsReg_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsReg_S(Reg); }
static uint32_t GetMipsRegLo ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegLo(Reg); }
static int32_t GetMipsRegLo_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegLo_S(Reg); }
static uint32_t GetMipsRegHi ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegHi(Reg); }
static int32_t GetMipsRegHi_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegHi_S(Reg); }
static CX86Ops::x86Reg GetMipsRegMapLo ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegMapLo(Reg); }
static CX86Ops::x86Reg GetMipsRegMapHi ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegMapHi(Reg); }
static bool IsKnown ( int32_t Reg ) { return m_RegWorkingSet.IsKnown(Reg); }
static bool IsUnknown ( int32_t Reg ) { return m_RegWorkingSet.IsUnknown(Reg); }
static bool IsMapped ( int32_t Reg ) { return m_RegWorkingSet.IsMapped(Reg); }
static bool IsConst ( int32_t Reg ) { return m_RegWorkingSet.IsConst(Reg); }
static bool IsSigned ( int32_t Reg ) { return m_RegWorkingSet.IsSigned(Reg); }
static bool IsUnsigned ( int32_t Reg ) { return m_RegWorkingSet.IsUnsigned(Reg); }
static bool Is32Bit ( int32_t Reg ) { return m_RegWorkingSet.Is32Bit(Reg); }
static bool Is64Bit ( int32_t Reg ) { return m_RegWorkingSet.Is64Bit(Reg); }
static bool Is32BitMapped ( int32_t Reg ) { return m_RegWorkingSet.Is32BitMapped(Reg); }
static bool Is64BitMapped ( int32_t Reg ) { return m_RegWorkingSet.Is64BitMapped(Reg); }
static void FixRoundModel ( CRegInfo::FPU_ROUND RoundMethod )
{
m_RegWorkingSet.FixRoundModel(RoundMethod);
}
static void ChangeFPURegFormat ( int32_t Reg, CRegInfo::FPU_STATE OldFormat, CRegInfo::FPU_STATE NewFormat, CRegInfo::FPU_ROUND RoundingModel )
{
m_RegWorkingSet.ChangeFPURegFormat(Reg,OldFormat,NewFormat,RoundingModel);
}
static void Load_FPR_ToTop ( int32_t Reg, int32_t RegToLoad, CRegInfo::FPU_STATE Format)
{
m_RegWorkingSet.Load_FPR_ToTop(Reg,RegToLoad,Format);
}
static bool RegInStack ( int32_t Reg, CRegInfo::FPU_STATE Format )
{
return m_RegWorkingSet.RegInStack(Reg,Format);
}
static x86FpuValues StackPosition ( int32_t Reg )
{
return m_RegWorkingSet.StackPosition(Reg);
}
static void UnMap_AllFPRs()
{
m_RegWorkingSet.UnMap_AllFPRs();
}
static void UnMap_FPR ( uint32_t Reg, bool WriteBackValue )
{
m_RegWorkingSet.UnMap_FPR(Reg,WriteBackValue);
}
static x86Reg FreeX86Reg()
{
return m_RegWorkingSet.FreeX86Reg();
}
static x86Reg Free8BitX86Reg()
{
return m_RegWorkingSet.Free8BitX86Reg();
}
static void Map_GPR_32bit ( int32_t Reg, bool SignValue, int32_t MipsRegToLoad )
{
m_RegWorkingSet.Map_GPR_32bit(Reg,SignValue,MipsRegToLoad);
}
static void Map_GPR_64bit ( int32_t Reg, int32_t MipsRegToLoad )
{
m_RegWorkingSet.Map_GPR_64bit(Reg,MipsRegToLoad);
}
static x86Reg Get_MemoryStack()
{
return m_RegWorkingSet.Get_MemoryStack();
}
static x86Reg Map_MemoryStack ( x86Reg Reg, bool bMapRegister, bool LoadValue = true )
{
return m_RegWorkingSet.Map_MemoryStack(Reg,bMapRegister,LoadValue);
}
static x86Reg Map_TempReg ( x86Reg Reg, int32_t MipsReg, bool LoadHiWord )
{
return m_RegWorkingSet.Map_TempReg(Reg,MipsReg,LoadHiWord);
}
static void ProtectGPR ( uint32_t Reg )
{
m_RegWorkingSet.ProtectGPR(Reg);
}
static void UnProtectGPR ( uint32_t Reg )
{
m_RegWorkingSet.UnProtectGPR(Reg);
}
static void ResetX86Protection()
{
m_RegWorkingSet.ResetX86Protection();
}
static x86Reg UnMap_TempReg()
{
return m_RegWorkingSet.UnMap_TempReg();
}
static void UnMap_GPR ( uint32_t Reg, bool WriteBackValue )
{
m_RegWorkingSet.UnMap_GPR(Reg,WriteBackValue);
}
static bool UnMap_X86reg ( x86Reg Reg )
{
return m_RegWorkingSet.UnMap_X86reg(Reg);
}
public:
static uint32_t CompilePC() { return m_CompilePC; }
private:
void SB_Const(uint8_t Value, uint32_t Addr);
void SB_Register(CX86Ops::x86Reg Reg, uint32_t Addr);
void SH_Const(uint16_t Value, uint32_t Addr);
void SH_Register(CX86Ops::x86Reg Reg, uint32_t Addr);
void SW_Const(uint32_t Value, uint32_t Addr);
void SW_Register(CX86Ops::x86Reg Reg, uint32_t Addr);
void LB_KnownAddress(x86Reg Reg, uint32_t VAddr, bool SignExtend);
void LH_KnownAddress(x86Reg Reg, uint32_t VAddr, bool SignExtend);
void LW_KnownAddress(x86Reg Reg, uint32_t VAddr);
void LW(bool ResultSigned, bool bRecordLLBit);
void SW(bool bCheckLLbit);
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason, bool CompileNow, void(*x86Jmp)(const char * Label, uint32_t Value));
void Compile_StoreInstructClean(x86Reg AddressReg, int32_t Length);
void ResetMemoryStack();
EXIT_LIST m_ExitInfo;
static STEP_TYPE m_NextInstruction;
static uint32_t m_CompilePC;
static OPCODE m_Opcode;
static CX86RegInfo m_RegWorkingSet;
static uint32_t m_BranchCompare;
static CCodeSection * m_Section;
static uint32_t m_TempValue;
};