git-svn-id: https://localhost/svn/Project64/trunk@30 111125ac-702d-7242-af9c-5ba8ae61c1ef

This commit is contained in:
zilmar 2010-05-30 01:54:42 +00:00
parent 142187aafb
commit ce1ff4d421
53 changed files with 11202 additions and 5494 deletions

View File

@ -18,6 +18,8 @@ class CNotification;
#include "N64 System/Rom Information Class.h"
#include "N64 System/Speed Limitor Class.h"
#include "N64 System/Mips/OpCode.h"
#include "N64 System/Mips/OpCode Analysis Class.h"
#include "N64 System/Recompiler/X86ops.h"
#include "N64 System/Mips/Register Class.h"
#include "N64 System/Mips/TranslateVaddr.h"
#include "N64 System/Mips/TLB Class.h"
@ -38,7 +40,12 @@ class CNotification;
//Recompiler
#include "N64 System/Recompiler/Recompiler Memory.h"
#include "N64 System/Recompiler/Reg Info.h"
#include "N64 System/Recompiler/Recompiler Ops.h"
#include "N64 System/Recompiler/Exit Info.h"
#include "N64 System/Recompiler/Jump Info.h"
#include "N64 System/Recompiler/Code Section.h"
#include "N64 System/Recompiler/Code Block.h"
#include "N64 System/Recompiler/Section Info.h"
#include "N64 System/Recompiler/Function Info.h"
#include "N64 System/Recompiler/Function Map Class.h"

View File

@ -672,10 +672,13 @@ void SyncToPC (void) {
BOOL ClearRecompCodeProtectMem ( DWORD Address, int length )
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
if (_Recompiler)
{
return _Recompiler->ClearRecompCode_Phys(Address,length,CRecompiler::Remove_ProtectedMem);
}
#endif
return false;
}
@ -683,7 +686,10 @@ BOOL ClearRecompCodeInitialCode ( void )
{
if (_Recompiler)
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
return _Recompiler->ClearRecompCode_Virt(0x80000000,0x200,CRecompiler::Remove_InitialCode);
#endif
}
return false;
}

View File

@ -18,7 +18,7 @@ void InitializeCPUCore ( void );
//from exception.h
void _fastcall DoTLBMiss ( BOOL DelaySlot, DWORD BadVaddr );
extern enum STEP_TYPE NextInstruction;
//extern enum STEP_TYPE NextInstruction;
#ifdef __cplusplus
}

View File

@ -8,14 +8,14 @@
//DWORD MemoryStack;
DWORD JumpToLocation;
R4300iOp_FUNC * R4300i_Opcode;
//R4300iOp_FUNC * R4300i_Opcode;
void InitializeCPUCore ( void )
{
LARGE_INTEGER PerformanceFrequency;
//R4300i_Opcode = R4300iOp::BuildInterpreter();
R4300i_Opcode = R4300iOp32::BuildInterpreter();
//R4300i_Opcode = R4300iOp32::BuildInterpreter();
CurrentFrame = 0;
QueryPerformanceFrequency(&PerformanceFrequency);
@ -57,358 +57,6 @@ void InitializeCPUCore ( void )
}
int DelaySlotEffectsJump (DWORD JumpPC) {
OPCODE Command;
if (!_MMU->LW_VAddr(JumpPC, Command.Hex)) { return TRUE; }
switch (Command.op) {
case R4300i_SPECIAL:
switch (Command.funct) {
case R4300i_SPECIAL_JR: return DelaySlotEffectsCompare(JumpPC,Command.rs,0);
case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(JumpPC,Command.rs,31);
}
break;
case R4300i_REGIMM:
switch (Command.rt) {
case R4300i_REGIMM_BLTZ:
case R4300i_REGIMM_BGEZ:
case R4300i_REGIMM_BLTZL:
case R4300i_REGIMM_BGEZL:
case R4300i_REGIMM_BLTZAL:
case R4300i_REGIMM_BGEZAL:
return DelaySlotEffectsCompare(JumpPC,Command.rs,0);
}
break;
case R4300i_JAL:
case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(JumpPC,31,0); break;
case R4300i_J: return FALSE;
case R4300i_BEQ:
case R4300i_BNE:
case R4300i_BLEZ:
case R4300i_BGTZ:
return DelaySlotEffectsCompare(JumpPC,Command.rs,Command.rt);
case R4300i_CP1:
switch (Command.fmt) {
case R4300i_COP1_BC:
switch (Command.ft) {
case R4300i_COP1_BC_BCF:
case R4300i_COP1_BC_BCT:
case R4300i_COP1_BC_BCFL:
case R4300i_COP1_BC_BCTL:
{
int EffectDelaySlot;
OPCODE NewCommand;
if (!_MMU->LW_VAddr(JumpPC + 4, NewCommand.Hex)) { return TRUE; }
EffectDelaySlot = FALSE;
if (NewCommand.op == R4300i_CP1) {
if (NewCommand.fmt == R4300i_COP1_S && (NewCommand.funct & 0x30) == 0x30 ) {
EffectDelaySlot = TRUE;
}
if (NewCommand.fmt == R4300i_COP1_D && (NewCommand.funct & 0x30) == 0x30 ) {
EffectDelaySlot = TRUE;
}
}
return EffectDelaySlot;
}
break;
}
break;
}
break;
case R4300i_BEQL:
case R4300i_BNEL:
case R4300i_BLEZL:
case R4300i_BGTZL:
return DelaySlotEffectsCompare(JumpPC,Command.rs,Command.rt);
}
return TRUE;
}
void DoSomething ( void ) {
if (CPU_Action.CloseCPU) {
return;
}
if (CPU_Action.SoftReset)
{
CPU_Action.SoftReset = false;
_SystemTimer->SetTimer(CSystemTimer::SoftResetTimer,0x3000000,false);
ShowCFB();
_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP4;
CheckInterrupts();
_Plugins->Gfx()->SoftReset();
}
if (CPU_Action.GenerateInterrupt)
{
CPU_Action.GenerateInterrupt = FALSE;
_Reg->MI_INTR_REG |= CPU_Action.InterruptFlag;
CPU_Action.InterruptFlag = 0;
CheckInterrupts();
}
if (CPU_Action.CheckInterrupts) {
CPU_Action.CheckInterrupts = FALSE;
CheckInterrupts();
}
if (CPU_Action.ProfileStartStop) {
CPU_Action.ProfileStartStop = FALSE;
ResetTimer();
}
if (CPU_Action.ProfileResetStats) {
CPU_Action.ProfileResetStats = FALSE;
ResetTimer();
}
if (CPU_Action.ProfileGenerateLogs) {
CPU_Action.ProfileGenerateLogs = FALSE;
GenerateProfileLog();
}
if (CPU_Action.DoInterrupt) {
CPU_Action.DoInterrupt = FALSE;
if (DoIntrException(FALSE) && !CPU_Action.InterruptExecuted)
{
CPU_Action.InterruptExecuted = TRUE;
ClearRecompCodeInitialCode();
}
}
if (CPU_Action.ChangeWindow) {
CPU_Action.ChangeWindow = FALSE;
ChangeFullScreenFunc();
}
if (CPU_Action.Pause) {
PauseExecution();
CPU_Action.Pause = FALSE;
}
if (CPU_Action.ChangePlugin) {
ChangePluginFunc();
CPU_Action.ChangePlugin = FALSE;
}
if (CPU_Action.GSButton) {
ApplyGSButtonCheats();
CPU_Action.GSButton = FALSE;
}
CPU_Action.DoSomething = FALSE;
if (CPU_Action.SaveState) {
//test if allowed
CPU_Action.SaveState = FALSE;
if (!Machine_SaveState()) {
CPU_Action.SaveState = TRUE;
CPU_Action.DoSomething = TRUE;
}
}
if (CPU_Action.RestoreState) {
CPU_Action.RestoreState = FALSE;
Machine_LoadState();
}
if (CPU_Action.DoInterrupt == TRUE) { CPU_Action.DoSomething = TRUE; }
}
void InPermLoop (void) {
// *** Changed ***/
if (CPU_Action.DoInterrupt)
{
CPU_Action.DoSomething = TRUE;
return;
}
//if (CPU_Type == CPU_SyncCores) { SyncRegisters.CP0[9] +=5; }
/* Interrupts enabled */
if (( _Reg->STATUS_REGISTER & STATUS_IE ) == 0 ) { goto InterruptsDisabled; }
if (( _Reg->STATUS_REGISTER & STATUS_EXL ) != 0 ) { goto InterruptsDisabled; }
if (( _Reg->STATUS_REGISTER & STATUS_ERL ) != 0 ) { goto InterruptsDisabled; }
if (( _Reg->STATUS_REGISTER & 0xFF00) == 0) { goto InterruptsDisabled; }
/* check sound playing */
_N64System->SyncToAudio();
/* check RSP running */
/* check RDP running */
if (*_NextTimer > 0) {
//_Reg->COUNT_REGISTER += *_Timer + 1;
//if (CPU_Type == CPU_SyncCores) { SyncRegisters.CP0[9] += Timers.Timer + 1; }
*_NextTimer = -1;
}
return;
InterruptsDisabled:
if (UpdateScreen != NULL) { UpdateScreen(); }
//CurrentFrame = 0;
//CurrentPercent = 0;
//DisplayFPS();
DisplayError(GS(MSG_PERM_LOOP));
StopEmulation();
}
int DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
OPCODE Command;
if (!_MMU->LW_VAddr(PC + 4, Command.Hex)) {
//DisplayError("Failed to load word 2");
//ExitThread(0);
return TRUE;
}
switch (Command.op) {
case R4300i_SPECIAL:
switch (Command.funct) {
case R4300i_SPECIAL_SLL:
case R4300i_SPECIAL_SRL:
case R4300i_SPECIAL_SRA:
case R4300i_SPECIAL_SLLV:
case R4300i_SPECIAL_SRLV:
case R4300i_SPECIAL_SRAV:
case R4300i_SPECIAL_MFHI:
case R4300i_SPECIAL_MTHI:
case R4300i_SPECIAL_MFLO:
case R4300i_SPECIAL_MTLO:
case R4300i_SPECIAL_DSLLV:
case R4300i_SPECIAL_DSRLV:
case R4300i_SPECIAL_DSRAV:
case R4300i_SPECIAL_ADD:
case R4300i_SPECIAL_ADDU:
case R4300i_SPECIAL_SUB:
case R4300i_SPECIAL_SUBU:
case R4300i_SPECIAL_AND:
case R4300i_SPECIAL_OR:
case R4300i_SPECIAL_XOR:
case R4300i_SPECIAL_NOR:
case R4300i_SPECIAL_SLT:
case R4300i_SPECIAL_SLTU:
case R4300i_SPECIAL_DADD:
case R4300i_SPECIAL_DADDU:
case R4300i_SPECIAL_DSUB:
case R4300i_SPECIAL_DSUBU:
case R4300i_SPECIAL_DSLL:
case R4300i_SPECIAL_DSRL:
case R4300i_SPECIAL_DSRA:
case R4300i_SPECIAL_DSLL32:
case R4300i_SPECIAL_DSRL32:
case R4300i_SPECIAL_DSRA32:
if (Command.rd == 0) { return FALSE; }
if (Command.rd == Reg1) { return TRUE; }
if (Command.rd == Reg2) { return TRUE; }
break;
case R4300i_SPECIAL_MULT:
case R4300i_SPECIAL_MULTU:
case R4300i_SPECIAL_DIV:
case R4300i_SPECIAL_DIVU:
case R4300i_SPECIAL_DMULT:
case R4300i_SPECIAL_DMULTU:
case R4300i_SPECIAL_DDIV:
case R4300i_SPECIAL_DDIVU:
break;
default:
#ifndef EXTERNAL_RELEASE
DisplayError("Does %s effect Delay slot at %X?",R4300iOpcodeName(Command.Hex,PC+4), PC);
#endif
return TRUE;
}
break;
case R4300i_CP0:
switch (Command.rs) {
case R4300i_COP0_MT: break;
case R4300i_COP0_MF:
if (Command.rt == 0) { return FALSE; }
if (Command.rt == Reg1) { return TRUE; }
if (Command.rt == Reg2) { return TRUE; }
break;
default:
if ( (Command.rs & 0x10 ) != 0 ) {
switch( Command.funct ) {
case R4300i_COP0_CO_TLBR: break;
case R4300i_COP0_CO_TLBWI: break;
case R4300i_COP0_CO_TLBWR: break;
case R4300i_COP0_CO_TLBP: break;
default:
#ifndef EXTERNAL_RELEASE
DisplayError("Does %s effect Delay slot at %X?\n6",R4300iOpcodeName(Command.Hex,PC+4), PC);
#endif
return TRUE;
}
} else {
#ifndef EXTERNAL_RELEASE
DisplayError("Does %s effect Delay slot at %X?\n7",R4300iOpcodeName(Command.Hex,PC+4), PC);
#endif
return TRUE;
}
}
break;
case R4300i_CP1:
switch (Command.fmt) {
case R4300i_COP1_MF:
if (Command.rt == 0) { return FALSE; }
if (Command.rt == Reg1) { return TRUE; }
if (Command.rt == Reg2) { return TRUE; }
break;
case R4300i_COP1_CF: break;
case R4300i_COP1_MT: break;
case R4300i_COP1_CT: break;
case R4300i_COP1_S: break;
case R4300i_COP1_D: break;
case R4300i_COP1_W: break;
case R4300i_COP1_L: break;
#ifndef EXTERNAL_RELEASE
default:
DisplayError("Does %s effect Delay slot at %X?",R4300iOpcodeName(Command.Hex,PC+4), PC);
#endif
return TRUE;
}
break;
case R4300i_ANDI:
case R4300i_ORI:
case R4300i_XORI:
case R4300i_LUI:
case R4300i_ADDI:
case R4300i_ADDIU:
case R4300i_SLTI:
case R4300i_SLTIU:
case R4300i_DADDI:
case R4300i_DADDIU:
case R4300i_LB:
case R4300i_LH:
case R4300i_LW:
case R4300i_LWL:
case R4300i_LWR:
case R4300i_LDL:
case R4300i_LDR:
case R4300i_LBU:
case R4300i_LHU:
case R4300i_LD:
case R4300i_LWC1:
case R4300i_LDC1:
if (Command.rt == 0) { return FALSE; }
if (Command.rt == Reg1) { return TRUE; }
if (Command.rt == Reg2) { return TRUE; }
break;
case R4300i_CACHE: break;
case R4300i_SB: break;
case R4300i_SH: break;
case R4300i_SW: break;
case R4300i_SWR: break;
case R4300i_SWL: break;
case R4300i_SWC1: break;
case R4300i_SDC1: break;
case R4300i_SD: break;
default:
#ifndef EXTERNAL_RELEASE
DisplayError("Does %s effect Delay slot at %X?",R4300iOpcodeName(Command.Hex,PC+4), PC);
#endif
return TRUE;
}
return FALSE;
}
#ifdef toremove
void ChangeCompareTimer(void) {
DWORD NextCompare = _Reg->COMPARE_REGISTER - _Reg->COUNT_REGISTER;

View File

@ -20,10 +20,6 @@
#include "pif.h"
#include "Sync Cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
//extern int NextInstruction/*, ManualPaused*/;
extern DWORD JumpToLocation;
extern BOOL TestTimer;
@ -61,7 +57,3 @@ int DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 );
int DelaySlotEffectsJump (DWORD JumpPC);
void InPermLoop ( void );
void DisplayFPS ( void );
#ifdef __cplusplus
}
#endif

View File

@ -169,7 +169,10 @@ void PI_DMA_WRITE (void) {
}
if (_Recompiler && _Recompiler->bSMM_PIDMA())
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
_Recompiler->ClearRecompCode_Phys(_Reg->PI_DRAM_ADDR_REG, _Reg->PI_WR_LEN_REG,CRecompiler::Remove_DMA);
#endif
}
_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
_Reg->MI_INTR_REG |= MI_INTR_PI;

View File

@ -26,6 +26,7 @@ public:
static void _fastcall LH ( void );
static void _fastcall LWL ( void );
static void _fastcall LW ( void );
static void _fastcall LW_LOG ( void );
static void _fastcall LBU ( void );
static void _fastcall LHU ( void );
static void _fastcall LWR ( void );

View File

@ -1,3 +1,4 @@
#ifdef tofix
/*
* Project 64 - A Nintendo 64 emulator.
*
@ -1165,4 +1166,6 @@ void Compile_R4300i_COP1_L_CVT_D (CCodeSection * Section) {
ChangeFPURegFormat(Section,m_CompileOpcode.fd,CRegInfo::FPU_Qword,CRegInfo::FPU_Double,CRegInfo::RoundDefault);
}
#endif
#endif

View File

@ -23,6 +23,7 @@
* should be forwarded to them so if they want them.
*
*/
#ifdef tofix
#include <windows.h>
#include <stdio.h>
#include "c core.h"
@ -1355,80 +1356,6 @@ void UnProtectGPR(CCodeSection * Section, DWORD Reg) {
}
UnMap_AllFPRs(Section);
}*/
void WriteBackRegisters (CCodeSection * Section) {
int count;
BOOL bEdiZero = FALSE;
BOOL bEsiSign = FALSE;
/*** coming soon ***/
BOOL bEaxGprLo = FALSE;
BOOL bEbxGprHi = FALSE;
for (count = 1; count < 10; count ++) { Section->x86Protected(count) = FALSE; }
for (count = 1; count < 10; count ++) { UnMap_X86reg (Section, count); }
/*************************************/
for (count = 1; count < 32; count ++) {
switch (Section->MipsRegState(count)) {
case CRegInfo::STATE_UNKNOWN: break;
case CRegInfo::STATE_CONST_32:
if (!bEdiZero && (!Section->MipsRegLo(count) || !(Section->MipsRegLo(count) & 0x80000000))) {
XorX86RegToX86Reg(x86_EDI, x86_EDI);
bEdiZero = TRUE;
}
if (!bEsiSign && (Section->MipsRegLo(count) & 0x80000000)) {
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
bEsiSign = TRUE;
}
if ((Section->MipsRegLo(count) & 0x80000000) != 0) {
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[1],GPR_NameHi[count]);
} else {
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[1],GPR_NameHi[count]);
}
if (Section->MipsRegLo(count) == 0) {
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],GPR_NameLo[count]);
} else if (Section->MipsRegLo(count) == 0xFFFFFFFF) {
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[0],GPR_NameLo[count]);
} else
MoveConstToVariable(Section->MipsRegLo(count),&_GPR[count].UW[0],GPR_NameLo[count]);
Section->MipsRegState(count) = CRegInfo::STATE_UNKNOWN;
break;
case CRegInfo::STATE_CONST_64:
if (Section->MipsRegLo(count) == 0 || Section->MipsRegHi(count) == 0) {
XorX86RegToX86Reg(x86_EDI, x86_EDI);
bEdiZero = TRUE;
}
if (Section->MipsRegLo(count) == 0xFFFFFFFF || Section->MipsRegHi(count) == 0xFFFFFFFF) {
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
bEsiSign = TRUE;
}
if (Section->MipsRegHi(count) == 0) {
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[1],GPR_NameHi[count]);
} else if (Section->MipsRegLo(count) == 0xFFFFFFFF) {
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[1],GPR_NameHi[count]);
} else {
MoveConstToVariable(Section->MipsRegHi(count),&_GPR[count].UW[1],GPR_NameHi[count]);
}
if (Section->MipsRegLo(count) == 0) {
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],GPR_NameLo[count]);
} else if (Section->MipsRegLo(count) == 0xFFFFFFFF) {
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[0],GPR_NameLo[count]);
} else {
MoveConstToVariable(Section->MipsRegLo(count),&_GPR[count].UW[0],GPR_NameLo[count]);
}
Section->MipsRegState(count) = CRegInfo::STATE_UNKNOWN;
break;
#ifndef EXTERNAL_RELEASE
default:
DisplayError("Unknown State: %d\nin WriteBackRegisters",Section->MipsRegState(count));
#endif
}
}
UnMap_AllFPRs(Section);
}
#endif

View File

@ -226,7 +226,6 @@ void SetupRegisters ( N64_REGISTERS * n64_Registers );
}
#endif
#endif
BOOL Is8BitReg ( int x86Reg);
void ChangeFPURegFormat ( CCodeSection * Section, int Reg, CRegInfo::FPU_STATE OldFormat, CRegInfo::FPU_STATE NewFormat, CRegInfo::FPU_ROUND RoundingModel );
@ -245,3 +244,5 @@ BOOL UnMap_X86reg ( CCodeSection * Section, DWORD x86Reg );
void UnProtectGPR ( CCodeSection * Section, DWORD Reg );
void WriteBackRegisters ( CCodeSection * Section );
void FixRoundModel ( CCodeSection * Section, CRegInfo::FPU_ROUND RoundMethod );
#endif

View File

@ -1,3 +1,5 @@
#ifdef tofix
/*
* Project 64 - A Nintendo 64 emulator.
*
@ -3009,3 +3011,5 @@ void * GetAddressOf(int value, ...) {
return Address;
}
#endif

View File

@ -1,3 +1,5 @@
#ifdef toremove
/*
* Project 64 - A Nintendo 64 emulator.
*
@ -281,3 +283,5 @@ void fpuSubRegPop ( int x86reg );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -28,6 +28,9 @@
#include "CPU.h"
#include "debugger.h"
#define FPR_Type(Reg) (Reg) == R4300i_COP1_S ? "S" : (Reg) == R4300i_COP1_D ? "D" :\
(Reg) == R4300i_COP1_W ? "W" : "L"
BOOL InR4300iCommandsWindow = FALSE;
char CommandName[100];

View File

@ -1,3 +1,5 @@
#ifdef tofix
/*
* Project 64 - A Nintendo 64 emulator.
*
@ -40,755 +42,7 @@
(Reg) == x86_ST6 ? "ST(6)" : (Reg) == x86_ST7 ? "ST(7)" :\
"Unknown x86fpu Register"
static char fpupop[2][2] = {
"", "p"
};
void fpuAbs(void) {
CPU_Message(" fabs ST(0)");
PUTDST16(RecompPos,0xE1D9);
}
void fpuAddDword(void *Variable, const char * VariableName) {
CPU_Message(" fadd ST(0), dword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x05D8);
PUTDST32(RecompPos,Variable);
}
void fpuAddDwordRegPointer(int x86Pointer) {
CPU_Message(" fadd ST(0), dword ptr [%s]",x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: PUTDST16(RecompPos,0x00D8); break;
case x86_EBX: PUTDST16(RecompPos,0x03D8); break;
case x86_ECX: PUTDST16(RecompPos,0x01D8); break;
case x86_EDX: PUTDST16(RecompPos,0x02D8); break;
case x86_ESI: PUTDST16(RecompPos,0x06D8); break;
case x86_EDI: PUTDST16(RecompPos,0x07D8); break;
default:
DisplayError("fpuAddDwordRegPointer\nUnknown x86 Register");
break;
}
}
void fpuAddQword(void *Variable, const char * VariableName) {
CPU_Message(" fadd ST(0), qword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x05DC);
PUTDST32(RecompPos,Variable);
}
void fpuAddQwordRegPointer(int x86Pointer) {
CPU_Message(" fadd ST(0), qword ptr [%s]",x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: PUTDST16(RecompPos,0x00DC); break;
case x86_EBX: PUTDST16(RecompPos,0x03DC); break;
case x86_ECX: PUTDST16(RecompPos,0x01DC); break;
case x86_EDX: PUTDST16(RecompPos,0x02DC); break;
case x86_ESI: PUTDST16(RecompPos,0x06DC); break;
case x86_EDI: PUTDST16(RecompPos,0x07DC); break;
default:
DisplayError("fpuAddQwordRegPointer\nUnknown x86 Register");
break;
}
}
void fpuAddReg(int x86reg) {
CPU_Message(" fadd ST(0), %s",fpu_Name(x86reg));
switch (x86reg) {
case x86_ST0: PUTDST16(RecompPos,0xC0D8); break;
case x86_ST1: PUTDST16(RecompPos,0xC1D8); break;
case x86_ST2: PUTDST16(RecompPos,0xC2D8); break;
case x86_ST3: PUTDST16(RecompPos,0xC3D8); break;
case x86_ST4: PUTDST16(RecompPos,0xC4D8); break;
case x86_ST5: PUTDST16(RecompPos,0xC5D8); break;
case x86_ST6: PUTDST16(RecompPos,0xC6D8); break;
case x86_ST7: PUTDST16(RecompPos,0xC7D8); break;
default:
DisplayError("fpuAddReg\nUnknown x86 Register");
break;
}
}
void fpuAddRegPop(int * StackPos, int x86reg) {
CPU_Message(" faddp ST(0), %s",fpu_Name(x86reg));
*StackPos = (*StackPos + 1) & 7;
switch (x86reg) {
case x86_ST0: PUTDST16(RecompPos,0xC0DE); break;
case x86_ST1: PUTDST16(RecompPos,0xC1DE); break;
case x86_ST2: PUTDST16(RecompPos,0xC2DE); break;
case x86_ST3: PUTDST16(RecompPos,0xC3DE); break;
case x86_ST4: PUTDST16(RecompPos,0xC4DE); break;
case x86_ST5: PUTDST16(RecompPos,0xC5DE); break;
case x86_ST6: PUTDST16(RecompPos,0xC6DE); break;
case x86_ST7: PUTDST16(RecompPos,0xC7DE); break;
default:
DisplayError("fpuAddReg\nUnknown x86 Register");
break;
}
}
void fpuComDword(void *Variable, const char * VariableName, BOOL Pop) {
CPU_Message(" fcom%s ST(0), dword ptr [%s]", fpupop[Pop], VariableName);
PUTDST16(RecompPos, (Pop == TRUE) ? 0x1DD8 : 0x15D8);
PUTDST32(RecompPos,Variable);
}
void fpuComDwordRegPointer(int x86Pointer, BOOL Pop) {
WORD x86Command;
CPU_Message(" fcom%s ST(0), dword ptr [%s]",fpupop[Pop],x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: x86Command = 0x10D8; break;
case x86_EBX: x86Command = 0x13D8; break;
case x86_ECX: x86Command = 0x11D8; break;
case x86_EDX: x86Command = 0x12D8; break;
case x86_ESI: x86Command = 0x16D8; break;
case x86_EDI: x86Command = 0x17D8; break;
}
if (Pop) { x86Command |= 0x0800; }
PUTDST16(RecompPos,x86Command);
}
void fpuComQword(void *Variable, const char * VariableName, BOOL Pop) {
CPU_Message(" fcom%s ST(0), qword ptr [%s]", fpupop[Pop], VariableName);
PUTDST16(RecompPos, (Pop == TRUE) ? 0x1DDC : 0x15DC);
PUTDST32(RecompPos,Variable);
}
void fpuComQwordRegPointer(int x86Pointer, BOOL Pop) {
WORD x86Command;
CPU_Message(" fcom%s ST(0), qword ptr [%s]",fpupop[Pop],x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: x86Command = 0x10DC; break;
case x86_EBX: x86Command = 0x13DC; break;
case x86_ECX: x86Command = 0x11DC; break;
case x86_EDX: x86Command = 0x12DC; break;
case x86_ESI: x86Command = 0x16DC; break;
case x86_EDI: x86Command = 0x17DC; break;
}
if (Pop) { x86Command |= 0x0800; }
PUTDST16(RecompPos,x86Command);
}
void fpuComReg(int x86reg, BOOL Pop) {
int s = (Pop == TRUE) ? 0x0800 : 0x0000;
CPU_Message(" fcom%s ST(0), %s", fpupop[Pop], fpu_Name(x86reg));
switch (x86reg) {
case x86_ST0: PUTDST16(RecompPos,0xD0D8|s); break;
case x86_ST1: PUTDST16(RecompPos,0xD1D8|s); break;
case x86_ST2: PUTDST16(RecompPos,0xD2D8|s); break;
case x86_ST3: PUTDST16(RecompPos,0xD3D8|s); break;
case x86_ST4: PUTDST16(RecompPos,0xD4D8|s); break;
case x86_ST5: PUTDST16(RecompPos,0xD5D8|s); break;
case x86_ST6: PUTDST16(RecompPos,0xD6D8|s); break;
case x86_ST7: PUTDST16(RecompPos,0xD7D8|s); break;
default:
DisplayError("fpuComReg\nUnknown x86 Register");
break;
}
}
void fpuDivDword(void *Variable, const char * VariableName) {
CPU_Message(" fdiv ST(0), dword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x35D8);
PUTDST32(RecompPos,Variable);
}
void fpuDivDwordRegPointer(int x86Pointer) {
CPU_Message(" fdiv ST(0), dword ptr [%s]",x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: PUTDST16(RecompPos,0x30D8); break;
case x86_EBX: PUTDST16(RecompPos,0x33D8); break;
case x86_ECX: PUTDST16(RecompPos,0x31D8); break;
case x86_EDX: PUTDST16(RecompPos,0x32D8); break;
case x86_ESI: PUTDST16(RecompPos,0x36D8); break;
case x86_EDI: PUTDST16(RecompPos,0x37D8); break;
default:
DisplayError("fpuDivDwordRegPointer\nUnknown x86 Register");
break;
}
}
void fpuDivQword(void *Variable, const char * VariableName) {
CPU_Message(" fdiv ST(0), qword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x35DC);
PUTDST32(RecompPos,Variable);
}
void fpuDivQwordRegPointer(int x86Pointer) {
CPU_Message(" fdiv ST(0), qword ptr [%s]",x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: PUTDST16(RecompPos,0x30DC); break;
case x86_EBX: PUTDST16(RecompPos,0x33DC); break;
case x86_ECX: PUTDST16(RecompPos,0x31DC); break;
case x86_EDX: PUTDST16(RecompPos,0x32DC); break;
case x86_ESI: PUTDST16(RecompPos,0x36DC); break;
case x86_EDI: PUTDST16(RecompPos,0x37DC); break;
default:
DisplayError("fpuDivQwordRegPointer\nUnknown x86 Register");
break;
}
}
void fpuDivReg(int Reg) {
CPU_Message(" fdiv ST(0), %s", fpu_Name(Reg));
switch (Reg) {
case x86_ST0: PUTDST16(RecompPos,0xF0D8); break;
case x86_ST1: PUTDST16(RecompPos,0xF1D8); break;
case x86_ST2: PUTDST16(RecompPos,0xF2D8); break;
case x86_ST3: PUTDST16(RecompPos,0xF3D8); break;
case x86_ST4: PUTDST16(RecompPos,0xF4D8); break;
case x86_ST5: PUTDST16(RecompPos,0xF5D8); break;
case x86_ST6: PUTDST16(RecompPos,0xF6D8); break;
case x86_ST7: PUTDST16(RecompPos,0xF7D8); break;
default:
DisplayError("fpuDivReg\nUnknown x86 Register");
break;
}
}
void fpuDivRegPop(int x86reg) {
CPU_Message(" fdivp ST(0), %s",fpu_Name(x86reg));
switch (x86reg) {
case x86_ST0: PUTDST16(RecompPos,0xF8DE); break;
case x86_ST1: PUTDST16(RecompPos,0xF9DE); break;
case x86_ST2: PUTDST16(RecompPos,0xFADE); break;
case x86_ST3: PUTDST16(RecompPos,0xFBDE); break;
case x86_ST4: PUTDST16(RecompPos,0xFCDE); break;
case x86_ST5: PUTDST16(RecompPos,0xFDDE); break;
case x86_ST6: PUTDST16(RecompPos,0xFEDE); break;
case x86_ST7: PUTDST16(RecompPos,0xFFDE); break;
default:
DisplayError("fpuDivReg\nUnknown x86 Register");
break;
}
}
void fpuExchange(int Reg) {
CPU_Message(" fxch ST(0), %s",fpu_Name(Reg));
switch (Reg) {
case x86_ST0: PUTDST16(RecompPos,0xC8D9); break;
case x86_ST1: PUTDST16(RecompPos,0xC9D9); break;
case x86_ST2: PUTDST16(RecompPos,0xCAD9); break;
case x86_ST3: PUTDST16(RecompPos,0xCBD9); break;
case x86_ST4: PUTDST16(RecompPos,0xCCD9); break;
case x86_ST5: PUTDST16(RecompPos,0xCDD9); break;
case x86_ST6: PUTDST16(RecompPos,0xCED9); break;
case x86_ST7: PUTDST16(RecompPos,0xCFD9); break;
default:
DisplayError("fpuExchange\nUnknown x86 Register: %i", Reg);
break;
}
}
void fpuFree(int Reg) {
CPU_Message(" ffree %s",fpu_Name(Reg));
switch (Reg) {
case x86_ST0: PUTDST16(RecompPos,0xC0DD); break;
case x86_ST1: PUTDST16(RecompPos,0xC1DD); break;
case x86_ST2: PUTDST16(RecompPos,0xC2DD); break;
case x86_ST3: PUTDST16(RecompPos,0xC3DD); break;
case x86_ST4: PUTDST16(RecompPos,0xC4DD); break;
case x86_ST5: PUTDST16(RecompPos,0xC5DD); break;
case x86_ST6: PUTDST16(RecompPos,0xC6DD); break;
case x86_ST7: PUTDST16(RecompPos,0xC7DD); break;
default:
DisplayError("fpuFree\nUnknown x86 Register");
break;
}
}
void fpuDecStack(int * StackPos) {
CPU_Message(" fdecstp");
*StackPos = (*StackPos - 1) & 7;
PUTDST16(RecompPos,0xF6D9);
}
void fpuIncStack(int * StackPos) {
CPU_Message(" fincstp");
*StackPos = (*StackPos + 1) & 7;
PUTDST16(RecompPos,0xF7D9);
}
void fpuLoadControl(void *Variable, const char * VariableName) {
CPU_Message(" fldcw [%s]",VariableName);
PUTDST16(RecompPos,0x2DD9);
PUTDST32(RecompPos,Variable);
}
void fpuLoadDword(int * StackPos,void *Variable, const char * VariableName) {
CPU_Message(" fld dword ptr [%s]",VariableName);
*StackPos = (*StackPos - 1) & 7;
PUTDST16(RecompPos,0x05D9);
PUTDST32(RecompPos,Variable);
}
void fpuLoadDwordFromX86Reg(int * StackPos, int x86Reg) {
CPU_Message(" fld dword ptr [%s]",x86_Name(x86Reg));
*StackPos = (*StackPos - 1) & 7;
PUTDST8(RecompPos,0xD9);
switch (x86Reg) {
case x86_EAX: PUTDST8(RecompPos,0x00); break;
case x86_EBX: PUTDST8(RecompPos,0x03); break;
case x86_ECX: PUTDST8(RecompPos,0x01); break;
case x86_EDX: PUTDST8(RecompPos,0x02); break;
case x86_ESI: PUTDST8(RecompPos,0x06); break;
case x86_EDI: PUTDST8(RecompPos,0x07); break;
default:
DisplayError("fpuLoadDwordFromX86Reg\nUnknown x86 Register");
}
}
void fpuLoadDwordFromN64Mem(int * StackPos,int x86reg) {
CPU_Message(" fld dword ptr [%s+N64mem]",x86_Name(x86reg));
*StackPos = (*StackPos - 1) & 7;
switch (x86reg) {
case x86_EAX: PUTDST16(RecompPos,0x80D9); break;
case x86_EBX: PUTDST16(RecompPos,0x83D9); break;
case x86_ECX: PUTDST16(RecompPos,0x81D9); break;
case x86_EDX: PUTDST16(RecompPos,0x82D9); break;
case x86_ESI: PUTDST16(RecompPos,0x86D9); break;
case x86_EDI: PUTDST16(RecompPos,0x87D9); break;
case x86_EBP: PUTDST16(RecompPos,0x85D9); break;
default:
DisplayError("fpuLoadDwordFromN64Mem\nUnknown x86 Register");
}
PUTDST32(RecompPos,_MMU->Rdram());
}
void fpuLoadInt32bFromN64Mem(int * StackPos,int x86reg) {
CPU_Message(" fild dword ptr [%s+N64mem]",x86_Name(x86reg));
*StackPos = (*StackPos - 1) & 7;
switch (x86reg) {
case x86_EAX: PUTDST16(RecompPos,0x80DB); break;
case x86_EBX: PUTDST16(RecompPos,0x83DB); break;
case x86_ECX: PUTDST16(RecompPos,0x81DB); break;
case x86_EDX: PUTDST16(RecompPos,0x82DB); break;
case x86_ESI: PUTDST16(RecompPos,0x86DB); break;
case x86_EDI: PUTDST16(RecompPos,0x87DB); break;
case x86_EBP: PUTDST16(RecompPos,0x85DB); break;
default:
DisplayError("fpuLoadIntDwordFromN64Mem\nUnknown x86 Register");
}
PUTDST32(RecompPos,_MMU->Rdram());
}
void fpuLoadIntegerDword(int * StackPos,void *Variable, const char * VariableName) {
CPU_Message(" fild dword ptr [%s]",VariableName);
*StackPos = (*StackPos - 1) & 7;
PUTDST16(RecompPos,0x05DB);
PUTDST32(RecompPos,Variable);
}
void fpuLoadIntegerDwordFromX86Reg(int * StackPos,int x86Reg) {
CPU_Message(" fild dword ptr [%s]",x86_Name(x86Reg));
*StackPos = (*StackPos - 1) & 7;
PUTDST8(RecompPos,0xDB);
switch (x86Reg) {
case x86_EAX: PUTDST8(RecompPos,0x00); break;
case x86_EBX: PUTDST8(RecompPos,0x03); break;
case x86_ECX: PUTDST8(RecompPos,0x01); break;
case x86_EDX: PUTDST8(RecompPos,0x02); break;
case x86_ESI: PUTDST8(RecompPos,0x06); break;
case x86_EDI: PUTDST8(RecompPos,0x07); break;
default:
DisplayError("fpuLoadIntegerDwordFromX86Reg\nUnknown x86 Register");
}
}
void fpuLoadIntegerQword(int * StackPos,void *Variable, const char * VariableName) {
CPU_Message(" fild qword ptr [%s]",VariableName);
*StackPos = (*StackPos - 1) & 7;
PUTDST16(RecompPos,0x2DDF);
PUTDST32(RecompPos,Variable);
}
void fpuLoadIntegerQwordFromX86Reg(int * StackPos,int x86Reg) {
CPU_Message(" fild qword ptr [%s]",x86_Name(x86Reg));
*StackPos = (*StackPos - 1) & 7;
PUTDST8(RecompPos,0xDF);
switch (x86Reg) {
case x86_EAX: PUTDST8(RecompPos,0x28); break;
case x86_EBX: PUTDST8(RecompPos,0x2B); break;
case x86_ECX: PUTDST8(RecompPos,0x29); break;
case x86_EDX: PUTDST8(RecompPos,0x2A); break;
case x86_ESI: PUTDST8(RecompPos,0x2E); break;
case x86_EDI: PUTDST8(RecompPos,0x2F); break;
default:
DisplayError("fpuLoadIntegerDwordFromX86Reg\nUnknown x86 Register");
}
}
void fpuLoadQword(int * StackPos,void *Variable, const char * VariableName) {
CPU_Message(" fld qword ptr [%s]",VariableName);
*StackPos = (*StackPos - 1) & 7;
PUTDST16(RecompPos,0x05DD);
PUTDST32(RecompPos,Variable);
}
void fpuLoadQwordFromX86Reg(int * StackPos, int x86Reg) {
CPU_Message(" fld qword ptr [%s]",x86_Name(x86Reg));
*StackPos = (*StackPos - 1) & 7;
PUTDST8(RecompPos,0xDD);
switch (x86Reg) {
case x86_EAX: PUTDST8(RecompPos,0x00); break;
case x86_EBX: PUTDST8(RecompPos,0x03); break;
case x86_ECX: PUTDST8(RecompPos,0x01); break;
case x86_EDX: PUTDST8(RecompPos,0x02); break;
case x86_ESI: PUTDST8(RecompPos,0x06); break;
case x86_EDI: PUTDST8(RecompPos,0x07); break;
default:
DisplayError("fpuLoadQwordFromX86Reg\nUnknown x86 Register");
}
}
void fpuLoadQwordFromN64Mem(int * StackPos,int x86reg) {
CPU_Message(" fld qword ptr [%s+N64mem]",x86_Name(x86reg));
*StackPos = (*StackPos - 1) & 7;
switch (x86reg) {
case x86_EAX: PUTDST16(RecompPos,0x80DD); break;
case x86_EBX: PUTDST16(RecompPos,0x83DD); break;
case x86_ECX: PUTDST16(RecompPos,0x81DD); break;
case x86_EDX: PUTDST16(RecompPos,0x82DD); break;
case x86_ESI: PUTDST16(RecompPos,0x86DD); break;
case x86_EDI: PUTDST16(RecompPos,0x87DD); break;
case x86_EBP: PUTDST16(RecompPos,0x85DD); break;
default:
DisplayError("fpuLoadQwordFromN64Mem\nUnknown x86 Register");
}
PUTDST32(RecompPos,_MMU->Rdram());
}
void fpuLoadReg(int * StackPos,int Reg) {
CPU_Message(" fld ST(0), %s",fpu_Name(Reg));
*StackPos = (*StackPos - 1) & 7;
switch (Reg) {
case x86_ST0: PUTDST16(RecompPos,0xC0D9); break;
case x86_ST1: PUTDST16(RecompPos,0xC1D9); break;
case x86_ST2: PUTDST16(RecompPos,0xC2D9); break;
case x86_ST3: PUTDST16(RecompPos,0xC3D9); break;
case x86_ST4: PUTDST16(RecompPos,0xC4D9); break;
case x86_ST5: PUTDST16(RecompPos,0xC5D9); break;
case x86_ST6: PUTDST16(RecompPos,0xC6D9); break;
case x86_ST7: PUTDST16(RecompPos,0xC7D9); break;
default:
DisplayError("fpuLoadReg\nUnknown x86 Register:%i", Reg);
break;
}
}
void fpuMulDword(void *Variable, const char * VariableName) {
CPU_Message(" fmul ST(0), dword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x0DD8);
PUTDST32(RecompPos,Variable);
}
void fpuMulDwordRegPointer(int x86Pointer) {
CPU_Message(" fmul ST(0), dword ptr [%s]",x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: PUTDST16(RecompPos,0x08D8); break;
case x86_EBX: PUTDST16(RecompPos,0x0BD8); break;
case x86_ECX: PUTDST16(RecompPos,0x09D8); break;
case x86_EDX: PUTDST16(RecompPos,0x0AD8); break;
case x86_ESI: PUTDST16(RecompPos,0x0ED8); break;
case x86_EDI: PUTDST16(RecompPos,0x0FD8); break;
default:
DisplayError("fpuMulDwordRegPointer\nUnknown x86 Register");
break;
}
}
void fpuMulQword(void *Variable, const char * VariableName) {
CPU_Message(" fmul ST(0), qword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x0DDC);
PUTDST32(RecompPos,Variable);
}
void fpuMulQwordRegPointer(int x86Pointer) {
CPU_Message(" fmul ST(0), qword ptr [%s]",x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: PUTDST16(RecompPos,0x08DC); break;
case x86_EBX: PUTDST16(RecompPos,0x0BDC); break;
case x86_ECX: PUTDST16(RecompPos,0x09DC); break;
case x86_EDX: PUTDST16(RecompPos,0x0ADC); break;
case x86_ESI: PUTDST16(RecompPos,0x0EDC); break;
case x86_EDI: PUTDST16(RecompPos,0x0FDC); break;
default:
DisplayError("fpuMulQwordRegPointer\nUnknown x86 Register");
break;
}
}
void fpuMulReg(int x86reg) {
CPU_Message(" fmul ST(0), %s",fpu_Name(x86reg));
switch (x86reg) {
case x86_ST0: PUTDST16(RecompPos,0xC8D8); break;
case x86_ST1: PUTDST16(RecompPos,0xC9D8); break;
case x86_ST2: PUTDST16(RecompPos,0xCAD8); break;
case x86_ST3: PUTDST16(RecompPos,0xCBD8); break;
case x86_ST4: PUTDST16(RecompPos,0xCCD8); break;
case x86_ST5: PUTDST16(RecompPos,0xCDD8); break;
case x86_ST6: PUTDST16(RecompPos,0xCED8); break;
case x86_ST7: PUTDST16(RecompPos,0xCFD8); break;
default:
DisplayError("fpuMulReg\nUnknown x86 Register");
break;
}
}
void fpuMulRegPop(int x86reg) {
CPU_Message(" fmulp ST(0), %s",fpu_Name(x86reg));
switch (x86reg) {
case x86_ST0: PUTDST16(RecompPos,0xC8DE); break;
case x86_ST1: PUTDST16(RecompPos,0xC9DE); break;
case x86_ST2: PUTDST16(RecompPos,0xCADE); break;
case x86_ST3: PUTDST16(RecompPos,0xCBDE); break;
case x86_ST4: PUTDST16(RecompPos,0xCCDE); break;
case x86_ST5: PUTDST16(RecompPos,0xCDDE); break;
case x86_ST6: PUTDST16(RecompPos,0xCEDE); break;
case x86_ST7: PUTDST16(RecompPos,0xCFDE); break;
default:
DisplayError("fpuMulReg\nUnknown x86 Register");
break;
}
}
void fpuNeg(void) {
CPU_Message(" fchs ST(0)");
PUTDST16(RecompPos,0xE0D9);
}
void fpuRound(void) {
CPU_Message(" frndint ST(0)");
PUTDST16(RecompPos,0xFCD9);
}
void fpuSqrt(void) {
CPU_Message(" fsqrt ST(0)");
PUTDST16(RecompPos,0xFAD9);
}
void fpuStoreControl(void *Variable, const char * VariableName) {
CPU_Message(" fnstcw [%s]",VariableName);
PUTDST16(RecompPos,0x3DD9);
PUTDST32(RecompPos,Variable);
}
void fpuStoreDword(int * StackPos,void *Variable, const char * VariableName, BOOL pop) {
CPU_Message(" fst%s dword ptr [%s]", fpupop[pop], VariableName);
if (pop) { *StackPos = (*StackPos + 1) & 7; }
PUTDST16(RecompPos,(pop == FALSE) ? 0x15D9 : 0x1DD9);
PUTDST32(RecompPos,Variable);
}
void fpuStoreDwordFromX86Reg(int * StackPos,int x86Reg, BOOL pop) {
BYTE Command;
CPU_Message(" fst%s dword ptr [%s]", fpupop[pop], x86_Name(x86Reg));
if (pop) { *StackPos = (*StackPos + 1) & 7; }
PUTDST8(RecompPos,0xD9);
switch (x86Reg) {
case x86_EAX: Command = 0x10; break;
case x86_EBX: Command = 0x13; break;
case x86_ECX: Command = 0x11; break;
case x86_EDX: Command = 0x12; break;
case x86_ESI: Command = 0x16; break;
case x86_EDI: Command = 0x17; break;
default:
DisplayError("fpuStoreIntegerQwordFromX86Reg\nUnknown x86 Register");
}
PUTDST8(RecompPos, (pop == FALSE) ? Command : (Command + 0x8));
}
void fpuStoreDwordToN64Mem(int * StackPos,int x86reg, BOOL Pop) {
int s = (Pop == TRUE) ? 0x0800 : 0;
CPU_Message(" fst%s dword ptr [%s+N64mem]", fpupop[Pop], x86_Name(x86reg));
if (Pop) { *StackPos = (*StackPos + 1) & 7; }
switch (x86reg) {
case x86_EAX: PUTDST16(RecompPos,0x90D9|s); break;
case x86_EBX: PUTDST16(RecompPos,0x93D9|s); break;
case x86_ECX: PUTDST16(RecompPos,0x91D9|s); break;
case x86_EDX: PUTDST16(RecompPos,0x92D9|s); break;
case x86_ESI: PUTDST16(RecompPos,0x96D9|s); break;
case x86_EDI: PUTDST16(RecompPos,0x97D9|s); break;
case x86_EBP: PUTDST16(RecompPos,0x95D9|s); break;
default:
DisplayError("fpuStoreDwordToN64Mem\nUnknown x86 Register");
}
PUTDST32(RecompPos,_MMU->Rdram());
}
void fpuStoreIntegerDword(int * StackPos,void *Variable, const char * VariableName, BOOL pop) {
CPU_Message(" fist%s dword ptr [%s]", fpupop[pop], VariableName);
if (pop) { *StackPos = (*StackPos + 1) & 7; }
PUTDST16(RecompPos, (pop == FALSE) ? 0x15DB : 0x1DDB);
PUTDST32(RecompPos,Variable);
}
void fpuStoreIntegerDwordFromX86Reg(int * StackPos,int x86Reg, BOOL pop) {
BYTE Command;
CPU_Message(" fist%s dword ptr [%s]", fpupop[pop], x86_Name(x86Reg));
if (pop) { *StackPos = (*StackPos + 1) & 7; }
PUTDST8(RecompPos,0xDB);
switch (x86Reg) {
case x86_EAX: Command = 0x10; break;
case x86_EBX: Command = 0x13; break;
case x86_ECX: Command = 0x11; break;
case x86_EDX: Command = 0x12; break;
case x86_ESI: Command = 0x16; break;
case x86_EDI: Command = 0x17; break;
default:
DisplayError("fpuStoreIntegerDwordFromX86Reg\nUnknown x86 Register");
}
PUTDST8(RecompPos, (pop == FALSE) ? Command : (Command + 0x8));
}
void fpuStoreIntegerQword(int * StackPos,void *Variable, const char * VariableName, BOOL pop) {
CPU_Message(" fist%s qword ptr [%s]", fpupop[pop], VariableName);
if (pop) { *StackPos = (*StackPos + 1) & 7; }
PUTDST16(RecompPos, (pop == FALSE) ? 0x35DF : 0x3DDF);
PUTDST32(RecompPos,Variable);
if (!pop) { X86BreakPoint(__FILE__,__LINE__); }
}
void fpuStoreIntegerQwordFromX86Reg(int * StackPos, int x86Reg, BOOL pop) {
BYTE Command;
CPU_Message(" fist%s qword ptr [%s]", fpupop[pop], x86_Name(x86Reg));
if (pop) { *StackPos = (*StackPos + 1) & 7; }
PUTDST8(RecompPos,0xDF);
switch (x86Reg) {
case x86_EAX: Command = 0x30; break;
case x86_EBX: Command = 0x33; break;
case x86_ECX: Command = 0x31; break;
case x86_EDX: Command = 0x32; break;
case x86_ESI: Command = 0x36; break;
case x86_EDI: Command = 0x37; break;
default:
DisplayError("fpuStoreIntegerQwordFromX86Reg\nUnknown x86 Register");
}
PUTDST8(RecompPos, (pop == FALSE) ? Command : (Command + 0x8));
}
void fpuStoreQwordFromX86Reg(int * StackPos, int x86Reg, BOOL pop) {
BYTE Command;
CPU_Message(" fst%s qword ptr [%s]", fpupop[pop], x86_Name(x86Reg));
if (pop) { *StackPos = (*StackPos + 1) & 7; }
PUTDST8(RecompPos,0xDD);
switch (x86Reg) {
case x86_EAX: Command = 0x10; break;
case x86_EBX: Command = 0x13; break;
case x86_ECX: Command = 0x11; break;
case x86_EDX: Command = 0x12; break;
case x86_ESI: Command = 0x16; break;
case x86_EDI: Command = 0x17; break;
default:
DisplayError("fpuStoreQwordFromX86Reg\nUnknown x86 Register");
}
PUTDST8(RecompPos, (pop == FALSE) ? Command : (Command + 0x8));
}
void fpuStoreStatus(void) {
CPU_Message(" fnstsw ax");
PUTDST16(RecompPos,0xE0DF);
}
void fpuSubDword(void *Variable, const char * VariableName) {
CPU_Message(" fsub ST(0), dword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x25D8);
PUTDST32(RecompPos,Variable);
}
void fpuSubDwordRegPointer(int x86Pointer) {
CPU_Message(" fsub ST(0), dword ptr [%s]",x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: PUTDST16(RecompPos,0x20D8); break;
case x86_EBX: PUTDST16(RecompPos,0x23D8); break;
case x86_ECX: PUTDST16(RecompPos,0x21D8); break;
case x86_EDX: PUTDST16(RecompPos,0x22D8); break;
case x86_ESI: PUTDST16(RecompPos,0x26D8); break;
case x86_EDI: PUTDST16(RecompPos,0x27D8); break;
default:
DisplayError("fpuSubDwordRegPointer\nUnknown x86 Register");
break;
}
}
void fpuSubDwordReverse(void *Variable, const char * VariableName) {
CPU_Message(" fsubr ST(0), dword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x2DD8);
PUTDST32(RecompPos,Variable);
}
void fpuSubQword(void *Variable, const char * VariableName) {
CPU_Message(" fsub ST(0), qword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x25DC);
PUTDST32(RecompPos,Variable);
}
void fpuSubQwordRegPointer(int x86Pointer) {
CPU_Message(" fsub ST(0), qword ptr [%s]",x86_Name(x86Pointer));
switch (x86Pointer) {
case x86_EAX: PUTDST16(RecompPos,0x20DC); break;
case x86_EBX: PUTDST16(RecompPos,0x23DC); break;
case x86_ECX: PUTDST16(RecompPos,0x21DC); break;
case x86_EDX: PUTDST16(RecompPos,0x22DC); break;
case x86_ESI: PUTDST16(RecompPos,0x26DC); break;
case x86_EDI: PUTDST16(RecompPos,0x27DC); break;
default:
DisplayError("fpuSubQwordRegPointer\nUnknown x86 Register");
break;
}
}
void fpuSubQwordReverse(void *Variable, const char * VariableName) {
CPU_Message(" fsubr ST(0), qword ptr [%s]", VariableName);
PUTDST16(RecompPos,0x2DDC);
PUTDST32(RecompPos,Variable);
}
void fpuSubReg(int x86reg) {
CPU_Message(" fsub ST(0), %s",fpu_Name(x86reg));
switch (x86reg) {
case x86_ST0: PUTDST16(RecompPos,0xE0D8); break;
case x86_ST1: PUTDST16(RecompPos,0xE1D8); break;
case x86_ST2: PUTDST16(RecompPos,0xE2D8); break;
case x86_ST3: PUTDST16(RecompPos,0xE3D8); break;
case x86_ST4: PUTDST16(RecompPos,0xE4D8); break;
case x86_ST5: PUTDST16(RecompPos,0xE5D8); break;
case x86_ST6: PUTDST16(RecompPos,0xE6D8); break;
case x86_ST7: PUTDST16(RecompPos,0xE7D8); break;
default:
DisplayError("fpuSubReg\nUnknown x86 Register");
break;
}
}
void fpuSubRegPop(int x86reg) {
CPU_Message(" fsubp ST(0), %s",fpu_Name(x86reg));
switch (x86reg) {
case x86_ST0: PUTDST16(RecompPos,0xE8DE); break;
case x86_ST1: PUTDST16(RecompPos,0xE9DE); break;
case x86_ST2: PUTDST16(RecompPos,0xEADE); break;
case x86_ST3: PUTDST16(RecompPos,0xEBDE); break;
case x86_ST4: PUTDST16(RecompPos,0xECDE); break;
case x86_ST5: PUTDST16(RecompPos,0xEDDE); break;
case x86_ST6: PUTDST16(RecompPos,0xEEDE); break;
case x86_ST7: PUTDST16(RecompPos,0xEFDE); break;
default:
DisplayError("fpuSubRegPop\nUnknown x86 Register");
break;
}
}
@ -826,7 +80,7 @@ void fpuDivQwordReverse(void *Variable, const char * VariableName) {
// FPU Utility
//
unsigned int fpucontrol;
static unsigned int fpucontrol;
/* returns and pushes current fpu state, bool for set normal */
int fpuSaveControl(BOOL bSetNormal) {
@ -861,4 +115,6 @@ void fpuSetupDouble(void) {
and [temp], 0xFFFFF3FF
fldcw word ptr [temp]
}
}
}
#endif

View File

@ -303,6 +303,8 @@ bool CDumpMemory::DumpMemory ( LPCSTR FileName,DumpFormat Format, DWORD StartPC,
}
LogFile.SetFlush(false);
LogFile.SetTruncateFile(false);
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
char Command[200];
for (COpcode OpCode(StartPC); OpCode.PC() < EndPC; OpCode.Next())
{
@ -310,6 +312,7 @@ bool CDumpMemory::DumpMemory ( LPCSTR FileName,DumpFormat Format, DWORD StartPC,
OpCode.OpcodeParam(Command);
LogFile.LogF("%X: %-15s%s\r\n",OpCode.PC(),szOpName,Command);
}
#endif
m_StartAddress.SetValue(StartPC,true,true);
m_EndAddress.SetValue(EndPC,true,true);
return true;

View File

@ -287,14 +287,6 @@ InterruptsDisabled:
}
void TestInterpreterJump (DWORD PC, DWORD TargetPC, int Reg1, int Reg2) {
if (PC != TargetPC) { return; }
if (DelaySlotEffectsCompare(PC,Reg1,Reg2)) { return; }
InPermLoop();
R4300iOp::m_NextInstruction = DELAY_SLOT;
R4300iOp::m_TestTimer = TRUE;
}
CInterpreterCPU::CInterpreterCPU () :
m_R4300i_Opcode(NULL)
{
@ -307,17 +299,20 @@ CInterpreterCPU::~CInterpreterCPU()
void CInterpreterCPU::StartInterpreterCPU (void )
{
R4300iOp::m_TestTimer = FALSE;
R4300iOp::m_TestTimer = FALSE;
R4300iOp::m_NextInstruction = NORMAL;
R4300iOp::m_JumpToLocation = 0;
DWORD CountPerOp = _Settings->LoadDword(Game_CounterFactor);
bool & Done = _N64System->m_EndEmulation;
DWORD & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
OPCODE & Opcode = R4300iOp::m_Opcode;
DWORD & JumpToLocation = R4300iOp::m_JumpToLocation;
BOOL & TestTimer = R4300iOp::m_TestTimer;
bool & Done = _N64System->m_EndEmulation;
DWORD & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
OPCODE & Opcode = R4300iOp::m_Opcode;
DWORD & JumpToLocation = R4300iOp::m_JumpToLocation;
BOOL & TestTimer = R4300iOp::m_TestTimer;
R4300iOp::Func * R4300i_Opcode = R4300iOp::BuildInterpreter();
//R4300iOp::Func * R4300i_Opcode = R4300iOp32::BuildInterpreter();
__try
{
@ -332,9 +327,10 @@ void CInterpreterCPU::StartInterpreterCPU (void )
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*_NextTimer,_SystemTimer->CurrentType());
}*/
*_NextTimer -= CountPerOp;
((void (_fastcall *)()) R4300i_Opcode[ Opcode.op ])();
R4300i_Opcode[ Opcode.op ]();
switch (R4300iOp::m_NextInstruction) {
switch (R4300iOp::m_NextInstruction)
{
case NORMAL:
PROGRAM_COUNTER += 4;
break;

View File

@ -1,4 +1,5 @@
class CInterpreterCPU
class CInterpreterCPU :
private R4300iOp
{
public:
CInterpreterCPU();

View File

@ -2,7 +2,7 @@
#include "../C Core/Logging.h"
void InPermLoop ( void );
void TestInterpreterJump ( DWORD PC, DWORD TargetPC, int Reg1, int Reg2 );
int DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 );
#define ADDRESS_ERROR_EXCEPTION(Address,FromRead) \
DoAddressError(m_NextInstruction == JUMP,Address,FromRead);\
@ -25,49 +25,7 @@ void TestInterpreterJump ( DWORD PC, DWORD TargetPC, int Reg1, int Reg2 );
m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;
void R4300iOp32::SPECIAL (void) {
((void (*)()) Jump_Special[ m_Opcode.funct ])();
}
void R4300iOp32::REGIMM (void) {
((void (*)()) Jump_Regimm[ m_Opcode.rt ])();
}
void R4300iOp32::COP0 (void) {
((void (*)()) Jump_CoP0[ m_Opcode.rs ])();
}
void R4300iOp32::COP0_CO (void) {
((void (*)()) Jump_CoP0_Function[ m_Opcode.funct ])();
}
void R4300iOp32::COP1 (void) {
((void (*)()) Jump_CoP1[ m_Opcode.fmt ])();
}
void R4300iOp32::COP1_BC (void) {
((void (*)()) Jump_CoP1_BC[ m_Opcode.ft ])();
}
void R4300iOp32::COP1_S (void) {
_controlfp(RoundingModel,_MCW_RC);
((void (*)()) Jump_CoP1_S[ m_Opcode.funct ])();
}
void R4300iOp32::COP1_D (void) {
_controlfp(RoundingModel,_MCW_RC);
((void (*)()) Jump_CoP1_D[ m_Opcode.funct ])();
}
void R4300iOp32::COP1_W (void) {
((void (*)()) Jump_CoP1_W[ m_Opcode.funct ])();
}
void R4300iOp32::COP1_L (void) {
((void (*)()) Jump_CoP1_L[ m_Opcode.funct ])();
}
R4300iOp_FUNC * R4300iOp32::BuildInterpreter (void )
R4300iOp32::Func * R4300iOp32::BuildInterpreter (void )
{
Jump_Opcode[ 0] = SPECIAL;
Jump_Opcode[ 1] = REGIMM;
@ -663,7 +621,11 @@ R4300iOp_FUNC * R4300iOp32::BuildInterpreter (void )
void R4300iOp32::J (void) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2);
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,0,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
InPermLoop();
}
}
void R4300iOp32::JAL (void) {
@ -674,8 +636,6 @@ void R4300iOp32::JAL (void) {
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
InPermLoop();
m_NextInstruction = DELAY_SLOT;
m_TestTimer = TRUE;
}
}
@ -683,7 +643,13 @@ void R4300iOp32::BEQ (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0]) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,m_Opcode.rt);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,m_Opcode.rt))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -693,7 +659,13 @@ void R4300iOp32::BNE (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0]) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,m_Opcode.rt);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,m_Opcode.rt))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -703,7 +675,13 @@ void R4300iOp32::BLEZ (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] <= 0) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -713,7 +691,13 @@ void R4300iOp32::BGTZ (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] > 0) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -790,7 +774,13 @@ void R4300iOp32::BEQL (void) {
if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0]) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,m_Opcode.rt);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,m_Opcode.rt))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -801,7 +791,13 @@ void R4300iOp32::BNEL (void) {
if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0]) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,m_Opcode.rt);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,m_Opcode.rt))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -812,7 +808,13 @@ void R4300iOp32::BLEZL (void) {
if (_GPR[m_Opcode.rs].W[0] <= 0) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -823,7 +825,13 @@ void R4300iOp32::BGTZL (void) {
if (_GPR[m_Opcode.rs].W[0] > 0) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -879,29 +887,13 @@ void R4300iOp32::LW (void) {
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); }
#if (!defined(EXTERNAL_RELEASE))
Log_LW((*_PROGRAM_COUNTER),Address);
#endif
if (LogOptions.GenerateLog)
{
Log_LW((*_PROGRAM_COUNTER),Address);
}
if (m_Opcode.rt == 0) { return; }
#ifdef toremove
if (Address >= 0xA3F00000 && Address < 0xC0000000)
{
if (Address < 0xA4000000 || Address >= 0xA4002000)
{
Address &= 0x1FFFFFFF;
if (!r4300i_LW_NonMemory(Address,&_GPR[m_Opcode.rt].UW[0]))
{
if (ShowUnhandledMemory)
{
DisplayError("Failed to load word\n\nIn LW",Address);
}
}
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].W[0];
return;
}
}
#endif
if (!_MMU->LW_VAddr(Address,_GPR[m_Opcode.rt].UW[0])) {
if (g_ShowTLBMisses) {
DisplayError("LW TLB: %X",Address);
@ -1016,26 +1008,13 @@ void R4300iOp32::SW (void) {
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,FALSE); }
#if (!defined(EXTERNAL_RELEASE))
Log_SW((*_PROGRAM_COUNTER),Address,_GPR[m_Opcode.rt].UW[0]);
#endif
#ifdef toremove
if (Address >= 0xA3F00000 && Address < 0xC0000000)
{
if (Address < 0xA4000000 || Address >= 0xA4002000)
{
Address &= 0x1FFFFFFF;
if (!r4300i_SW_NonMemory(Address,_GPR[m_Opcode.rt].UW[0]))
{
if (ShowUnhandledMemory)
{
DisplayError("Failed to load word\n\nIn SW",Address);
}
}
return;
}
if (LogOptions.GenerateLog)
{
Log_SW((*_PROGRAM_COUNTER),Address,_GPR[m_Opcode.rt].UW[0]);
}
#endif
if (!_MMU->SW_VAddr(Address,_GPR[m_Opcode.rt].UW[0])) {
if (!_MMU->SW_VAddr(Address,_GPR[m_Opcode.rt].UW[0]))
{
#ifndef EXTERNAL_RELEASE
DisplayError("SW TLB: %X",Address);
#endif
@ -1262,7 +1241,13 @@ void R4300iOp32::REGIMM_BLTZ (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] < 0) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -1272,7 +1257,13 @@ void R4300iOp32::REGIMM_BGEZ (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] >= 0) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -1282,7 +1273,13 @@ void R4300iOp32::REGIMM_BLTZL (void) {
if (_GPR[m_Opcode.rs].W[0] < 0) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -1293,7 +1290,13 @@ void R4300iOp32::REGIMM_BGEZL (void) {
if (_GPR[m_Opcode.rs].W[0] >= 0) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -1304,7 +1307,13 @@ void R4300iOp32::REGIMM_BLTZAL (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] < 0) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -1315,7 +1324,13 @@ void R4300iOp32::REGIMM_BGEZAL (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] >= 0) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER),m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}

View File

@ -1,5 +1,3 @@
typedef void ( * R4300iOp_FUNC )();
class R4300iOp32 :
public R4300iOp
{
@ -155,17 +153,5 @@ public:
static void UnknownOpcode ( void );
static R4300iOp_FUNC * BuildInterpreter (void );
private:
static void SPECIAL (void);
static void REGIMM (void);
static void COP0 (void);
static void COP0_CO (void);
static void COP1 (void);
static void COP1_BC (void);
static void COP1_S (void);
static void COP1_D (void);
static void COP1_W (void);
static void COP1_L (void);
static Func * BuildInterpreter (void );
};

View File

@ -34,17 +34,17 @@ DWORD R4300iOp::m_NextInstruction;
OPCODE R4300iOp::m_Opcode;
DWORD R4300iOp::m_JumpToLocation;
R4300iOp_FUNC R4300iOp::Jump_Opcode[64];
R4300iOp_FUNC R4300iOp::Jump_Special[64];
R4300iOp_FUNC R4300iOp::Jump_Regimm[32];
R4300iOp_FUNC R4300iOp::Jump_CoP0[32];
R4300iOp_FUNC R4300iOp::Jump_CoP0_Function[64];
R4300iOp_FUNC R4300iOp::Jump_CoP1[32];
R4300iOp_FUNC R4300iOp::Jump_CoP1_BC[32];
R4300iOp_FUNC R4300iOp::Jump_CoP1_S[64];
R4300iOp_FUNC R4300iOp::Jump_CoP1_D[64];
R4300iOp_FUNC R4300iOp::Jump_CoP1_W[64];
R4300iOp_FUNC R4300iOp::Jump_CoP1_L[64];
R4300iOp::Func R4300iOp::Jump_Opcode[64];
R4300iOp::Func R4300iOp::Jump_Special[64];
R4300iOp::Func R4300iOp::Jump_Regimm[32];
R4300iOp::Func R4300iOp::Jump_CoP0[32];
R4300iOp::Func R4300iOp::Jump_CoP0_Function[64];
R4300iOp::Func R4300iOp::Jump_CoP1[32];
R4300iOp::Func R4300iOp::Jump_CoP1_BC[32];
R4300iOp::Func R4300iOp::Jump_CoP1_S[64];
R4300iOp::Func R4300iOp::Jump_CoP1_D[64];
R4300iOp::Func R4300iOp::Jump_CoP1_W[64];
R4300iOp::Func R4300iOp::Jump_CoP1_L[64];
const DWORD R4300iOp::SWL_MASK[4] = { 0x00000000, 0xFF000000,0xFFFF0000,0xFFFFFF00 };
const DWORD R4300iOp::SWR_MASK[4] = { 0x00FFFFFF, 0x0000FFFF,0x000000FF,0x00000000 };
@ -80,48 +80,48 @@ int RoundingModel = _RC_NEAR;
return;
void R4300iOp::SPECIAL (void) {
((void (*)()) Jump_Special[ m_Opcode.funct ])();
Jump_Special[ m_Opcode.funct ]();
}
void R4300iOp::REGIMM (void) {
((void (*)()) Jump_Regimm[ m_Opcode.rt ])();
Jump_Regimm[ m_Opcode.rt ]();
}
void R4300iOp::COP0 (void) {
((void (*)()) Jump_CoP0[ m_Opcode.rs ])();
Jump_CoP0[ m_Opcode.rs ]();
}
void R4300iOp::COP0_CO (void) {
((void (*)()) Jump_CoP0_Function[ m_Opcode.funct ])();
Jump_CoP0_Function[ m_Opcode.funct ]();
}
void R4300iOp::COP1 (void) {
((void (*)()) Jump_CoP1[ m_Opcode.fmt ])();
Jump_CoP1[ m_Opcode.fmt ]();
}
void R4300iOp::COP1_BC (void) {
((void (*)()) Jump_CoP1_BC[ m_Opcode.ft ])();
Jump_CoP1_BC[ m_Opcode.ft ]();
}
void R4300iOp::COP1_S (void) {
_controlfp(RoundingModel,_MCW_RC);
((void (*)()) Jump_CoP1_S[ m_Opcode.funct ])();
Jump_CoP1_S[ m_Opcode.funct ]();
}
void R4300iOp::COP1_D (void) {
_controlfp(RoundingModel,_MCW_RC);
((void (*)()) Jump_CoP1_D[ m_Opcode.funct ])();
Jump_CoP1_D[ m_Opcode.funct ]();
}
void R4300iOp::COP1_W (void) {
((void (*)()) Jump_CoP1_W[ m_Opcode.funct ])();
Jump_CoP1_W[ m_Opcode.funct ]();
}
void R4300iOp::COP1_L (void) {
((void (*)()) Jump_CoP1_L[ m_Opcode.funct ])();
Jump_CoP1_L[ m_Opcode.funct ]();
}
R4300iOp_FUNC * R4300iOp::BuildInterpreter (void )
R4300iOp::Func * R4300iOp::BuildInterpreter (void )
{
Jump_Opcode[ 0] = SPECIAL;
Jump_Opcode[ 1] = REGIMM;
@ -713,11 +713,25 @@ R4300iOp_FUNC * R4300iOp::BuildInterpreter (void )
return Jump_Opcode;
}
int DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2);
void TestInterpreterJump (DWORD PC, DWORD TargetPC, int Reg1, int Reg2)
{
if (PC != TargetPC) { return; }
if (DelaySlotEffectsCompare(PC,Reg1,Reg2)) { return; }
InPermLoop();
R4300iOp::m_NextInstruction = DELAY_SLOT;
R4300iOp::m_TestTimer = TRUE;
}
/************************* m_Opcode functions *************************/
void R4300iOp::J (void) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2);
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,0,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
InPermLoop();
}
}
void R4300iOp::JAL (void) {
@ -728,8 +742,6 @@ void R4300iOp::JAL (void) {
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
InPermLoop();
m_NextInstruction = DELAY_SLOT;
m_TestTimer = TRUE;
}
}
@ -737,7 +749,13 @@ void R4300iOp::BEQ (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,m_Opcode.rt);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER,m_Opcode.rs,m_Opcode.rt))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -747,7 +765,13 @@ void R4300iOp::BNE (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,m_Opcode.rt);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER,m_Opcode.rs,m_Opcode.rt))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -757,7 +781,13 @@ void R4300iOp::BLEZ (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW <= 0) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER,m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -767,7 +797,13 @@ void R4300iOp::BGTZ (void) {
m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW > 0) {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER,m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
}
@ -844,7 +880,13 @@ void R4300iOp::BEQL (void) {
if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,m_Opcode.rt);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER,m_Opcode.rs,m_Opcode.rt))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -855,7 +897,13 @@ void R4300iOp::BNEL (void) {
if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,m_Opcode.rt);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER,m_Opcode.rs,m_Opcode.rt))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -866,7 +914,13 @@ void R4300iOp::BLEZL (void) {
if (_GPR[m_Opcode.rs].DW <= 0) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER,m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
@ -877,7 +931,13 @@ void R4300iOp::BGTZL (void) {
if (_GPR[m_Opcode.rs].DW > 0) {
m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
TestInterpreterJump((*_PROGRAM_COUNTER),m_JumpToLocation,m_Opcode.rs,0);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER,m_Opcode.rs,0))
{
InPermLoop();
}
}
} else {
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;

View File

@ -1,4 +1,4 @@
#include <windows.h>
//#include <windows.h>
#ifdef toremove
enum MemorySize { _8Bit, _16Bit, _32Bit, _64Bit };
@ -14,6 +14,7 @@ public:
};
class CCodeSection;
class CRegInfo;
class CMipsMemory
{
@ -43,16 +44,16 @@ public:
virtual void UnProtectMemory ( DWORD StartVaddr, DWORD EndVaddr ) = 0;
//Compilation Functions
virtual void ResetMemoryStack ( CCodeSection * Section ) = 0;
virtual void Compile_LB ( int Reg, DWORD Addr, BOOL SignExtend ) = 0;
virtual void Compile_LH ( int Reg, DWORD Addr, BOOL SignExtend ) = 0;
virtual void Compile_LW ( CCodeSection * Section, int Reg, DWORD Addr ) = 0;
virtual void ResetMemoryStack ( CRegInfo & RegInfo ) = 0;
virtual void Compile_LB ( CX86Ops::x86Reg Reg, DWORD Addr, BOOL SignExtend ) = 0;
virtual void Compile_LH ( CX86Ops::x86Reg Reg, DWORD Addr, BOOL SignExtend ) = 0;
virtual void Compile_LW ( CCodeSection * Section, CX86Ops::x86Reg Reg, DWORD Addr ) = 0;
virtual void Compile_SB_Const ( BYTE Value, DWORD Addr ) = 0;
virtual void Compile_SB_Register ( int x86Reg, DWORD Addr ) = 0;
virtual void Compile_SB_Register ( CX86Ops::x86Reg Reg, DWORD Addr ) = 0;
virtual void Compile_SH_Const ( WORD Value, DWORD Addr ) = 0;
virtual void Compile_SH_Register ( int x86Reg, DWORD Addr ) = 0;
virtual void Compile_SH_Register ( CX86Ops::x86Reg Reg, DWORD Addr ) = 0;
virtual void Compile_SW_Const ( DWORD Value, DWORD Addr ) = 0;
virtual void Compile_SW_Register ( CCodeSection * Section, int x86Reg, DWORD Addr ) = 0;
virtual void Compile_SW_Register ( CRegInfo & RegInfo, CX86Ops::x86Reg Reg, DWORD Addr ) = 0;
};
@ -60,7 +61,8 @@ class CRSP_Plugin;
class CMipsMemoryVM :
public CMipsMemory,
public CTransVaddr
public CTransVaddr,
private CX86Ops
#ifdef toremove
,
@ -159,16 +161,16 @@ public:
void UnProtectMemory ( DWORD StartVaddr, DWORD EndVaddr );
//Compilation Functions
void ResetMemoryStack ( CCodeSection * Section );
void Compile_LB ( int Reg, DWORD Addr, BOOL SignExtend );
void Compile_LH ( int Reg, DWORD Addr, BOOL SignExtend );
void Compile_LW ( CCodeSection * Section, int Reg, DWORD Addr );
void ResetMemoryStack ( CRegInfo & RegInfo );
void Compile_LB ( CX86Ops::x86Reg Reg, DWORD Addr, BOOL SignExtend );
void Compile_LH ( CX86Ops::x86Reg Reg, DWORD Addr, BOOL SignExtend );
void Compile_LW ( CCodeSection * Section, CX86Ops::x86Reg Reg, DWORD Addr );
void Compile_SB_Const ( BYTE Value, DWORD Addr );
void Compile_SB_Register ( int x86Reg, DWORD Addr );
void Compile_SB_Register ( CX86Ops::x86Reg Reg, DWORD Addr );
void Compile_SH_Const ( WORD Value, DWORD Addr );
void Compile_SH_Register ( int x86Reg, DWORD Addr );
void Compile_SH_Register ( CX86Ops::x86Reg Reg, DWORD Addr );
void Compile_SW_Const ( DWORD Value, DWORD Addr );
void Compile_SW_Register ( CCodeSection * Section, int x86Reg, DWORD Addr );
void Compile_SW_Register ( CRegInfo & RegInfo, CX86Ops::x86Reg Reg, DWORD Addr );
//Functions for TLB notification
void TLB_Mapped ( DWORD VAddr, DWORD Len, DWORD PAddr, bool bReadOnly );
@ -244,4 +246,3 @@ private:
};
extern void ** JumpTable;
extern BYTE *RecompPos;

View File

@ -621,7 +621,7 @@ void CMipsMemoryVM::MemoryFilterFailed( char * FailureType, DWORD MipsAddress,
}
#endif
void CMipsMemoryVM::Compile_LB ( int Reg, DWORD VAddr, BOOL SignExtend) {
void CMipsMemoryVM::Compile_LB ( CX86Ops::x86Reg Reg, DWORD VAddr, BOOL SignExtend) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
DWORD PAddr;
@ -658,7 +658,7 @@ void CMipsMemoryVM::Compile_LB ( int Reg, DWORD VAddr, BOOL SignExtend) {
#endif
}
void CMipsMemoryVM::Compile_LH ( int Reg, DWORD VAddr, BOOL SignExtend) {
void CMipsMemoryVM::Compile_LH ( CX86Ops::x86Reg Reg, DWORD VAddr, BOOL SignExtend) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
char VarName[100];
@ -695,9 +695,7 @@ void CMipsMemoryVM::Compile_LH ( int Reg, DWORD VAddr, BOOL SignExtend) {
#endif
}
void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr ) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
void CMipsMemoryVM::Compile_LW (CCodeSection * Section, CX86Ops::x86Reg Reg, DWORD VAddr ) {
char VarName[100];
DWORD PAddr;
@ -727,10 +725,10 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
break;
}
switch (PAddr) {
case 0x04040010: MoveVariableToX86reg(&SP_STATUS_REG,"SP_STATUS_REG",Reg); break;
case 0x04040014: MoveVariableToX86reg(&SP_DMA_FULL_REG,"SP_DMA_FULL_REG",Reg); break;
case 0x04040018: MoveVariableToX86reg(&SP_DMA_BUSY_REG,"SP_DMA_BUSY_REG",Reg); break;
case 0x04080000: MoveVariableToX86reg(&SP_PC_REG,"SP_PC_REG",Reg); break;
case 0x04040010: MoveVariableToX86reg(&_Reg->SP_STATUS_REG,"SP_STATUS_REG",Reg); break;
case 0x04040014: MoveVariableToX86reg(&_Reg->SP_DMA_FULL_REG,"SP_DMA_FULL_REG",Reg); break;
case 0x04040018: MoveVariableToX86reg(&_Reg->SP_DMA_BUSY_REG,"SP_DMA_BUSY_REG",Reg); break;
case 0x04080000: MoveVariableToX86reg(&_Reg->SP_PC_REG,"SP_PC_REG",Reg); break;
default:
MoveConstToX86reg(0,Reg);
if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { DisplayError("Compile_LW\nFailed to translate address: %X",VAddr); }
@ -743,10 +741,10 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
break;
case 0x04300000:
switch (PAddr) {
case 0x04300000: MoveVariableToX86reg(&MI_MODE_REG,"MI_MODE_REG",Reg); break;
case 0x04300004: MoveVariableToX86reg(&MI_VERSION_REG,"MI_VERSION_REG",Reg); break;
case 0x04300008: MoveVariableToX86reg(&MI_INTR_REG,"MI_INTR_REG",Reg); break;
case 0x0430000C: MoveVariableToX86reg(&MI_INTR_MASK_REG,"MI_INTR_MASK_REG",Reg); break;
case 0x04300000: MoveVariableToX86reg(&_Reg->MI_MODE_REG,"MI_MODE_REG",Reg); break;
case 0x04300004: MoveVariableToX86reg(&_Reg->MI_VERSION_REG,"MI_VERSION_REG",Reg); break;
case 0x04300008: MoveVariableToX86reg(&_Reg->MI_INTR_REG,"MI_INTR_REG",Reg); break;
case 0x0430000C: MoveVariableToX86reg(&_Reg->MI_INTR_MASK_REG,"MI_INTR_MASK_REG",Reg); break;
default:
MoveConstToX86reg(0,Reg);
if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { DisplayError("Compile_LW\nFailed to translate address: %X",VAddr); }
@ -755,14 +753,17 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
case 0x04400000:
switch (PAddr) {
case 0x04400010:
_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE);
Section->BlockCycleCount() = 0;
Section->BlockRandomModifier() = 0;
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
Section->UpdateCounters(&RegInfo.BlockCycleCount(),&RegInfo.BlockRandomModifier(),FALSE);
RegInfo.BlockCycleCount() = 0;
RegInfo.BlockRandomModifier() = 0;
Pushad();
MoveConstToX86reg((DWORD)this,x86_ECX);
Call_Direct(AddressOf(CMipsMemoryVM::UpdateHalfLine),"CMipsMemoryVM::UpdateHalfLine");
Popad();
MoveVariableToX86reg(m_HalfLine,"m_HalfLine",Reg);
MoveVariableToX86reg(&m_HalfLine,"m_HalfLine",Reg);
#endif
break;
default:
MoveConstToX86reg(0,Reg);
@ -774,13 +775,16 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
case 0x04500004:
if (_Settings->LoadBool(Game_FixedAudio))
{
_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE);
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
CRecompilerOps::UpdateCounters(&RegInfo.BlockCycleCount(),&RegInfo.BlockRandomModifier(),FALSE);
Pushad();
MoveConstToX86reg((DWORD)_Audio,x86_ECX);
Call_Direct(CAudio::AiGetLength,"AiGetLength");
Call_Direct(AddressOf(CAudio::AiGetLength),"AiGetLength");
MoveX86regToVariable(x86_EAX,&m_TempValue,"m_TempValue");
Popad();
MoveVariableToX86reg(&m_TempValue,"m_TempValue",Reg);
#endif
} else {
if (AiReadLength != NULL) {
Pushad();
@ -798,12 +802,12 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
{
Pushad();
MoveConstToX86reg((DWORD)_Audio,x86_ECX);
Call_Direct(CAudio::AiGetStatus,"AiGetStatus");
Call_Direct(AddressOf(CAudio::AiGetStatus),"AiGetStatus");
MoveX86regToVariable(x86_EAX,&m_TempValue,"m_TempValue");
Popad();
MoveVariableToX86reg(&m_TempValue,"m_TempValue",Reg);
} else {
MoveVariableToX86reg(&AI_STATUS_REG,"AI_STATUS_REG",Reg);
MoveVariableToX86reg(&_Reg->AI_STATUS_REG,"AI_STATUS_REG",Reg);
}
break;
default:
@ -813,15 +817,15 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
break;
case 0x04600000:
switch (PAddr) {
case 0x04600010: MoveVariableToX86reg(&PI_STATUS_REG,"PI_STATUS_REG",Reg); break;
case 0x04600014: MoveVariableToX86reg(&PI_DOMAIN1_REG,"PI_DOMAIN1_REG",Reg); break;
case 0x04600018: MoveVariableToX86reg(&PI_BSD_DOM1_PWD_REG,"PI_BSD_DOM1_PWD_REG",Reg); break;
case 0x0460001C: MoveVariableToX86reg(&PI_BSD_DOM1_PGS_REG,"PI_BSD_DOM1_PGS_REG",Reg); break;
case 0x04600020: MoveVariableToX86reg(&PI_BSD_DOM1_RLS_REG,"PI_BSD_DOM1_RLS_REG",Reg); break;
case 0x04600024: MoveVariableToX86reg(&PI_DOMAIN2_REG,"PI_DOMAIN2_REG",Reg); break;
case 0x04600028: MoveVariableToX86reg(&PI_BSD_DOM2_PWD_REG,"PI_BSD_DOM2_PWD_REG",Reg); break;
case 0x0460002C: MoveVariableToX86reg(&PI_BSD_DOM2_PGS_REG,"PI_BSD_DOM2_PGS_REG",Reg); break;
case 0x04600030: MoveVariableToX86reg(&PI_BSD_DOM2_RLS_REG,"PI_BSD_DOM2_RLS_REG",Reg); break;
case 0x04600010: MoveVariableToX86reg(&_Reg->PI_STATUS_REG,"PI_STATUS_REG",Reg); break;
case 0x04600014: MoveVariableToX86reg(&_Reg->PI_DOMAIN1_REG,"PI_DOMAIN1_REG",Reg); break;
case 0x04600018: MoveVariableToX86reg(&_Reg->PI_BSD_DOM1_PWD_REG,"PI_BSD_DOM1_PWD_REG",Reg); break;
case 0x0460001C: MoveVariableToX86reg(&_Reg->PI_BSD_DOM1_PGS_REG,"PI_BSD_DOM1_PGS_REG",Reg); break;
case 0x04600020: MoveVariableToX86reg(&_Reg->PI_BSD_DOM1_RLS_REG,"PI_BSD_DOM1_RLS_REG",Reg); break;
case 0x04600024: MoveVariableToX86reg(&_Reg->PI_DOMAIN2_REG,"PI_DOMAIN2_REG",Reg); break;
case 0x04600028: MoveVariableToX86reg(&_Reg->PI_BSD_DOM2_PWD_REG,"PI_BSD_DOM2_PWD_REG",Reg); break;
case 0x0460002C: MoveVariableToX86reg(&_Reg->PI_BSD_DOM2_PGS_REG,"PI_BSD_DOM2_PGS_REG",Reg); break;
case 0x04600030: MoveVariableToX86reg(&_Reg->PI_BSD_DOM2_RLS_REG,"PI_BSD_DOM2_RLS_REG",Reg); break;
default:
MoveConstToX86reg(0,Reg);
if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { DisplayError("Compile_LW\nFailed to translate address: %X",VAddr); }
@ -829,8 +833,8 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
break;
case 0x04700000:
switch (PAddr) {
case 0x0470000C: MoveVariableToX86reg(&RI_SELECT_REG,"RI_SELECT_REG",Reg); break;
case 0x04700010: MoveVariableToX86reg(&RI_REFRESH_REG,"RI_REFRESH_REG",Reg); break;
case 0x0470000C: MoveVariableToX86reg(&_Reg->RI_SELECT_REG,"RI_SELECT_REG",Reg); break;
case 0x04700010: MoveVariableToX86reg(&_Reg->RI_REFRESH_REG,"RI_REFRESH_REG",Reg); break;
default:
MoveConstToX86reg(0,Reg);
if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { DisplayError("Compile_LW\nFailed to translate address: %X",VAddr); }
@ -838,7 +842,7 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
break;
case 0x04800000:
switch (PAddr) {
case 0x04800018: MoveVariableToX86reg(&SI_STATUS_REG,"SI_STATUS_REG",Reg); break;
case 0x04800018: MoveVariableToX86reg(&_Reg->SI_STATUS_REG,"SI_STATUS_REG",Reg); break;
default:
MoveConstToX86reg(0,Reg);
if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { DisplayError("Compile_LW\nFailed to translate address: %X",VAddr); }
@ -855,7 +859,6 @@ void CMipsMemoryVM::Compile_LW ( CCodeSection * Section, int Reg, DWORD VAddr )
DisplayError("Compile_LW\nFailed to translate address: %X",VAddr);
}
}
#endif
}
void CMipsMemoryVM::Compile_SB_Const ( BYTE Value, DWORD VAddr ) {
@ -888,7 +891,7 @@ void CMipsMemoryVM::Compile_SB_Const ( BYTE Value, DWORD VAddr ) {
#endif
}
void CMipsMemoryVM::Compile_SB_Register ( int x86Reg, DWORD VAddr ) {
void CMipsMemoryVM::Compile_SB_Register ( CX86Ops::x86Reg Reg, DWORD VAddr ) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
char VarName[100];
@ -948,7 +951,7 @@ void CMipsMemoryVM::Compile_SH_Const ( WORD Value, DWORD VAddr ) {
#endif
}
void CMipsMemoryVM::Compile_SH_Register ( int x86Reg, DWORD VAddr ) {
void CMipsMemoryVM::Compile_SH_Register ( CX86Ops::x86Reg Reg, DWORD VAddr ) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
char VarName[100];
@ -1320,7 +1323,7 @@ void CMipsMemoryVM::Compile_SW_Const ( DWORD Value, DWORD VAddr ) {
#endif
}
void CMipsMemoryVM::Compile_SW_Register ( CCodeSection * Section, int x86Reg, DWORD VAddr )
void CMipsMemoryVM::Compile_SW_Register (CRegInfo & RegInfo, CX86Ops::x86Reg Reg, DWORD VAddr )
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
@ -1590,7 +1593,7 @@ void CMipsMemoryVM::Compile_SW_Register ( CCodeSection * Section, int x86Reg, DW
#endif
}
void CMipsMemoryVM::ResetMemoryStack (CCodeSection * Section)
void CMipsMemoryVM::ResetMemoryStack (CRegInfo & RegInfo)
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix

View File

@ -1,6 +1,6 @@
#include "stdafx.h"
extern CLog TlbLog;
#ifdef tofix
COpcodeAnalysis::COpcodeAnalysis(OPCODE &opcode) :
m_opcode(opcode)
{
@ -1152,3 +1152,5 @@ void COpcodeAnalysis::OpcodeParam(char * CommandName)
}
#endif

View File

@ -1,3 +1,5 @@
#ifdef tofix
class COpcodeAnalysis
{
OPCODE &m_opcode;
@ -27,4 +29,6 @@ public:
//Stops execution
bool TerminateExecution ( void );
};
};
#endif

View File

@ -1,5 +1,6 @@
#include "stdafx.h"
#ifdef toremove
QWORD const COpcode::LDL_MASK[8] = { 0x0000000000000000,0x00000000000000FF,0x000000000000FFFF,
0x0000000000FFFFFF,0x00000000FFFFFFFF,0x000000FFFFFFFFFF,
0x0000FFFFFFFFFFFF,0x00FFFFFFFFFFFFFF };
@ -116,3 +117,4 @@ bool COpcode::SetPC ( DWORD VirtualAddress ) {
return Result;
}
#endif

View File

@ -1,3 +1,5 @@
#ifdef toremove
#ifndef __OPCODE_CLASS__H__
#define __OPCODE_CLASS__H__
@ -57,97 +59,6 @@ enum StepType
DoDelaySlot, InsideDelaySlot, DelaySlotDone, BranchCompiled
};
//enum R4300iOpCodes
//{
// R4300i_SPECIAL = 0, R4300i_REGIMM = 1, R4300i_J = 2, R4300i_JAL = 3,
// R4300i_BEQ = 4, R4300i_BNE = 5, R4300i_BLEZ = 6, R4300i_BGTZ = 7,
// R4300i_ADDI = 8, R4300i_ADDIU = 9, R4300i_SLTI = 10, R4300i_SLTIU = 11,
// R4300i_ANDI = 12, R4300i_ORI = 13, R4300i_XORI = 14, R4300i_LUI = 15,
// R4300i_CP0 = 16, R4300i_CP1 = 17, R4300i_BEQL = 20, R4300i_BNEL = 21,
// R4300i_BLEZL = 22, R4300i_BGTZL = 23, R4300i_DADDI = 24, R4300i_DADDIU = 25,
// R4300i_LDL = 26, R4300i_LDR = 27, R4300i_LB = 32, R4300i_LH = 33,
// R4300i_LWL = 34, R4300i_LW = 35, R4300i_LBU = 36, R4300i_LHU = 37,
// R4300i_LWR = 38, R4300i_LWU = 39, R4300i_SB = 40, R4300i_SH = 41,
// R4300i_SWL = 42, R4300i_SW = 43, R4300i_SDL = 44, R4300i_SDR = 45,
// R4300i_SWR = 46, R4300i_CACHE = 47, R4300i_LL = 48, R4300i_LWC1 = 49,
// R4300i_LDC1 = 53, R4300i_LD = 55, R4300i_SC = 56, R4300i_SWC1 = 57,
// R4300i_SDC1 = 61, R4300i_SDC2 = 62, R4300i_SD = 63
//};
//
//enum R4300iSpecialOpCodes
//{
// R4300i_SPECIAL_SLL = 0, R4300i_SPECIAL_SRL = 2, R4300i_SPECIAL_SRA = 3,
// R4300i_SPECIAL_SLLV = 4, R4300i_SPECIAL_SRLV = 6, R4300i_SPECIAL_SRAV = 7,
// R4300i_SPECIAL_JR = 8, R4300i_SPECIAL_JALR = 9, R4300i_SPECIAL_SYSCALL = 12,
// R4300i_SPECIAL_BREAK = 13, R4300i_SPECIAL_SYNC = 15, R4300i_SPECIAL_MFHI = 16,
// R4300i_SPECIAL_MTHI = 17, R4300i_SPECIAL_MFLO = 18, R4300i_SPECIAL_MTLO = 19,
// R4300i_SPECIAL_DSLLV = 20, R4300i_SPECIAL_DSRLV = 22, R4300i_SPECIAL_DSRAV = 23,
// R4300i_SPECIAL_MULT = 24, R4300i_SPECIAL_MULTU = 25, R4300i_SPECIAL_DIV = 26,
// R4300i_SPECIAL_DIVU = 27, R4300i_SPECIAL_DMULT = 28, R4300i_SPECIAL_DMULTU = 29,
// R4300i_SPECIAL_DDIV = 30, R4300i_SPECIAL_DDIVU = 31, R4300i_SPECIAL_ADD = 32,
// R4300i_SPECIAL_ADDU = 33, R4300i_SPECIAL_SUB = 34, R4300i_SPECIAL_SUBU = 35,
// R4300i_SPECIAL_AND = 36, R4300i_SPECIAL_OR = 37, R4300i_SPECIAL_XOR = 38,
// R4300i_SPECIAL_NOR = 39, R4300i_SPECIAL_SLT = 42, R4300i_SPECIAL_SLTU = 43,
// R4300i_SPECIAL_DADD = 44, R4300i_SPECIAL_DADDU = 45, R4300i_SPECIAL_DSUB = 46,
// R4300i_SPECIAL_DSUBU = 47, R4300i_SPECIAL_TGE = 48, R4300i_SPECIAL_TGEU = 49,
// R4300i_SPECIAL_TLT = 50, R4300i_SPECIAL_TLTU = 51, R4300i_SPECIAL_TEQ = 52,
// R4300i_SPECIAL_TNE = 54, R4300i_SPECIAL_DSLL = 56, R4300i_SPECIAL_DSRL = 58,
// R4300i_SPECIAL_DSRA = 59, R4300i_SPECIAL_DSLL32 = 60, R4300i_SPECIAL_DSRL32 = 62,
// R4300i_SPECIAL_DSRA32 = 63
//};
//
//enum R4300iRegImmOpCodes
//{
// R4300i_REGIMM_BLTZ = 0, R4300i_REGIMM_BGEZ = 1, R4300i_REGIMM_BLTZL = 2,
// R4300i_REGIMM_BGEZL = 3, R4300i_REGIMM_TGEI = 8, R4300i_REGIMM_TGEIU = 9,
// R4300i_REGIMM_TLTI = 10, R4300i_REGIMM_TLTIU = 11, R4300i_REGIMM_TEQI = 12,
// R4300i_REGIMM_TNEI = 14, R4300i_REGIMM_BLTZAL = 16, R4300i_REGIMM_BGEZAL = 17,
// R4300i_REGIMM_BLTZALL = 18, R4300i_REGIMM_BGEZALL = 19,
//};
//
//enum R4300iCOP0OpCodes
//{
// R4300i_COP0_MF = 0, R4300i_COP0_MT = 4
//};
//
//enum R4300iCOP0C0OpCodes
//{
// R4300i_COP0_CO_TLBR = 1, R4300i_COP0_CO_TLBWI = 2, R4300i_COP0_CO_TLBWR = 6,
// R4300i_COP0_CO_TLBP = 8, R4300i_COP0_CO_ERET = 24,
//};
//
//enum R4300iCOP1OpCodes
//{
// R4300i_COP1_MF = 0, R4300i_COP1_DMF = 1, R4300i_COP1_CF = 2, R4300i_COP1_MT = 4,
// R4300i_COP1_DMT = 5, R4300i_COP1_CT = 6, R4300i_COP1_BC = 8, R4300i_COP1_S = 16,
// R4300i_COP1_D = 17, R4300i_COP1_W = 20, R4300i_COP1_L = 21,
//};
//
//enum R4300iCOP1BcOpCodes
//{
// R4300i_COP1_BC_BCF = 0, R4300i_COP1_BC_BCT = 1, R4300i_COP1_BC_BCFL = 2,
// R4300i_COP1_BC_BCTL = 3,
//};
//
//enum R4300iCOP1FuntOpCodes
//{
// R4300i_COP1_FUNCT_ADD = 0, R4300i_COP1_FUNCT_SUB = 1, R4300i_COP1_FUNCT_MUL = 2,
// R4300i_COP1_FUNCT_DIV = 3, R4300i_COP1_FUNCT_SQRT = 4, R4300i_COP1_FUNCT_ABS = 5,
// R4300i_COP1_FUNCT_MOV = 6, R4300i_COP1_FUNCT_NEG = 7, R4300i_COP1_FUNCT_ROUND_L = 8,
// R4300i_COP1_FUNCT_TRUNC_L = 9, R4300i_COP1_FUNCT_CEIL_L = 10,R4300i_COP1_FUNCT_FLOOR_L = 11,
// R4300i_COP1_FUNCT_ROUND_W = 12,R4300i_COP1_FUNCT_TRUNC_W = 13,R4300i_COP1_FUNCT_CEIL_W = 14,
// R4300i_COP1_FUNCT_FLOOR_W = 15,R4300i_COP1_FUNCT_CVT_S = 32,R4300i_COP1_FUNCT_CVT_D = 33,
// R4300i_COP1_FUNCT_CVT_W = 36,R4300i_COP1_FUNCT_CVT_L = 37,R4300i_COP1_FUNCT_C_F = 48,
// R4300i_COP1_FUNCT_C_UN = 49,R4300i_COP1_FUNCT_C_EQ = 50,R4300i_COP1_FUNCT_C_UEQ = 51,
// R4300i_COP1_FUNCT_C_OLT = 52,R4300i_COP1_FUNCT_C_ULT = 53,R4300i_COP1_FUNCT_C_OLE = 54,
// R4300i_COP1_FUNCT_C_ULE = 55,R4300i_COP1_FUNCT_C_SF = 56,R4300i_COP1_FUNCT_C_NGLE = 57,
// R4300i_COP1_FUNCT_C_SEQ = 58,R4300i_COP1_FUNCT_C_NGL = 59,R4300i_COP1_FUNCT_C_LT = 60,
// R4300i_COP1_FUNCT_C_NGE = 61,R4300i_COP1_FUNCT_C_LE = 62,R4300i_COP1_FUNCT_C_NGT = 63,
//};
#define FPR_Type(Reg) (Reg) == R4300i_COP1_S ? "S" : (Reg) == R4300i_COP1_D ? "D" :\
(Reg) == R4300i_COP1_W ? "W" : "L"
enum { OpCode_Size = 4};
enum PERM_LOOP { PermLoop_None, PermLoop_Jump, PermLoop_Delay };
class CRecompilerOps;
@ -185,11 +96,8 @@ public:
bool m_FlagSet; //A Flag was set
bool m_ExectionJumped; //Was the last next moved to a new location from a jump
PERM_LOOP m_InPermLoop; //Jumped to same address with delay slot not effecting the operation
//Flags used in LWL/SWL/etc .. instructions
static QWORD const LDL_MASK[8], LDR_MASK[8], SDL_MASK[8], SDR_MASK[8];
static DWORD const LWL_MASK[4], LWR_MASK[4], SWL_MASK[4], SWR_MASK[4];
static int const WL_SHIFT[4], WR_SHIFT[4], DL_SHIFT[8], DR_SHIFT[8];
};
#endif
#endif

View File

@ -1,50 +1,45 @@
#ifndef __OPCODE__H__
#define __OPCODE__H__
#pragma once
typedef struct {
DWORD VirtualAddress;
union {
unsigned long Hex;
unsigned char Ascii[4];
struct {
unsigned offset : 16;
unsigned rt : 5;
unsigned rs : 5;
unsigned op : 6;
};
struct {
unsigned immediate : 16;
unsigned : 5;
unsigned base : 5;
unsigned : 6;
};
struct {
unsigned target : 26;
unsigned : 6;
};
struct {
unsigned funct : 6;
unsigned sa : 5;
unsigned rd : 5;
unsigned : 5;
unsigned : 5;
unsigned : 6;
};
struct {
unsigned : 6;
unsigned fd : 5;
unsigned fs : 5;
unsigned ft : 5;
unsigned fmt : 5;
unsigned : 6;
};
typedef union {
unsigned long Hex;
unsigned char Ascii[4];
struct {
unsigned offset : 16;
unsigned rt : 5;
unsigned rs : 5;
unsigned op : 6;
};
struct {
unsigned immediate : 16;
unsigned : 5;
unsigned base : 5;
unsigned : 6;
};
struct {
unsigned target : 26;
unsigned : 6;
};
struct {
unsigned funct : 6;
unsigned sa : 5;
unsigned rd : 5;
unsigned : 5;
unsigned : 5;
unsigned : 6;
};
struct {
unsigned : 6;
unsigned fd : 5;
unsigned fs : 5;
unsigned ft : 5;
unsigned fmt : 5;
unsigned : 6;
};
} OPCODE;
enum R4300iOpCodes
@ -134,5 +129,3 @@ enum R4300iCOP1FuntOpCodes
R4300i_COP1_FUNCT_C_SEQ = 58,R4300i_COP1_FUNCT_C_NGL = 59,R4300i_COP1_FUNCT_C_LT = 60,
R4300i_COP1_FUNCT_C_NGE = 61,R4300i_COP1_FUNCT_C_LE = 62,R4300i_COP1_FUNCT_C_NGT = 63,
};
#endif

View File

@ -0,0 +1,6 @@
class CTransVaddr
{
public:
virtual bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const = 0;
virtual bool ValidVaddr ( DWORD VAddr ) const = 0;
};

View File

@ -1787,7 +1787,10 @@ bool CN64System::WriteToProtectedMemory (DWORD Address, int length)
WriteTraceF(TraceDebug,"WriteToProtectedMemory Addres: %X Len: %d",Address,length);
if (m_Recomp)
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
return m_Recomp->ClearRecompCode_Phys(Address,length,CRecompiler::Remove_ProtectedMem);
#endif
}
return false;
}
@ -1802,7 +1805,10 @@ void CN64System::TLB_Unmaped ( DWORD VAddr, DWORD Len )
m_MMU_VM.TLB_Unmaped(VAddr,Len);
if (m_Recomp && m_Recomp->bSMM_TLB())
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
m_Recomp->ClearRecompCode_Virt(VAddr,Len,CRecompiler::Remove_TLB);
#endif
}
}

View File

@ -0,0 +1,29 @@
class CCodeBlock
{
public:
CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos);
bool Compile ( void );
inline DWORD VAddrEnter ( void ) const { return m_VAddrEnter; }
inline DWORD VAddrFirst ( void ) const { return m_VAddrFirst; }
inline DWORD VAddrLast ( void ) const { return m_VAddrLast; }
inline BYTE * CompiledLocation ( void ) const { return m_CompiledLocation; }
inline int NoOfSections ( void ) const { return m_NoOfSections; }
inline const CCodeSection & EnterSection ( void ) const { return m_EnterSection; }
inline void SetVAddrFirst ( DWORD VAddr ) { m_VAddrFirst = VAddr; }
inline void SetVAddrLast ( DWORD VAddr ) { m_VAddrLast = VAddr; }
EXIT_LIST m_ExitInfo;
private:
void AnalyseBlock ( void );
DWORD m_VAddrEnter;
DWORD m_VAddrFirst; // the address of the first opcode in the block
DWORD m_VAddrLast; // the address of the first opcode in the block
BYTE * m_CompiledLocation; // What address is this compiled at
int m_NoOfSections; // The number of sections this block uses
CCodeSection m_EnterSection;
};

View File

@ -0,0 +1,981 @@
#include "stdafx.h"
void InPermLoop ( void );
int DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 );
int DelaySlotEffectsJump (DWORD JumpPC) {
OPCODE Command;
if (!_MMU->LW_VAddr(JumpPC, Command.Hex)) { return TRUE; }
switch (Command.op) {
case R4300i_SPECIAL:
switch (Command.funct) {
case R4300i_SPECIAL_JR: return DelaySlotEffectsCompare(JumpPC,Command.rs,0);
case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(JumpPC,Command.rs,31);
}
break;
case R4300i_REGIMM:
switch (Command.rt) {
case R4300i_REGIMM_BLTZ:
case R4300i_REGIMM_BGEZ:
case R4300i_REGIMM_BLTZL:
case R4300i_REGIMM_BGEZL:
case R4300i_REGIMM_BLTZAL:
case R4300i_REGIMM_BGEZAL:
return DelaySlotEffectsCompare(JumpPC,Command.rs,0);
}
break;
case R4300i_JAL:
case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(JumpPC,31,0); break;
case R4300i_J: return FALSE;
case R4300i_BEQ:
case R4300i_BNE:
case R4300i_BLEZ:
case R4300i_BGTZ:
return DelaySlotEffectsCompare(JumpPC,Command.rs,Command.rt);
case R4300i_CP1:
switch (Command.fmt) {
case R4300i_COP1_BC:
switch (Command.ft) {
case R4300i_COP1_BC_BCF:
case R4300i_COP1_BC_BCT:
case R4300i_COP1_BC_BCFL:
case R4300i_COP1_BC_BCTL:
{
int EffectDelaySlot;
OPCODE NewCommand;
if (!_MMU->LW_VAddr(JumpPC + 4, NewCommand.Hex)) { return TRUE; }
EffectDelaySlot = FALSE;
if (NewCommand.op == R4300i_CP1) {
if (NewCommand.fmt == R4300i_COP1_S && (NewCommand.funct & 0x30) == 0x30 ) {
EffectDelaySlot = TRUE;
}
if (NewCommand.fmt == R4300i_COP1_D && (NewCommand.funct & 0x30) == 0x30 ) {
EffectDelaySlot = TRUE;
}
}
return EffectDelaySlot;
}
break;
}
break;
}
break;
case R4300i_BEQL:
case R4300i_BNEL:
case R4300i_BLEZL:
case R4300i_BGTZL:
return DelaySlotEffectsCompare(JumpPC,Command.rs,Command.rt);
}
return TRUE;
}
CCodeSection::CCodeSection( CCodeBlock * CodeBlock, DWORD EnterPC, DWORD ID) :
m_BlockInfo(CodeBlock),
m_EnterPC(EnterPC),
m_SectionID(ID),
m_ContinueSection(NULL),
m_JumpSection(NULL),
m_LinkAllowed(true),
m_CompiledLocation(NULL),
m_Test(0)
{
/*
Test2 = 0;
InLoop = false;
DelaySlotSection = false;
*/
if (&CodeBlock->EnterSection() == this)
{
m_LinkAllowed = false;
m_RegEnter.Initilize();
}
}
CCodeSection::~CCodeSection( void )
{
}
void CCodeSection::CompileExit ( DWORD JumpPC, DWORD TargetPC, CRegInfo ExitRegSet, CExitInfo::EXIT_REASON reason, int CompileNow, void (*x86Jmp)(char * Label, DWORD Value))
{
if (!CompileNow)
{
char String[100];
sprintf(String,"Exit_%d",m_BlockInfo->m_ExitInfo.size());
if (x86Jmp == NULL)
{
DisplayError("CompileExit error");
ExitThread(0);
}
x86Jmp(String,0);
CExitInfo ExitInfo;
ExitInfo.ID = m_BlockInfo->m_ExitInfo.size();
ExitInfo.TargetPC = TargetPC;
ExitInfo.ExitRegSet = ExitRegSet;
ExitInfo.reason = reason;
ExitInfo.NextInstruction = m_NextInstruction;
ExitInfo.JumpLoc = m_RecompPos - 4;
m_BlockInfo->m_ExitInfo.push_back(ExitInfo);
return;
}
//CPU_Message("CompileExit: %d",reason);
CCodeSection TempSection(m_BlockInfo,-1,0);
TempSection.m_RegWorkingSet = ExitRegSet;
if (TargetPC != (DWORD)-1)
{
MoveConstToVariable(TargetPC,&_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER");
UpdateCounters(ExitRegSet,false,TargetPC <= JumpPC && reason == CExitInfo::Normal);
} else {
UpdateCounters(ExitRegSet,false,reason == CExitInfo::Normal);
}
TempSection.m_RegWorkingSet.WriteBackRegisters();
switch (reason) {
case CExitInfo::Normal: case CExitInfo::Normal_NoSysCheck:
TempSection.m_RegWorkingSet.SetBlockCycleCount(0);
if (TargetPC != (DWORD)-1)
{
if (TargetPC <= JumpPC && reason == CExitInfo::Normal)
{
CompileSystemCheck((DWORD)-1,TempSection.m_RegWorkingSet);
}
} else {
if (reason == CExitInfo::Normal) { CompileSystemCheck((DWORD)-1,TempSection.m_RegWorkingSet); }
}
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
if (m_SyncSystem) { Call_Direct(SyncToPC, "SyncToPC"); }
#endif
#ifdef LinkBlocks
if (bSMM_ValidFunc == false)
{
if (LookUpMode() == FuncFind_ChangeMemory)
{
BreakPoint(__FILE__,__LINE__);
// BYTE * Jump, * Jump2;
// if (TargetPC >= 0x80000000 && TargetPC < 0xC0000000) {
// DWORD pAddr = TargetPC & 0x1FFFFFFF;
//
// MoveVariableToX86reg((BYTE *)RDRAM + pAddr,"RDRAM + pAddr",x86_EAX);
// Jump2 = NULL;
// } else {
// MoveConstToX86reg((TargetPC >> 12),x86_ECX);
// MoveConstToX86reg(TargetPC,x86_EBX);
// MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",x86_ECX,x86_ECX,4);
// TestX86RegToX86Reg(x86_ECX,x86_ECX);
// JeLabel8("NoTlbEntry",0);
// Jump2 = m_RecompPos - 1;
// MoveX86regPointerToX86reg(x86_ECX, x86_EBX,x86_EAX);
// }
// MoveX86RegToX86Reg(x86_EAX,x86_ECX);
// AndConstToX86Reg(x86_ECX,0xFFFF0000);
// CompConstToX86reg(x86_ECX,0x7C7C0000);
// JneLabel8("NoCode",0);
// Jump = m_RecompPos - 1;
// AndConstToX86Reg(x86_EAX,0xFFFF);
// ShiftLeftSignImmed(x86_EAX,4);
// AddConstToX86Reg(x86_EAX,0xC);
// MoveVariableDispToX86Reg(OrigMem,"OrigMem",x86_ECX,x86_EAX,1);
// JmpDirectReg(x86_ECX);
// CPU_Message(" NoCode:");
// *((BYTE *)(Jump))=(BYTE)(m_RecompPos - Jump - 1);
// if (Jump2 != NULL) {
// CPU_Message(" NoTlbEntry:");
// *((BYTE *)(Jump2))=(BYTE)(m_RecompPos - Jump2 - 1);
// }
}
else if (LookUpMode() == FuncFind_VirtualLookup)
{
MoveConstToX86reg(TargetPC,x86_EDX);
MoveConstToX86reg((DWORD)&m_Functions,x86_ECX);
Call_Direct(AddressOf(CFunctionMap::CompilerFindFunction), "CFunctionMap::CompilerFindFunction");
MoveX86RegToX86Reg(x86_EAX,x86_ECX);
JecxzLabel8("NullPointer",0);
BYTE * Jump = m_RecompPos - 1;
MoveX86PointerToX86regDisp(x86_EBX,x86_ECX,0xC);
JmpDirectReg(x86_EBX);
CPU_Message(" NullPointer:");
*((BYTE *)(Jump))=(BYTE)(m_RecompPos - Jump - 1);
}
else if (LookUpMode() == FuncFind_PhysicalLookup)
{
BYTE * Jump2 = NULL;
if (TargetPC >= 0x80000000 && TargetPC < 0x90000000) {
DWORD pAddr = TargetPC & 0x1FFFFFFF;
MoveVariableToX86reg((BYTE *)JumpTable + pAddr,"JumpTable + pAddr",x86_ECX);
} else if (TargetPC >= 0x90000000 && TargetPC < 0xC0000000) {
} else {
MoveConstToX86reg((TargetPC >> 12),x86_ECX);
MoveConstToX86reg(TargetPC,x86_EBX);
MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",x86_ECX,x86_ECX,4);
TestX86RegToX86Reg(x86_ECX,x86_ECX);
JeLabel8("NoTlbEntry",0);
Jump2 = m_RecompPos - 1;
AddConstToX86Reg(x86_ECX,(DWORD)JumpTable - (DWORD)RDRAM);
MoveX86regPointerToX86reg(x86_ECX, x86_EBX,x86_ECX);
}
if (TargetPC < 0x90000000 || TargetPC >= 0xC0000000)
{
JecxzLabel8("NullPointer",0);
BYTE * Jump = m_RecompPos - 1;
MoveX86PointerToX86regDisp(x86_EAX,x86_ECX,0xC);
JmpDirectReg(x86_EAX);
CPU_Message(" NullPointer:");
*((BYTE *)(Jump))=(BYTE)(m_RecompPos - Jump - 1);
if (Jump2 != NULL) {
CPU_Message(" NoTlbEntry:");
*((BYTE *)(Jump2))=(BYTE)(m_RecompPos - Jump2 - 1);
}
}
}
}
Ret();
#else
Ret();
#endif
break;
case CExitInfo::DoCPU_Action:
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
Call_Direct(DoSomething,"DoSomething");
if (m_SyncSystem) { Call_Direct(SyncToPC, "SyncToPC"); }
#endif
Ret();
break;
case CExitInfo::DoSysCall:
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
MoveConstToX86reg(NextInstruction == JUMP || NextInstruction == DELAY_SLOT,x86_ECX);
Call_Direct(DoSysCallException,"DoSysCallException");
if (m_SyncSystem) { Call_Direct(SyncToPC, "SyncToPC"); }
Ret();
#endif
break;
case CExitInfo::COP1_Unuseable:
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
MoveConstToX86reg(NextInstruction == JUMP || NextInstruction == DELAY_SLOT,x86_ECX);
MoveConstToX86reg(1,x86_EDX);
Call_Direct(DoCopUnusableException,"DoCopUnusableException");
if (m_SyncSystem) { Call_Direct(SyncToPC, "SyncToPC"); }
Ret();
#endif
break;
case CExitInfo::ExitResetRecompCode:
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
if (NextInstruction == JUMP || NextInstruction == DELAY_SLOT) {
X86BreakPoint(__FILE__,__LINE__);
}
if (m_SyncSystem) { Call_Direct(SyncToPC, "SyncToPC"); }
X86BreakPoint(__FILE__,__LINE__);
MoveVariableToX86reg(this,"this",x86_ECX);
Call_Direct(AddressOf(ResetRecompCode), "ResetRecompCode");
#endif
Ret();
break;
case CExitInfo::TLBReadMiss:
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
MoveConstToX86reg(NextInstruction == JUMP || NextInstruction == DELAY_SLOT,x86_ECX);
MoveVariableToX86reg(&TLBLoadAddress,"TLBLoadAddress",x86_EDX);
Call_Direct(DoTLBMiss,"DoTLBMiss");
if (m_SyncSystem) { Call_Direct(SyncToPC, "SyncToPC"); }
Ret();
#endif
break;
default:
DisplayError("how did you want to exit on reason (%d) ???",reason);
}
}
void CCodeSection::CompileSystemCheck (DWORD TargetPC, const CRegInfo & RegSet)
{
CompConstToVariable(0,&g_CPU_Action->DoSomething,"g_CPU_Action.DoSomething");
JeLabel32("Continue_From_Interrupt_Test",0);
DWORD * Jump = (DWORD *)(m_RecompPos - 4);
if (TargetPC != (DWORD)-1)
{
MoveConstToVariable(TargetPC,&_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER");
}
CCodeSection Section(NULL,-1,0);
Section.m_RegWorkingSet = RegSet;
Section.m_RegWorkingSet.WriteBackRegisters();
CompileExit(-1, -1,Section.m_RegWorkingSet,CExitInfo::DoCPU_Action,true,NULL);
CPU_Message("");
CPU_Message(" $Continue_From_Interrupt_Test:");
SetJump32(Jump,(DWORD *)m_RecompPos);
}
void CCodeSection::GenerateSectionLinkage (void)
{
CCodeSection * TargetSection[] = { m_ContinueSection, m_JumpSection };
CJumpInfo * JumpInfo[] = { &m_Cont, &m_Jump };
BYTE * Jump;
int count;
for (count = 0; count < 2; count ++)
{
if (JumpInfo[count]->LinkLocation == NULL &&
JumpInfo[count]->FallThrough == false)
{
JumpInfo[count]->TargetPC = -1;
}
}
if ((CRecompilerOps::CompilePC() & 0xFFC) == 0xFFC) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
//Handle Fall througth
Jump = NULL;
for (count = 0; count < 2; count ++) {
if (!JumpInfo[count]->FallThrough) { continue; }
JumpInfo[count]->FallThrough = false;
if (JumpInfo[count]->LinkLocation != NULL) {
SetJump32(JumpInfo[count]->LinkLocation,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation = NULL;
if (JumpInfo[count]->LinkLocation2 != NULL) {
SetJump32(JumpInfo[count]->LinkLocation2,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation2 = NULL;
}
}
MoveConstToVariable(JumpInfo[count]->TargetPC,&JumpToLocation,"JumpToLocation");
if (JumpInfo[(count + 1) & 1]->LinkLocation == NULL) { break; }
JmpLabel8("FinishBlock",0);
Jump = m_RecompPos - 1;
}
for (count = 0; count < 2; count ++) {
if (JumpInfo[count]->LinkLocation == NULL) { continue; }
JumpInfo[count]->FallThrough = false;
if (JumpInfo[count]->LinkLocation != NULL) {
SetJump32(JumpInfo[count]->LinkLocation,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation = NULL;
if (JumpInfo[count]->LinkLocation2 != NULL) {
SetJump32(JumpInfo[count]->LinkLocation2,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation2 = NULL;
}
}
MoveConstToVariable(JumpInfo[count]->TargetPC,&JumpToLocation,"JumpToLocation");
if (JumpInfo[(count + 1) & 1]->LinkLocation == NULL) { break; }
JmpLabel8("FinishBlock",0);
Jump = m_RecompPos - 1;
}
if (Jump != NULL) {
CPU_Message(" $FinishBlock:");
SetJump8(Jump,m_RecompPos);
}
MoveConstToVariable(CRecompilerOps::CompilePC() + 4,_PROGRAM_COUNTER,"PROGRAM_COUNTER");
m_RegWorkingSet.WriteBackRegisters();
m_RegWorkingSet.UpdateCounters(&BlockCycleCount(),&BlockRandomModifier(),false);
// WriteBackRegisters(Section);
// if (m_SyncSystem) { Call_Direct(SyncToPC, "SyncToPC"); }
MoveConstToVariable(DELAY_SLOT,&NextInstruction,"NextInstruction");
Ret();
#endif
return;
}
if (!g_UseLinking) {
if (CRecompilerOps::m_CompilePC == m_Jump.TargetPC && (m_Cont.FallThrough == false)) {
if (!DelaySlotEffectsJump(CRecompilerOps::CompilePC())) {
CPU_Message("PermLoop *** a");
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
MoveConstToVariable(CRecompilerOps::CompilePC(),_PROGRAM_COUNTER,"PROGRAM_COUNTER");
m_RegWorkingSet.WriteBackRegisters();
m_RegWorkingSet.BlockCycleCount() -= g_CountPerOp;
UpdateCounters(&m_RegWorkingSet.BlockCycleCount(),&m_RegWorkingSet.BlockRandomModifier(), false);
Call_Direct(InPermLoop,"InPermLoop");
m_RegWorkingSet.BlockCycleCount() += g_CountPerOp;
UpdateCounters(&m_RegWorkingSet.BlockCycleCount(),&m_RegWorkingSet.BlockRandomModifier(), true);
CompileSystemCheck(-1,m_RegWorkingSet);
#endif
}
}
}
if (TargetSection[0] != TargetSection[1] || TargetSection[0] == NULL) {
for (count = 0; count < 2; count ++) {
if (JumpInfo[count]->LinkLocation == NULL && JumpInfo[count]->FallThrough == false) {
if (TargetSection[count])
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
TargetSection[count]->UnlinkParent(Section,true, count == 0);
#endif
}
} else if (TargetSection[count] == NULL && JumpInfo[count]->FallThrough) {
if (JumpInfo[count]->LinkLocation != NULL) {
SetJump32(JumpInfo[count]->LinkLocation,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation = NULL;
if (JumpInfo[count]->LinkLocation2 != NULL) {
SetJump32(JumpInfo[count]->LinkLocation2,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation2 = NULL;
}
}
CompileExit (CRecompilerOps::CompilePC(), JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL);
JumpInfo[count]->FallThrough = false;
} else if (TargetSection[count] != NULL && JumpInfo[count] != NULL) {
if (!JumpInfo[count]->FallThrough) { continue; }
if (JumpInfo[count]->TargetPC == TargetSection[count]->m_EnterPC) { continue; }
if (JumpInfo[count]->LinkLocation != NULL) {
SetJump32(JumpInfo[count]->LinkLocation,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation = NULL;
if (JumpInfo[count]->LinkLocation2 != NULL) {
SetJump32(JumpInfo[count]->LinkLocation2,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation2 = NULL;
}
}
CompileExit (CRecompilerOps::CompilePC(), JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL);
//FreeSection(TargetSection[count],Section);
}
}
} else {
if (m_Cont.LinkLocation == NULL && m_Cont.FallThrough == false) { m_ContinueSection = NULL; }
if (m_Jump.LinkLocation == NULL && m_Jump.FallThrough == false) { m_JumpSection = NULL; }
if (m_JumpSection == NULL && m_ContinueSection == NULL) {
//FreeSection(TargetSection[0],Section);
}
}
TargetSection[0] = m_ContinueSection;
TargetSection[1] = m_JumpSection;
for (count = 0; count < 2; count ++) {
if (TargetSection[count] == NULL) { continue; }
if (!JumpInfo[count]->FallThrough) { continue; }
if (TargetSection[count]->m_CompiledLocation != NULL) {
char Label[100];
sprintf(Label,"Section_%d",TargetSection[count]->m_SectionID);
JumpInfo[count]->FallThrough = false;
if (JumpInfo[count]->LinkLocation != NULL) {
SetJump32(JumpInfo[count]->LinkLocation,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation = NULL;
if (JumpInfo[count]->LinkLocation2 != NULL) {
SetJump32(JumpInfo[count]->LinkLocation2,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation2 = NULL;
}
}
if (JumpInfo[count]->TargetPC <= CRecompilerOps::CompilePC()) {
if (JumpInfo[count]->PermLoop) {
CPU_Message("PermLoop *** 1");
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
MoveConstToVariable(JumpInfo[count]->TargetPC,_PROGRAM_COUNTER,"PROGRAM_COUNTER");
JumpInfo[count]->RegSet.BlockCycleCount() -= g_CountPerOp;
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), false);
Call_Direct(InPermLoop,"InPermLoop");
JumpInfo[count]->RegSet.BlockCycleCount() += g_CountPerOp;
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), true);
CompileSystemCheck(-1,JumpInfo[count]->RegSet);
#endif
} else {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(), &JumpInfo[count]->RegSet.BlockRandomModifier(), true);
CompileSystemCheck(JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet);
#endif
}
} else {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(), &JumpInfo[count]->RegSet.BlockRandomModifier(), false);
#endif
}
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
JumpInfo[count]->RegSet.BlockCycleCount() = 0;
m_RegWorkingSet = JumpInfo[count]->RegSet;
SyncRegState(Section,&TargetSection[count]->RegStart);
#endif
JmpLabel32(Label,0);
SetJump32((DWORD *)m_RecompPos - 1,(DWORD *)(TargetSection[count]->m_CompiledLocation));
}
}
//BlockCycleCount() = 0;
//BlockRandomModifier() = 0;
for (count = 0; count < 2; count ++) {
if (TargetSection[count] == NULL) { continue; }
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
if (TargetSection[count]->ParentSection.empty()) { continue; }
for (SECTION_LIST::iterator iter = TargetSection[count]->ParentSection.begin(); iter != TargetSection[count]->ParentSection.end(); iter++)
{
CCodeSection * Parent = *iter;
if (Parent->CompiledLocation != NULL) { continue; }
if (JumpInfo[count]->PermLoop) {
CPU_Message("PermLoop *** 2");
MoveConstToVariable(JumpInfo[count]->TargetPC,_PROGRAM_COUNTER,"PROGRAM_COUNTER");
JumpInfo[count]->RegSet.BlockCycleCount() -= g_CountPerOp;
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), false);
Call_Direct(InPermLoop,"InPermLoop");
JumpInfo[count]->RegSet.BlockCycleCount() += g_CountPerOp;
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), true);
CompileSystemCheck(-1,JumpInfo[count]->RegSet);
}
if (JumpInfo[count]->FallThrough) {
JumpInfo[count]->FallThrough = false;
JmpLabel32(JumpInfo[count]->BranchLabel,0);
JumpInfo[count]->LinkLocation = m_RecompPos - 4;
}
}
#endif
}
for (count = 0; count < 2; count ++) {
if (JumpInfo[count]->FallThrough) {
if (JumpInfo[count]->TargetPC < CRecompilerOps::CompilePC()) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(),true);
#endif
CompileSystemCheck(JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet);
}
}
}
CPU_Message("====== End of Section %d ======",m_SectionID);
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
for (count = 0; count < 2; count ++) {
if (JumpInfo[count]->FallThrough) {
GenerateX86Code(*(m_BlockInfo),TargetSection[count],m_BlockInfo->m_Test + 1);
}
}
#endif
//CPU_Message("Section %d",m_SectionID);
for (count = 0; count < 2; count ++) {
if (JumpInfo[count]->LinkLocation == NULL) { continue; }
if (TargetSection[count] == NULL) {
CPU_Message("ExitBlock (from %d):",m_SectionID);
SetJump32(JumpInfo[count]->LinkLocation,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation = NULL;
if (JumpInfo[count]->LinkLocation2 != NULL) {
SetJump32(JumpInfo[count]->LinkLocation2,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation2 = NULL;
}
CompileExit (CRecompilerOps::CompilePC(),JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL);
continue;
}
if (JumpInfo[count]->TargetPC != TargetSection[count]->m_EnterPC) {
DisplayError("I need to add more code in GenerateSectionLinkage cause this is going to cause an exception");
BreakPoint(__FILE__,__LINE__);
}
if (TargetSection[count]->m_CompiledLocation == NULL) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
GenerateX86Code(*TargetSection[count]->m_BlockInfo,TargetSection[count],m_BlockInfo->m_Test + 1);
#endif
} else {
char Label[100];
CPU_Message("Section_%d (from %d):",TargetSection[count]->m_SectionID,m_SectionID);
SetJump32(JumpInfo[count]->LinkLocation,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation = NULL;
if (JumpInfo[count]->LinkLocation2 != NULL) {
SetJump32(JumpInfo[count]->LinkLocation2,(DWORD *)m_RecompPos);
JumpInfo[count]->LinkLocation2 = NULL;
}
m_RegWorkingSet = JumpInfo[count]->RegSet;
if (JumpInfo[count]->TargetPC <= CRecompilerOps::CompilePC()) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), true);
#endif
if (JumpInfo[count]->PermLoop) {
CPU_Message("PermLoop *** 3");
MoveConstToVariable(JumpInfo[count]->TargetPC,_PROGRAM_COUNTER,"PROGRAM_COUNTER");
Call_Direct(InPermLoop,"InPermLoop");
CompileSystemCheck(-1,JumpInfo[count]->RegSet);
} else {
CompileSystemCheck(JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet);
}
} else{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), false);
#endif
}
m_RegWorkingSet = JumpInfo[count]->RegSet;
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
SyncRegState(Section,&TargetSection[count]->RegStart);
#endif
JmpLabel32(Label,0);
SetJump32((DWORD *)m_RecompPos - 1,(DWORD *)(TargetSection[count]->m_CompiledLocation));
}
}
}
bool CCodeSection::GenerateX86Code ( DWORD Test )
{
if (this == NULL) { return false; }
if (m_CompiledLocation != NULL) {
if (m_Test == Test)
{
return false;
}
m_Test = Test;
if (m_ContinueSection->GenerateX86Code(Test)) { return true; }
if (m_JumpSection->GenerateX86Code(Test)) { return true; }
return false;
}
#ifdef tofix
if (ParentSection.size() > 0)
{
for (SECTION_LIST::iterator iter = ParentSection.begin(); iter != ParentSection.end(); iter++)
{
CBlockSection * Parent = *iter;
if (Parent->CompiledLocation != NULL) { continue; }
if (IsAllParentLoops(Parent,true,CBlockSection::GetNewTestValue())) { continue; }
return false;
}
}
if (!InheritParentInfo(Section)) { return false; }
#endif
m_RegWorkingSet = m_RegEnter;
m_CompiledLocation = m_RecompPos;
m_CompilePC = m_EnterPC;
m_NextInstruction = NORMAL;
m_RegWorkingSet = m_RegEnter;
m_Section = this;
if (m_CompilePC < m_BlockInfo->VAddrFirst())
{
m_BlockInfo->SetVAddrFirst(m_CompilePC);
}
do {
__try {
if (!_MMU->LW_VAddr(m_CompilePC,m_Opcode.Hex))
{
DisplayError(GS(MSG_FAIL_LOAD_WORD));
ExitThread(0);
}
} __except( _MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) ) {
DisplayError(GS(MSG_UNKNOWN_MEM_ACTION));
ExitThread(0);
}
if (m_CompilePC > m_BlockInfo->VAddrLast())
{
m_BlockInfo->SetVAddrLast(m_CompilePC);
}
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_CountPerOp);
m_RegWorkingSet.ResetX86Protection();
switch (m_Opcode.op) {
case R4300i_SPECIAL:
switch (m_Opcode.funct) {
case R4300i_SPECIAL_SLL: SPECIAL_SLL(); break;
case R4300i_SPECIAL_SRL: SPECIAL_SRL(); break;
case R4300i_SPECIAL_SRA: SPECIAL_SRA(); break;
case R4300i_SPECIAL_SLLV: SPECIAL_SLLV(); break;
case R4300i_SPECIAL_SRLV: SPECIAL_SRLV(); break;
case R4300i_SPECIAL_SRAV: SPECIAL_SRAV(); break;
case R4300i_SPECIAL_JR: SPECIAL_JR(); break;
case R4300i_SPECIAL_JALR: SPECIAL_JALR(); break;
case R4300i_SPECIAL_MFLO: SPECIAL_MFLO(); break;
case R4300i_SPECIAL_SYSCALL: SPECIAL_SYSCALL(); break;
case R4300i_SPECIAL_MTLO: SPECIAL_MTLO(); break;
case R4300i_SPECIAL_MFHI: SPECIAL_MFHI(); break;
case R4300i_SPECIAL_MTHI: SPECIAL_MTHI(); break;
case R4300i_SPECIAL_DSLLV: SPECIAL_DSLLV(); break;
case R4300i_SPECIAL_DSRLV: SPECIAL_DSRLV(); break;
case R4300i_SPECIAL_DSRAV: SPECIAL_DSRAV(); break;
case R4300i_SPECIAL_MULT: SPECIAL_MULT(); break;
case R4300i_SPECIAL_DIV: SPECIAL_DIV(); break;
case R4300i_SPECIAL_DIVU: SPECIAL_DIVU(); break;
case R4300i_SPECIAL_MULTU: SPECIAL_MULTU(); break;
case R4300i_SPECIAL_DMULT: SPECIAL_DMULT(); break;
case R4300i_SPECIAL_DMULTU: SPECIAL_DMULTU(); break;
case R4300i_SPECIAL_DDIV: SPECIAL_DDIV(); break;
case R4300i_SPECIAL_DDIVU: SPECIAL_DDIVU(); break;
case R4300i_SPECIAL_ADD: SPECIAL_ADD(); break;
case R4300i_SPECIAL_ADDU: SPECIAL_ADDU(); break;
case R4300i_SPECIAL_SUB: SPECIAL_SUB(); break;
case R4300i_SPECIAL_SUBU: SPECIAL_SUBU(); break;
case R4300i_SPECIAL_AND: SPECIAL_AND(); break;
case R4300i_SPECIAL_OR: SPECIAL_OR(); break;
case R4300i_SPECIAL_XOR: SPECIAL_XOR(); break;
case R4300i_SPECIAL_NOR: SPECIAL_NOR(); break;
case R4300i_SPECIAL_SLT: SPECIAL_SLT(); break;
case R4300i_SPECIAL_SLTU: SPECIAL_SLTU(); break;
case R4300i_SPECIAL_DADD: SPECIAL_DADD(); break;
case R4300i_SPECIAL_DADDU: SPECIAL_DADDU(); break;
case R4300i_SPECIAL_DSUB: SPECIAL_DSUB(); break;
case R4300i_SPECIAL_DSUBU: SPECIAL_DSUBU(); break;
case R4300i_SPECIAL_DSLL: SPECIAL_DSLL(); break;
case R4300i_SPECIAL_DSRL: SPECIAL_DSRL(); break;
case R4300i_SPECIAL_DSRA: SPECIAL_DSRA(); break;
case R4300i_SPECIAL_DSLL32: SPECIAL_DSLL32(); break;
case R4300i_SPECIAL_DSRL32: SPECIAL_DSRL32(); break;
case R4300i_SPECIAL_DSRA32: SPECIAL_DSRA32(); break;
default:
UnknownOpcode(); break;
}
break;
case R4300i_REGIMM:
switch (m_Opcode.rt) {
case R4300i_REGIMM_BLTZ:Compile_Branch(BLTZ_Compare,BranchTypeRs, false); break;
case R4300i_REGIMM_BGEZ:Compile_Branch(BGEZ_Compare,BranchTypeRs, false); break;
case R4300i_REGIMM_BLTZL:Compile_BranchLikely(BLTZ_Compare, false); break;
case R4300i_REGIMM_BGEZL:Compile_BranchLikely(BGEZ_Compare, false); break;
case R4300i_REGIMM_BLTZAL:Compile_Branch(BLTZ_Compare,BranchTypeRs, true); break;
case R4300i_REGIMM_BGEZAL:Compile_Branch(BGEZ_Compare,BranchTypeRs, true); break;
default:
UnknownOpcode(); break;
}
break;
case R4300i_BEQ: Compile_Branch(BEQ_Compare,BranchTypeRsRt,false); break;
case R4300i_BNE: Compile_Branch(BNE_Compare,BranchTypeRsRt,false); break;
case R4300i_BGTZ:Compile_Branch(BGTZ_Compare,BranchTypeRs,false); break;
case R4300i_BLEZ:Compile_Branch(BLEZ_Compare,BranchTypeRs,false); break;
case R4300i_J: J(); break;
case R4300i_JAL: JAL(); break;
case R4300i_ADDI: ADDI(); break;
case R4300i_ADDIU: ADDIU(); break;
case R4300i_SLTI: SLTI(); break;
case R4300i_SLTIU: SLTIU(); break;
case R4300i_ANDI: ANDI(); break;
case R4300i_ORI: ORI(); break;
case R4300i_XORI: XORI(); break;
case R4300i_LUI: LUI(); break;
case R4300i_CP0:
switch (m_Opcode.rs) {
case R4300i_COP0_MF: COP0_MF(); break;
case R4300i_COP0_MT: COP0_MT(); break;
default:
if ( (m_Opcode.rs & 0x10 ) != 0 ) {
switch( m_Opcode.funct ) {
case R4300i_COP0_CO_TLBR: COP0_CO_TLBR(); break;
case R4300i_COP0_CO_TLBWI: COP0_CO_TLBWI(); break;
case R4300i_COP0_CO_TLBWR: COP0_CO_TLBWR(); break;
case R4300i_COP0_CO_TLBP: COP0_CO_TLBP(); break;
case R4300i_COP0_CO_ERET: COP0_CO_ERET(); break;
default: UnknownOpcode(); break;
}
} else {
UnknownOpcode();
}
}
break;
case R4300i_CP1:
switch (m_Opcode.rs) {
case R4300i_COP1_MF: COP1_MF(); break;
case R4300i_COP1_DMF: COP1_DMF(); break;
case R4300i_COP1_CF: COP1_CF(); break;
case R4300i_COP1_MT: COP1_MT(); break;
case R4300i_COP1_DMT: COP1_DMT(); break;
case R4300i_COP1_CT: COP1_CT(); break;
case R4300i_COP1_BC:
switch (m_Opcode.ft) {
case R4300i_COP1_BC_BCF: Compile_Branch(COP1_BCF_Compare,BranchTypeCop1,false); break;
case R4300i_COP1_BC_BCT: Compile_Branch(COP1_BCT_Compare,BranchTypeCop1,false); break;
case R4300i_COP1_BC_BCFL: Compile_BranchLikely(COP1_BCF_Compare,false); break;
case R4300i_COP1_BC_BCTL: Compile_BranchLikely(COP1_BCT_Compare,false); break;
default:
UnknownOpcode(); break;
}
break;
case R4300i_COP1_S:
switch (m_Opcode.funct) {
case R4300i_COP1_FUNCT_ADD: COP1_S_ADD(); break;
case R4300i_COP1_FUNCT_SUB: COP1_S_SUB(); break;
case R4300i_COP1_FUNCT_MUL: COP1_S_MUL(); break;
case R4300i_COP1_FUNCT_DIV: COP1_S_DIV(); break;
case R4300i_COP1_FUNCT_ABS: COP1_S_ABS(); break;
case R4300i_COP1_FUNCT_NEG: COP1_S_NEG(); break;
case R4300i_COP1_FUNCT_SQRT: COP1_S_SQRT(); break;
case R4300i_COP1_FUNCT_MOV: COP1_S_MOV(); break;
case R4300i_COP1_FUNCT_TRUNC_L: COP1_S_TRUNC_L(); break;
case R4300i_COP1_FUNCT_CEIL_L: COP1_S_CEIL_L(); break; //added by Witten
case R4300i_COP1_FUNCT_FLOOR_L: COP1_S_FLOOR_L(); break; //added by Witten
case R4300i_COP1_FUNCT_ROUND_W: COP1_S_ROUND_W(); break;
case R4300i_COP1_FUNCT_TRUNC_W: COP1_S_TRUNC_W(); break;
case R4300i_COP1_FUNCT_CEIL_W: COP1_S_CEIL_W(); break; //added by Witten
case R4300i_COP1_FUNCT_FLOOR_W: COP1_S_FLOOR_W(); break;
case R4300i_COP1_FUNCT_CVT_D: COP1_S_CVT_D(); break;
case R4300i_COP1_FUNCT_CVT_W: COP1_S_CVT_W(); break;
case R4300i_COP1_FUNCT_CVT_L: COP1_S_CVT_L(); break;
case R4300i_COP1_FUNCT_C_F: case R4300i_COP1_FUNCT_C_UN:
case R4300i_COP1_FUNCT_C_EQ: case R4300i_COP1_FUNCT_C_UEQ:
case R4300i_COP1_FUNCT_C_OLT: case R4300i_COP1_FUNCT_C_ULT:
case R4300i_COP1_FUNCT_C_OLE: case R4300i_COP1_FUNCT_C_ULE:
case R4300i_COP1_FUNCT_C_SF: case R4300i_COP1_FUNCT_C_NGLE:
case R4300i_COP1_FUNCT_C_SEQ: case R4300i_COP1_FUNCT_C_NGL:
case R4300i_COP1_FUNCT_C_LT: case R4300i_COP1_FUNCT_C_NGE:
case R4300i_COP1_FUNCT_C_LE: case R4300i_COP1_FUNCT_C_NGT:
COP1_S_CMP(); break;
default:
UnknownOpcode(); break;
}
break;
case R4300i_COP1_D:
switch (m_Opcode.funct) {
case R4300i_COP1_FUNCT_ADD: COP1_D_ADD(); break;
case R4300i_COP1_FUNCT_SUB: COP1_D_SUB(); break;
case R4300i_COP1_FUNCT_MUL: COP1_D_MUL(); break;
case R4300i_COP1_FUNCT_DIV: COP1_D_DIV(); break;
case R4300i_COP1_FUNCT_ABS: COP1_D_ABS(); break;
case R4300i_COP1_FUNCT_NEG: COP1_D_NEG(); break;
case R4300i_COP1_FUNCT_SQRT: COP1_D_SQRT(); break;
case R4300i_COP1_FUNCT_MOV: COP1_D_MOV(); break;
case R4300i_COP1_FUNCT_TRUNC_L: COP1_D_TRUNC_L(); break; //added by Witten
case R4300i_COP1_FUNCT_CEIL_L: COP1_D_CEIL_L(); break; //added by Witten
case R4300i_COP1_FUNCT_FLOOR_L: COP1_D_FLOOR_L(); break; //added by Witten
case R4300i_COP1_FUNCT_ROUND_W: COP1_D_ROUND_W(); break;
case R4300i_COP1_FUNCT_TRUNC_W: COP1_D_TRUNC_W(); break;
case R4300i_COP1_FUNCT_CEIL_W: COP1_D_CEIL_W(); break; //added by Witten
case R4300i_COP1_FUNCT_FLOOR_W: COP1_D_FLOOR_W(); break; //added by Witten
case R4300i_COP1_FUNCT_CVT_S: COP1_D_CVT_S(); break;
case R4300i_COP1_FUNCT_CVT_W: COP1_D_CVT_W(); break;
case R4300i_COP1_FUNCT_CVT_L: COP1_D_CVT_L(); break;
case R4300i_COP1_FUNCT_C_F: case R4300i_COP1_FUNCT_C_UN:
case R4300i_COP1_FUNCT_C_EQ: case R4300i_COP1_FUNCT_C_UEQ:
case R4300i_COP1_FUNCT_C_OLT: case R4300i_COP1_FUNCT_C_ULT:
case R4300i_COP1_FUNCT_C_OLE: case R4300i_COP1_FUNCT_C_ULE:
case R4300i_COP1_FUNCT_C_SF: case R4300i_COP1_FUNCT_C_NGLE:
case R4300i_COP1_FUNCT_C_SEQ: case R4300i_COP1_FUNCT_C_NGL:
case R4300i_COP1_FUNCT_C_LT: case R4300i_COP1_FUNCT_C_NGE:
case R4300i_COP1_FUNCT_C_LE: case R4300i_COP1_FUNCT_C_NGT:
COP1_D_CMP(); break;
default:
UnknownOpcode(); break;
}
break;
case R4300i_COP1_W:
switch (m_Opcode.funct) {
case R4300i_COP1_FUNCT_CVT_S: COP1_W_CVT_S(); break;
case R4300i_COP1_FUNCT_CVT_D: COP1_W_CVT_D(); break;
default:
UnknownOpcode(); break;
}
break;
case R4300i_COP1_L:
switch (m_Opcode.funct) {
case R4300i_COP1_FUNCT_CVT_S: COP1_L_CVT_S(); break;
case R4300i_COP1_FUNCT_CVT_D: COP1_L_CVT_D(); break;
default:
UnknownOpcode(); break;
}
break;
default:
UnknownOpcode(); break;
}
break;
case R4300i_BEQL: Compile_BranchLikely(BEQ_Compare,false); break;
case R4300i_BNEL: Compile_BranchLikely(BNE_Compare,false); break;
case R4300i_BGTZL:Compile_BranchLikely(BGTZ_Compare,false); break;
case R4300i_BLEZL:Compile_BranchLikely(BLEZ_Compare,false); break;
case R4300i_DADDIU: DADDIU(); break;
case R4300i_LDL: LDL(); break;
case R4300i_LDR: LDR(); break;
case R4300i_LB: LB(); break;
case R4300i_LH: LH(); break;
case R4300i_LWL: LWL(); break;
case R4300i_LW: LW(); break;
case R4300i_LBU: LBU(); break;
case R4300i_LHU: LHU(); break;
case R4300i_LWR: LWR(); break;
case R4300i_LWU: LWU(); break; //added by Witten
case R4300i_SB: SB(); break;
case R4300i_SH: SH(); break;
case R4300i_SWL: SWL(); break;
case R4300i_SW: SW(); break;
case R4300i_SWR: SWR(); break;
case R4300i_SDL: SDL(); break;
case R4300i_SDR: SDR(); break;
case R4300i_CACHE: CACHE(); break;
case R4300i_LL: LL(); break;
case R4300i_LWC1: LWC1(); break;
case R4300i_LDC1: LDC1(); break;
case R4300i_SC: SC(); break;
case R4300i_LD: LD(); break;
case R4300i_SWC1: SWC1(); break;
case R4300i_SDC1: SDC1(); break;
case R4300i_SD: SD(); break;
default:
UnknownOpcode(); break;
}
#ifdef tofix
if (!bRegCaching()) { WriteBackRegisters(); }
/*if ((DWORD)RecompPos > 0x60B452E6) {
if (m_CompilePC == 0x8002D9B8 && m_CompilePC < 0x8002DA20) {
CurrentRoundingModel = RoundUnknown;
}
}*/
UnMap_AllFPRs();
/*if ((DWORD)RecompPos > 0x60AD0BD3) {
if (m_CompilePC >= 0x8008B804 && m_CompilePC < 0x800496D8) {
CPU_Message("Blah *");
WriteBackRegisters();
}
/*if (m_CompilePC >= 0x80000180 && m_CompilePC < 0x80000190) {
CPU_Message("Blah *");
//WriteBackRegisters();
}*/
//}
/*for (count = 1; count < 10; count ++) {
if (x86Mapped(count) == CRegInfo::Stack_Mapped) {
UnMap_X86reg (Section, count);
}
}*/
//CPU_Message("MemoryStack = %s",Map_MemoryStack(Section, false) > 0?x86_Name(Map_MemoryStack(Section, false)):"Not Mapped");
if ((m_CompilePC &0xFFC) == 0xFFC) {
if (NextInstruction == DO_DELAY_SLOT) {
#ifndef EXTERNAL_RELEASE
DisplayError("Wanting to do delay slot over end of block");
#endif
}
if (NextInstruction == NORMAL) {
CompileExit (Section,m_CompilePC, m_CompilePC + 4,m_RegWorkingSet,CExitInfo::Normal,true,NULL);
NextInstruction = END_BLOCK;
}
}
if (DelaySlotSection)
{
Cont.RegSet = m_RegWorkingSet;
GenerateSectionLinkage();
NextInstruction = END_BLOCK;
}
#endif
switch (m_NextInstruction) {
case NORMAL:
m_CompilePC += 4;
break;
case DO_DELAY_SLOT:
m_NextInstruction = DELAY_SLOT;
m_CompilePC += 4;
break;
case DELAY_SLOT:
m_NextInstruction = DELAY_SLOT_DONE;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_CountPerOp);
m_CompilePC -= 4;
break;
}
} while (m_NextInstruction != END_BLOCK);
return true;
}

View File

@ -0,0 +1,94 @@
#pragma once
class CCodeBlock;
class CCodeSection :
private CRecompilerOps
{
public:
CCodeSection( CCodeBlock * CodeBlock, DWORD EnterPC, DWORD ID);
~CCodeSection( void );
bool GenerateX86Code ( DWORD Test );
void GenerateSectionLinkage ( void );
void CompileSystemCheck ( DWORD TargetPC, const CRegInfo &RegSet );
void CompileExit ( DWORD JumpPC, DWORD TargetPC, CRegInfo ExitRegSet, CExitInfo::EXIT_REASON reason, int CompileNow, void (*x86Jmp)(char * Label, DWORD Value));
/* Block Connection info */
CCodeBlock * const m_BlockInfo;
const DWORD m_EnterPC;
const DWORD m_SectionID;
CCodeSection * m_ContinueSection;
CCodeSection * m_JumpSection;
bool m_LinkAllowed; // are other sections allowed to find block to link to it
DWORD m_Test;
BYTE * m_CompiledLocation;
/* SECTION_LIST ParentSection;
DWORD Test2;
bool InLoop;
bool DelaySlotSection;
/* Register Info */
CRegInfo m_RegEnter;
/* Jump Info */
CJumpInfo m_Jump;
CJumpInfo m_Cont;
//Information about the opcode current being compiled
/* DWORD m_CompilePC;
OPCODE m_CompileOpcode;
void AddParent ( CCodeSection * Parent );
void UnlinkParent ( CCodeSection * Parent, bool AllowDelete, bool ContinueLink );
bool IsAllParentLoops ( CCodeSection * Parent, bool IgnoreIfCompiled, DWORD Test );
void ResetX86Protection ( void );
static DWORD GetNewTestValue ( void );
static void TestRegConstantStates ( CRegInfo & Base, CRegInfo & Reg );
//Handy Functions
inline CRegInfo::REG_STATE & MipsRegState ( int Reg ) { return RegWorking.MipsRegState(Reg); }
inline unsigned _int64 & MipsReg ( int Reg ) { return RegWorking.MipsReg(Reg); }
inline _int64 & MipsReg_S ( int Reg ) { return RegWorking.MipsReg_S(Reg); }
inline DWORD & MipsRegLo ( int Reg ) { return RegWorking.MipsRegLo(Reg); }
inline long & MipsRegLo_S ( int Reg ) { return RegWorking.MipsRegLo_S(Reg); }
inline DWORD & MipsRegHi ( int Reg ) { return RegWorking.MipsRegHi(Reg); }
inline long & MipsRegHi_S ( int Reg ) { return RegWorking.MipsRegHi_S(Reg); }
inline DWORD & BlockCycleCount(void) { return RegWorking.BlockCycleCount(); }
inline DWORD & BlockRandomModifier(void) { return RegWorking.BlockRandomModifier(); }
inline DWORD & x86MapOrder( int Reg ) { return RegWorking.x86MapOrder(Reg); }
inline bool & x86Protected( int Reg ) { return RegWorking.x86Protected(Reg); }
inline CRegInfo::REG_MAPPED & x86Mapped(int Reg) { return RegWorking.x86Mapped(Reg); }
inline bool IsKnown(int Reg) { return RegWorking.IsKnown(Reg); }
inline bool IsUnknown(int Reg) { return RegWorking.IsUnknown(Reg); }
inline bool IsMapped(int Reg) { return RegWorking.IsMapped(Reg); }
inline bool IsConst(int Reg) { return RegWorking.IsConst(Reg); }
inline bool IsSigned(int Reg) { return RegWorking.IsSigned(Reg); }
inline bool IsUnsigned(int Reg) { return RegWorking.IsUnsigned(Reg); }
inline bool Is32Bit(int Reg) { return RegWorking.Is32Bit(Reg); }
inline bool Is64Bit(int Reg) { return RegWorking.Is64Bit(Reg); }
inline bool Is32BitMapped(int Reg) { return RegWorking.Is32BitMapped(Reg); }
inline bool Is64BitMapped(int Reg) { return RegWorking.Is64BitMapped(Reg); }
inline int & StackTopPos ( void ) { return RegWorking.StackTopPos(); }
inline DWORD & FpuMappedTo( int Reg) { return RegWorking.FpuMappedTo(Reg); }
inline CRegInfo::FPU_STATE & FpuState(int Reg) { return RegWorking.FpuState(Reg); }
inline CRegInfo::FPU_ROUND & FpuRoundingModel(int Reg) { return RegWorking.FpuRoundingModel(Reg); }
inline bool & FpuBeenUsed (void ) { return RegWorking.FpuBeenUsed(); }
inline CRegInfo::FPU_ROUND & CurrentRoundingModel ( void ) { return RegWorking.CurrentRoundingModel(); }*/
private:
};

View File

@ -12,6 +12,8 @@ CDelaySlotFunctionMap::~CDelaySlotFunctionMap()
CCompiledFunc * CDelaySlotFunctionMap::AddFunctionInfo ( DWORD vAddr, DWORD pAddr )
{
Notify().BreakPoint(__FILE__,__LINE__);
#ifdef tofix
if (FunctionMap.find(vAddr) != FunctionMap.end())
{
Notify().BreakPoint(__FILE__,__LINE__);
@ -22,6 +24,7 @@ CCompiledFunc * CDelaySlotFunctionMap::AddFunctionInfo ( DWORD vAddr, DWORD pAdd
return info;
Notify().BreakPoint(__FILE__,__LINE__);
#endif
return NULL;
}
@ -53,13 +56,16 @@ CCompiledFunc * CDelaySlotFunctionMap::FindFunction ( DWORD vAddr ) const
void CDelaySlotFunctionMap::Remove ( CCompiledFunc * info )
{
FUNCTION_MAP::iterator iter = FunctionMap.find(info->VStartPC());
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
FUNCTION_MAP::iterator iter = FunctionMap.find(info->VAddrEnter());
if (iter != FunctionMap.end())
{
delete iter->second;
FunctionMap.erase(iter);
}
#endif
}
void CDelaySlotFunctionMap::Reset ( void )

View File

@ -0,0 +1,24 @@
class CExitInfo
{
public:
enum EXIT_REASON
{
Normal = 0,
Normal_NoSysCheck = 1,
DoCPU_Action = 2,
COP1_Unuseable = 3,
DoSysCall = 4,
TLBReadMiss = 5,
TLBWriteMiss = 6,
ExitResetRecompCode = 7,
};
DWORD ID;
DWORD TargetPC;
CRegInfo ExitRegSet;
EXIT_REASON reason;
STEP_TYPE NextInstruction;
BYTE * JumpLoc; //32bit jump
};
typedef std::list<CExitInfo> EXIT_LIST;

View File

@ -1,9 +1,20 @@
#include "..\..\N64 System.h"
CCompiledFunc::CCompiledFunc( const CCodeBlock & CodeBlock ) :
m_EnterPC(CodeBlock.VAddrEnter()),
m_MinPC(CodeBlock.VAddrFirst()),
m_MaxPC(CodeBlock.VAddrLast()),
m_Function((Func)CodeBlock.CompiledLocation())
{
}
#ifdef tofix
CCompiledFunc::CCompiledFunc(DWORD StartAddress, DWORD PhysicalStartAddress) :
m_VStartPC(StartAddress),
m_PStartPC(PhysicalStartAddress),
m_VEndPC(0),
m_VEnterPC(StartAddress),
m_PEnterPC(PhysicalStartAddress),
m_VMinPC(StartAddress),
m_VMaxPC(StartAddress),
m_Function(NULL),
Next(NULL)
{
@ -17,7 +28,7 @@ CCompiledFunc::CCompiledFunc(DWORD StartAddress, DWORD PhysicalStartAddress) :
bool CCompiledFunc::CompilerCodeBlock(void)
{
DWORD StartTime = timeGetTime();
WriteTraceF(TraceRecompiler,"Compile Block-Start: VAddr: %X PAddr",m_VStartPC,m_PStartPC);
WriteTraceF(TraceRecompiler,"Compile Block-Start: VEnterPC: %X PEnterPC",m_VEnterPC,m_PEnterPC);
//if (bProfiling()) { m_Profile.StartTimer(Timer_GetBlockInfo); }
@ -48,7 +59,7 @@ bool CCompiledFunc::CompilerCodeBlock(void)
#endif
ExitThread(0);
#endif
}*/
}
#endif
CPU_Message("====== Code block ======");
CPU_Message("VAddress: %X",BlockInfo.StartVAddr );
@ -110,3 +121,5 @@ bool CCompiledFunc::CompilerCodeBlock(void)
WriteTraceF(TraceRecompiler,"Compile Block-Done: %X-%X - Taken: %d",info->VStartPC(),info->VEndPC(),TimeTaken);*/
return true;
}
#endif

View File

@ -1,35 +1,28 @@
typedef void (* RECOMP_FUNC)(void);
class CCompiledFunc
{
//Information
DWORD m_VStartPC; //The Virtual Address that the jump is going to
DWORD m_PStartPC; //The Physical Address that the jump is going to
DWORD m_VEndPC;
//From querying the recompiler get information about the function
RECOMP_FUNC m_Function;
public:
//constructor
CCompiledFunc (DWORD VirtualStartAddress, DWORD PhysicalStartAddress );
CCompiledFunc ( void ); // not implemented
public:
CCompiledFunc ( const CCodeBlock & CodeBlock );
typedef void (* Func)(void);
//Get Private Information
inline const DWORD VStartPC ( void ) const { return m_VStartPC; }
inline const DWORD PStartPC ( void ) const { return m_PStartPC; }
inline const DWORD VEndPC ( void ) const { return m_VEndPC; }
inline const RECOMP_FUNC Function ( void ) const { return m_Function; }
inline const DWORD EnterPC ( void ) const { return m_EnterPC; }
inline const DWORD MinPC ( void ) const { return m_MinPC; }
inline const DWORD MaxPC ( void ) const { return m_MaxPC; }
inline const Func Function ( void ) const { return m_Function; }
private:
//Information
DWORD m_EnterPC; // The Entry PC
DWORD m_MinPC; // The Lowest PC in the function
DWORD m_MaxPC; // The Highest PC in the function
//From querying the recompiler get information about the function
Func m_Function;
//Set Private Information
inline void SetVEndPC ( DWORD VEndPC ) { m_VEndPC = VEndPC; }
inline void SetFunctionAddr ( RECOMP_FUNC FunctionAddr ) { m_Function = FunctionAddr; }
//Functions
bool CompilerCodeBlock ( void );
//Validation
QWORD MemContents[2], * MemLocation[2];
CCompiledFunc * Next;
//QWORD MemContents[2], * MemLocation[2];
};

View File

@ -0,0 +1,14 @@
class CJumpInfo
{
public:
CJumpInfo();
DWORD TargetPC;
char * BranchLabel;
DWORD * LinkLocation;
DWORD * LinkLocation2;
BOOL FallThrough;
BOOL PermLoop;
BOOL DoneDelaySlot;
CRegInfo RegSet;
};

File diff suppressed because it is too large Load Diff

View File

@ -21,18 +21,14 @@ public:
void Run ( void );
void ResetRecompCode ( void );
void CompileSystemCheck (DWORD TargetPC, CRegInfo &RegSet);
void UpdateCounters ( DWORD * Cycles, DWORD * RandomMod, BOOL CheckTimer);
void CompileExit ( CCodeSection * Section, DWORD JumpPC, DWORD TargetPC, CRegInfo ExitRegSet, CExitInfo::EXIT_REASON reason, int CompileNow, void (*x86Jmp)(char * Label, DWORD Value));
bool GenerateX86Code (CBlockInfo & BlockInfo, CCodeSection * Section, DWORD Test );
void GenerateSectionLinkage (CCodeSection * Section);
bool GenerateX86Code (CCodeBlock & BlockInfo, CCodeSection * Section, DWORD Test );
//Self modifying code methods
bool ClearRecompCode_Virt ( DWORD VirtualAddress, int length, REMOVE_REASON Reason );
bool ClearRecompCode_Phys ( DWORD PhysicalAddress, int length, REMOVE_REASON Reason );
private:
bool const m_SyncSystem;
bool const m_SyncSystem;
CProfiling & m_Profile;
bool & m_EndEmulation;
@ -47,12 +43,10 @@ private:
CCompiledFunc * CompileDelaySlot ( DWORD PC );
bool Compiler4300iBlock ( CCompiledFunc * info );
void CheckRecompMem ( void );
// Compiling code
bool AnalyseBlock ( CBlockInfo & BlockInfo );
bool AnalyseBlock ( CCodeBlock & BlockInfo );
bool CreateSectionLinkage ( CCodeSection * Section );
void CompileExitCode ( CBlockInfo & BlockInfo );
void CompileExitCode ( CCodeBlock & BlockInfo );
void DetermineLoop ( CCodeSection * Section, DWORD Test, DWORD Test2, DWORD TestID);
bool DisplaySectionInformation (CCodeSection * Section, DWORD ID, DWORD Test);
bool FixConstants ( CCodeSection * Section, DWORD Test );

View File

@ -1,9 +1,10 @@
#include "stdafx.h"
CRecompMemory::CRecompMemory() :
m_RecompCode(0),
m_RecompCode(NULL),
m_RecompSize(0)
{
m_RecompPos = NULL;
}
CRecompMemory::~CRecompMemory()
@ -13,6 +14,7 @@ CRecompMemory::~CRecompMemory()
VirtualFree( m_RecompCode, 0 , MEM_RELEASE);
m_RecompCode = NULL;
}
m_RecompPos = NULL;
}
bool CRecompMemory::AllocateMemory()
@ -31,6 +33,26 @@ bool CRecompMemory::AllocateMemory()
return FALSE;
}
m_RecompSize = InitialCompileBufferSize;
m_RecompPos = m_RecompCode;
return true;
}
}
void CRecompMemory::CheckRecompMem ( void )
{
int Size = (int)((BYTE *)m_RecompPos - (BYTE *)m_RecompCode);
if ((Size + 0x20000) < m_RecompSize)
{
return;
}
if (m_RecompSize == MaxCompileBufferSize)
{
return;
}
LPVOID MemAddr = VirtualAlloc( m_RecompCode + m_RecompSize , IncreaseCompileBufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
m_RecompSize += IncreaseCompileBufferSize;
if (MemAddr == NULL)
{
_Notify->FatalError(MSG_MEM_ALLOC_ERROR);
}
}

View File

@ -1,11 +1,16 @@
class CRecompMemory
class CRecompMemory :
protected CX86Ops
{
protected:
CRecompMemory();
~CRecompMemory();
bool AllocateMemory ( void );
void CheckRecompMem ( void );
inline BYTE * RecompPos ( void ) const { return m_RecompPos; }
private:
BYTE * m_RecompCode;
DWORD m_RecompSize;

File diff suppressed because it is too large Load Diff

View File

@ -1,188 +1,272 @@
class CRecompilerOps
{
CRecompilerOps();
class CCodeSection;
class CRecompilerOps :
protected CX86Ops
{
protected:
enum BRANCH_TYPE
{
BranchTypeCop1, BranchTypeRs, BranchTypeRsRt
};
typedef void (CRecompilerOps::* BranchFunction) (void);
typedef void ( * BranchFunction )();
CRecompilerOps( CCodeSection * Section );
/************************** Branch functions ************************/
void Compile_Branch ( BranchFunction CompareFunc, BRANCH_TYPE BranchType, BOOL Link);
void Compile_BranchLikely ( BranchFunction CompareFunc, BOOL Link);
void BNE_Compare ( void );
void BEQ_Compare ( void );
void BGTZ_Compare ( void );
void BLEZ_Compare ( void );
void BLTZ_Compare ( void );
void BGEZ_Compare ( void );
void COP1_BCF_Compare ( void );
void COP1_BCT_Compare ( void );
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 );
/************************* OpCode functions *************************/
void Compile_J ( void );
void Compile_JAL ( void );
void Compile_ADDI ( void );
void Compile_ADDIU ( void );
void Compile_SLTI ( void );
void Compile_SLTIU ( void );
void Compile_ANDI ( void );
void Compile_ORI ( void );
void Compile_XORI ( void );
void Compile_LUI ( void );
void Compile_DADDIU ( void );
void Compile_LDL ( void );
void Compile_LDR ( void );
void Compile_LB ( void );
void Compile_LH ( void );
void Compile_LWL ( void );
void Compile_LW ( void );
void Compile_LBU ( void );
void Compile_LHU ( void );
void Compile_LWR ( void );
void Compile_LWU ( void ); //added by Witten
void Compile_SB ( void );
void Compile_SH ( void );
void Compile_SWL ( void );
void Compile_SW ( void );
void Compile_SWR ( void );
void Compile_SDL ( void );
void Compile_SDR ( void );
void Compile_CACHE ( void );
void Compile_LL ( void );
void Compile_LWC1 ( void );
void Compile_LDC1 ( void );
void Compile_LD ( void );
void Compile_SC ( void );
void Compile_SWC1 ( void );
void Compile_SDC1 ( void );
void Compile_SD ( void );
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 );
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 );
static void CACHE ( void );
static void LL ( void );
static void LWC1 ( void );
static void LDC1 ( void );
static void LD ( void );
static void SC ( void );
static void SWC1 ( void );
static void SDC1 ( void );
static void SD ( void );
/********************** R4300i OpCodes: Special **********************/
void Compile_SPECIAL_SLL ( void );
void Compile_SPECIAL_SRL ( void );
void Compile_SPECIAL_SRA ( void );
void Compile_SPECIAL_SLLV ( void );
void Compile_SPECIAL_SRLV ( void );
void Compile_SPECIAL_SRAV ( void );
void Compile_SPECIAL_JR ( void );
void Compile_SPECIAL_JALR ( void );
void Compile_SPECIAL_SYSCALL( void );
void Compile_SPECIAL_MFLO ( void );
void Compile_SPECIAL_MTLO ( void );
void Compile_SPECIAL_MFHI ( void );
void Compile_SPECIAL_MTHI ( void );
void Compile_SPECIAL_DSLLV ( void );
void Compile_SPECIAL_DSRLV ( void );
void Compile_SPECIAL_DSRAV ( void );
void Compile_SPECIAL_MULT ( void );
void Compile_SPECIAL_MULTU ( void );
void Compile_SPECIAL_DIV ( void );
void Compile_SPECIAL_DIVU ( void );
void Compile_SPECIAL_DMULT ( void );
void Compile_SPECIAL_DMULTU ( void );
void Compile_SPECIAL_DDIV ( void );
void Compile_SPECIAL_DDIVU ( void );
void Compile_SPECIAL_ADD ( void );
void Compile_SPECIAL_ADDU ( void );
void Compile_SPECIAL_SUB ( void );
void Compile_SPECIAL_SUBU ( void );
void Compile_SPECIAL_AND ( void );
void Compile_SPECIAL_OR ( void );
void Compile_SPECIAL_XOR ( void );
void Compile_SPECIAL_NOR ( void );
void Compile_SPECIAL_SLT ( void );
void Compile_SPECIAL_SLTU ( void );
void Compile_SPECIAL_DADD ( void );
void Compile_SPECIAL_DADDU ( void );
void Compile_SPECIAL_DSUB ( void );
void Compile_SPECIAL_DSUBU ( void );
void Compile_SPECIAL_DSLL ( void );
void Compile_SPECIAL_DSRL ( void );
void Compile_SPECIAL_DSRA ( void );
void Compile_SPECIAL_DSLL32 ( void );
void Compile_SPECIAL_DSRL32 ( void );
void Compile_SPECIAL_DSRA32 ( void );
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 );
/************************** COP0 functions **************************/
void Compile_COP0_MF ( void );
void Compile_COP0_MT ( void );
static void COP0_MF ( void );
static void COP0_MT ( void );
/************************** COP0 CO functions ***********************/
void Compile_COP0_CO_TLBR ( void );
void Compile_COP0_CO_TLBWI ( void );
void Compile_COP0_CO_TLBWR ( void );
void Compile_COP0_CO_TLBP ( void );
void Compile_COP0_CO_ERET ( void );
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 );
/************************** COP1 functions **************************/
void Compile_COP1_MF ( void );
void Compile_COP1_DMF ( void );
void Compile_COP1_CF ( void );
void Compile_COP1_MT ( void );
void Compile_COP1_DMT ( void );
void Compile_COP1_CT ( void );
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 );
/************************** COP1: S functions ************************/
void Compile_COP1_S_ADD ( void );
void Compile_COP1_S_SUB ( void );
void Compile_COP1_S_MUL ( void );
void Compile_COP1_S_DIV ( void );
void Compile_COP1_S_ABS ( void );
void Compile_COP1_S_NEG ( void );
void Compile_COP1_S_SQRT ( void );
void Compile_COP1_S_MOV ( void );
void Compile_COP1_S_TRUNC_L ( void );
void Compile_COP1_S_CEIL_L ( void ); //added by Witten
void Compile_COP1_S_FLOOR_L ( void ); //added by Witten
void Compile_COP1_S_ROUND_W ( void );
void Compile_COP1_S_TRUNC_W ( void );
void Compile_COP1_S_CEIL_W ( void ); //added by Witten
void Compile_COP1_S_FLOOR_W ( void );
void Compile_COP1_S_CVT_D ( void );
void Compile_COP1_S_CVT_W ( void );
void Compile_COP1_S_CVT_L ( void );
void Compile_COP1_S_CMP ( void );
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 );
/************************** COP1: D functions ************************/
void Compile_COP1_D_ADD ( void );
void Compile_COP1_D_SUB ( void );
void Compile_COP1_D_MUL ( void );
void Compile_COP1_D_DIV ( void );
void Compile_COP1_D_ABS ( void );
void Compile_COP1_D_NEG ( void );
void Compile_COP1_D_SQRT ( void );
void Compile_COP1_D_MOV ( void );
void Compile_COP1_D_TRUNC_L ( void ); //added by Witten
void Compile_COP1_D_CEIL_L ( void ); //added by Witten
void Compile_COP1_D_FLOOR_L ( void ); //added by Witten
void Compile_COP1_D_ROUND_W ( void );
void Compile_COP1_D_TRUNC_W ( void );
void Compile_COP1_D_CEIL_W ( void ); //added by Witten
void Compile_COP1_D_FLOOR_W ( void ); //added by Witten
void Compile_COP1_D_CVT_S ( void );
void Compile_COP1_D_CVT_W ( void );
void Compile_COP1_D_CVT_L ( void );
void Compile_COP1_D_CMP ( void );
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 );
/************************** COP1: W functions ************************/
void Compile_COP1_W_CVT_S ( void );
void Compile_COP1_W_CVT_D ( void );
static void COP1_W_CVT_S ( void );
static void COP1_W_CVT_D ( void );
/************************** COP1: L functions ************************/
void Compile_COP1_L_CVT_S ( void );
void Compile_COP1_L_CVT_D ( void );
static void COP1_L_CVT_S ( void );
static void COP1_L_CVT_D ( void );
/************************** Other functions **************************/
void Compile_UnknownOpcode ( void );
void CompileReadTLBMiss (CCodeSection * Section, int AddressReg, int LookUpReg );
void CompileWriteTLBMiss (CCodeSection * Section, int AddressReg, int LookUpReg );
static void UnknownOpcode ( void );
static void CompileReadTLBMiss (CCodeSection * Section, int AddressReg, int LookUpReg );
static void CompileWriteTLBMiss (CCodeSection * Section, int AddressReg, int LookUpReg );
static void UpdateCounters (CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false );
private:
CCodeSection * m_Section;
static STEP_TYPE m_NextInstruction;
static DWORD m_CompilePC;
static OPCODE m_Opcode;
static CRegInfo m_RegWorkingSet;
static CCodeSection * m_Section;
/********* Helper Functions *********/
typedef CRegInfo::REG_STATE REG_STATE;
static inline REG_STATE cMipsRegState ( int Reg ) { return m_RegWorkingSet.cMipsRegState(Reg); }
static inline unsigned __int64 cMipsReg ( int Reg ) { return m_RegWorkingSet.cMipsReg(Reg); }
static inline __int64 cMipsReg_S ( int Reg ) { return m_RegWorkingSet.cMipsReg_S(Reg); }
static inline DWORD cMipsRegLo ( int Reg ) { return m_RegWorkingSet.cMipsRegLo(Reg); }
static inline long cMipsRegLo_S ( int Reg ) { return m_RegWorkingSet.cMipsRegLo_S(Reg); }
static inline DWORD cMipsRegHi ( int Reg ) { return m_RegWorkingSet.cMipsRegHi(Reg); }
static inline long cMipsRegHi_S ( int Reg ) { return m_RegWorkingSet.cMipsRegHi_S(Reg); }
static inline CX86Ops::x86Reg cMipsRegMapLo ( int Reg ) { return m_RegWorkingSet.cMipsRegMapLo(Reg); }
static inline CX86Ops::x86Reg cMipsRegMapHi ( int Reg ) { return m_RegWorkingSet.cMipsRegMapHi(Reg); }
static inline REG_STATE & MipsRegState ( int Reg ) { return m_RegWorkingSet.MipsRegState(Reg); }
static inline unsigned _int64 & MipsReg ( int Reg ) { return m_RegWorkingSet.MipsReg(Reg); }
static inline _int64 & MipsReg_S ( int Reg ) { return m_RegWorkingSet.MipsReg_S(Reg); }
static inline DWORD & MipsRegLo ( int Reg ) { return m_RegWorkingSet.MipsRegLo(Reg); }
static inline long & MipsRegLo_S ( int Reg ) { return m_RegWorkingSet.MipsRegLo_S(Reg); }
static inline DWORD & MipsRegHi ( int Reg ) { return m_RegWorkingSet.MipsRegHi(Reg); }
static inline long & MipsRegHi_S ( int Reg ) { return m_RegWorkingSet.MipsRegHi_S(Reg); }
static inline CX86Ops::x86Reg & MipsRegMapLo ( int Reg ) { return m_RegWorkingSet.MipsRegMapLo(Reg); }
static inline CX86Ops::x86Reg & MipsRegMapHi ( int Reg ) { return m_RegWorkingSet.MipsRegMapHi(Reg); }
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); }
static inline x86Reg FreeX86Reg ( void )
{
return m_RegWorkingSet.FreeX86Reg();
}
static inline x86Reg Free8BitX86Reg ( void )
{
return m_RegWorkingSet.Free8BitX86Reg();
}
static inline void Map_GPR_32bit ( int Reg, BOOL SignValue, int MipsRegToLoad )
{
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);
}
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);
}
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);
}
public:
static DWORD CompilePC ( void ) { return m_CompilePC; }
};

View File

@ -0,0 +1,771 @@
#include "stdafx.h"
unsigned int CRegInfo::m_fpuControl = 0;
void CRegInfo::Initilize ( void )
{
int count;
MIPS_RegState[0] = STATE_CONST_32;
MIPS_RegVal[0].DW = 0;
RegMapLo[0] = x86_Unknown;
RegMapHi[0] = x86_Unknown;
for (count = 1; count < 32; count ++ ) {
MIPS_RegState[count] = STATE_UNKNOWN;
MIPS_RegVal[count].DW = 0;
RegMapLo[count] = x86_Unknown;
RegMapHi[count] = x86_Unknown;
}
for (count = 0; count < 10; count ++ ) {
x86reg_MappedTo[count] = NotMapped;
x86reg_Protected[count] = false;
x86reg_MapOrder[count] = 0;
}
m_CycleCount = 0;
Stack_TopPos = 0;
for (count = 0; count < 8; count ++ ) {
x86fpu_MappedTo[count] = -1;
x86fpu_State[count] = FPU_Unkown;
x86fpu_RoundingModel[count] = RoundDefault;
}
Fpu_Used = false;
RoundingModel = RoundUnknown;
}
void CRegInfo::FixRoundModel(FPU_ROUND RoundMethod )
{
if (CurrentRoundingModel() == RoundMethod)
{
return;
}
m_fpuControl = 0;
fpuStoreControl(&m_fpuControl, "m_fpuControl");
x86Reg reg = Map_TempReg(x86_Any,-1,FALSE);
MoveVariableToX86reg(&m_fpuControl, "m_fpuControl", reg);
AndConstToX86Reg(reg, 0xF3FF);
switch (RoundMethod) {
case CRegInfo::RoundDefault: OrVariableToX86Reg(&_Reg->m_RoundingModel,"FPU_RoundingMode", reg); break;
case CRegInfo::RoundTruncate: OrConstToX86Reg(0x0C00, reg); break;
case CRegInfo::RoundNearest: /*OrConstToX86Reg(0x0000, reg);*/ break;
case CRegInfo::RoundDown: OrConstToX86Reg(0x0400, reg); break;
case CRegInfo::RoundUp: OrConstToX86Reg(0x0800, reg); break;
default:
DisplayError("Unknown Rounding model");
}
MoveX86regToVariable(reg, &m_fpuControl, "m_fpuControl");
fpuLoadControl(&m_fpuControl, "m_fpuControl");
CurrentRoundingModel() = RoundMethod;
}
CX86Ops::x86Reg CRegInfo::FreeX86Reg ( void )
{
if (x86Mapped(x86_EDI) == NotMapped && !x86Protected(x86_EDI)) { return x86_EDI; }
if (x86Mapped(x86_ESI) == NotMapped && !x86Protected(x86_ESI)) { return x86_ESI; }
if (x86Mapped(x86_EBX) == NotMapped && !x86Protected(x86_EBX)) { return x86_EBX; }
if (x86Mapped(x86_EAX) == NotMapped && !x86Protected(x86_EAX)) { return x86_EAX; }
if (x86Mapped(x86_EDX) == NotMapped && !x86Protected(x86_EDX)) { return x86_EDX; }
if (x86Mapped(x86_ECX) == NotMapped && !x86Protected(x86_ECX)) { return x86_ECX; }
x86Reg Reg = UnMap_TempReg();
if (Reg != x86_Unknown) { return Reg; }
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
int count, MapCount[10], MapReg[10];
for (count = 0; count < 10; count ++)
{
MapCount[count] = x86MapOrder(count);
MapReg[count] = count;
}
for (count = 0; count < 10; count ++) {
int i;
for (i = 0; i < 9; i ++) {
int temp;
if (MapCount[i] < MapCount[i+1]) {
temp = MapCount[i];
MapCount[i] = MapCount[i+1];
MapCount[i+1] = temp;
temp = MapReg[i];
MapReg[i] = MapReg[i+1];
MapReg[i+1] = temp;
}
}
}
x86Reg StackReg = x86_Unknown;
for (count = 0; count < 10; count ++)
{
if (MapCount[count] > 0 && x86Mapped(MapReg[count]) != CRegInfo::Stack_Mapped)
{
if (UnMap_X86reg((x86Reg)MapReg[count]))
{
return (x86Reg)MapReg[count];
}
}
if (x86Mapped(MapReg[count]) == CRegInfo::Stack_Mapped) { StackReg = MapReg[count]; }
}
if (StackReg != x86_Unknown) {
UnMap_X86reg(StackReg);
return StackReg;
}
#endif
return x86_Unknown;
}
CX86Ops::x86Reg CRegInfo::Free8BitX86Reg ( void )
{
if (x86Mapped(x86_EBX) == NotMapped && !x86Protected(x86_EBX)) {return x86_EBX; }
if (x86Mapped(x86_EAX) == NotMapped && !x86Protected(x86_EAX)) {return x86_EAX; }
if (x86Mapped(x86_EDX) == NotMapped && !x86Protected(x86_EDX)) {return x86_EDX; }
if (x86Mapped(x86_ECX) == NotMapped && !x86Protected(x86_ECX)) {return x86_ECX; }
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
int x86Reg, count, MapCount[10], MapReg[10];
x86Reg = UnMap_8BitTempReg(Section);
if (x86Reg > 0) { return x86Reg; }
for (count = 0; count < 10; count ++) {
MapCount[count] = x86MapOrder(count);
MapReg[count] = count;
}
for (count = 0; count < 10; count ++) {
int i;
for (i = 0; i < 9; i ++) {
int temp;
if (MapCount[i] < MapCount[i+1]) {
temp = MapCount[i];
MapCount[i] = MapCount[i+1];
MapCount[i+1] = temp;
temp = MapReg[i];
MapReg[i] = MapReg[i+1];
MapReg[i+1] = temp;
}
}
}
for (count = 0; count < 10; count ++) {
if (MapCount[count] > 0) {
if (!Is8BitReg(count)) { continue; }
if (UnMap_X86reg(Section,count)) {
return count;
}
}
}
#endif
return x86_Unknown;
}
void CRegInfo::Map_GPR_32bit (int MipsReg, BOOL SignValue, int MipsRegToLoad)
{
int count;
x86Reg Reg;
if (MipsReg == 0) {
#ifndef EXTERNAL_RELEASE
DisplayError("Map_GPR_32bit\n\nWhy are you trying to map reg 0");
#endif
return;
}
if (IsUnknown(MipsReg) || IsConst(MipsReg)) {
Reg = FreeX86Reg();
if (Reg < 0) {
#ifndef EXTERNAL_RELEASE
DisplayError("Map_GPR_32bit\n\nOut of registers");
BreakPoint(__FILE__,__LINE__);
#endif
return;
}
CPU_Message(" regcache: allocate %s to %s",x86_Name(Reg),CRegName::GPR[MipsReg]);
} else {
if (Is64Bit(MipsReg)) {
CPU_Message(" regcache: unallocate %s from high 32bit of %s",x86_Name(MipsRegMapHi(MipsReg)),CRegName::GPR_Hi[MipsReg]);
x86MapOrder(MipsRegHi(MipsReg)) = 0;
x86Mapped(MipsRegHi(MipsReg)) = CRegInfo::NotMapped;
x86Protected(MipsRegHi(MipsReg)) = FALSE;
MipsRegHi(MipsReg) = 0;
}
Reg = MipsRegMapLo(MipsReg);
}
for (count = 0; count < 10; count ++) {
if (x86MapOrder(count) > 0) {
x86MapOrder(count) += 1;
}
}
x86MapOrder(Reg) = 1;
if (MipsRegToLoad > 0) {
if (IsUnknown(MipsRegToLoad)) {
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0],CRegName::GPR_Lo[MipsRegToLoad],Reg);
} else if (IsMapped(MipsRegToLoad)) {
if (MipsReg != MipsRegToLoad) {
MoveX86RegToX86Reg(MipsRegMapLo(MipsRegToLoad),Reg);
}
} else {
MoveConstToX86reg(MipsRegLo(MipsRegToLoad),Reg);
}
} else if (MipsRegToLoad == 0) {
XorX86RegToX86Reg(Reg,Reg);
}
x86Mapped(Reg) = CRegInfo::GPR_Mapped;
x86Protected(Reg) = TRUE;
MipsRegMapLo(MipsReg) = Reg;
MipsRegState(MipsReg) = SignValue ? CRegInfo::STATE_MAPPED_32_SIGN : CRegInfo::STATE_MAPPED_32_ZERO;
}
void CRegInfo::Map_GPR_64bit ( int MipsReg, int MipsRegToLoad)
{
x86Reg x86Hi, x86lo;
int count;
if (MipsReg == 0) {
#ifndef EXTERNAL_RELEASE
DisplayError("Map_GPR_32bit\n\nWhy are you trying to map reg 0");
#endif
return;
}
ProtectGPR(MipsReg);
if (IsUnknown(MipsReg) || IsConst(MipsReg)) {
x86Hi = FreeX86Reg();
if (x86Hi < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
x86Protected(x86Hi) = TRUE;
x86lo = FreeX86Reg();
if (x86lo < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
x86Protected(x86lo) = TRUE;
CPU_Message(" regcache: allocate %s to hi word of %s",x86_Name(x86Hi),CRegName::GPR[MipsReg]);
CPU_Message(" regcache: allocate %s to low word of %s",x86_Name(x86lo),CRegName::GPR[MipsReg]);
} else {
x86lo = MipsRegMapLo(MipsReg);
if (Is32Bit(MipsReg)) {
x86Protected(x86lo) = TRUE;
x86Hi = FreeX86Reg();
if (x86Hi < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
x86Protected(x86Hi) = TRUE;
} else {
x86Hi = MipsRegMapHi(MipsReg);
}
}
for (count = 0; count < 10; count ++) {
if (x86MapOrder(count) > 0) { x86MapOrder(count) += 1; }
}
x86MapOrder(x86Hi) = 1;
x86MapOrder(x86lo) = 1;
if (MipsRegToLoad > 0) {
if (IsUnknown(MipsRegToLoad)) {
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[1],CRegName::GPR_Hi[MipsRegToLoad],x86Hi);
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0],CRegName::GPR_Lo[MipsRegToLoad],x86lo);
} else if (IsMapped(MipsRegToLoad)) {
if (Is32Bit(MipsRegToLoad)) {
if (IsSigned(MipsRegToLoad)) {
MoveX86RegToX86Reg(MipsRegMapLo(MipsRegToLoad),x86Hi);
ShiftRightSignImmed(x86Hi,31);
} else {
XorX86RegToX86Reg(x86Hi,x86Hi);
}
if (MipsReg != MipsRegToLoad) {
MoveX86RegToX86Reg(MipsRegMapLo(MipsRegToLoad),x86lo);
}
} else {
if (MipsReg != MipsRegToLoad) {
MoveX86RegToX86Reg(MipsRegMapHi(MipsRegToLoad),x86Hi);
MoveX86RegToX86Reg(MipsRegMapLo(MipsRegToLoad),x86lo);
}
}
} else {
CPU_Message("Map_GPR_64bit 11");
if (Is32Bit(MipsRegToLoad)) {
if (IsSigned(MipsRegToLoad)) {
MoveConstToX86reg((int)MipsRegLo(MipsRegToLoad) >> 31,x86Hi);
} else {
MoveConstToX86reg(0,x86Hi);
}
} else {
MoveConstToX86reg(MipsRegHi(MipsRegToLoad),x86Hi);
}
MoveConstToX86reg(MipsRegLo(MipsRegToLoad),x86lo);
}
} else if (MipsRegToLoad == 0) {
XorX86RegToX86Reg(x86Hi,x86Hi);
XorX86RegToX86Reg(x86lo,x86lo);
}
x86Mapped(x86Hi) = CRegInfo::GPR_Mapped;
x86Mapped(x86lo) = CRegInfo::GPR_Mapped;
MipsRegMapHi(MipsReg) = x86Hi;
MipsRegMapLo(MipsReg) = x86lo;
MipsRegState(MipsReg) = CRegInfo::STATE_MAPPED_64;
}
CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL LoadHiWord)
{
int count;
if (Reg == x86_Any)
{
if (x86Mapped(x86_EAX) == Temp_Mapped && !x86Protected(x86_EAX)) { Reg = x86_EAX; }
else if (x86Mapped(x86_EBX) == Temp_Mapped && !x86Protected(x86_EBX)) { Reg = x86_EBX; }
else if (x86Mapped(x86_ECX) == Temp_Mapped && !x86Protected(x86_ECX)) { Reg = x86_ECX; }
else if (x86Mapped(x86_EDX) == Temp_Mapped && !x86Protected(x86_EDX)) { Reg = x86_EDX; }
else if (x86Mapped(x86_ESI) == Temp_Mapped && !x86Protected(x86_ESI)) { Reg = x86_ESI; }
else if (x86Mapped(x86_EDI) == Temp_Mapped && !x86Protected(x86_EDI)) { Reg = x86_EDI; }
else if (x86Mapped(x86_EBP) == Temp_Mapped && !x86Protected(x86_EBP)) { Reg = x86_EBP; }
else if (x86Mapped(x86_ESP) == Temp_Mapped && !x86Protected(x86_ESP)) { Reg = x86_ESP; }
if (Reg == x86_Any) {
Reg = FreeX86Reg();
if (Reg == x86_Unknown)
{
WriteTrace(TraceError,"CRegInfo::Map_TempReg: Failed to find a free register");
_Notify->BreakPoint(__FILE__,__LINE__);
return x86_Unknown;
}
CPU_Message(" regcache: allocate %s as temp storage",x86_Name(Reg));
}
}
else if (Reg == x86_Any8Bit)
{
if (x86Mapped(x86_EAX) == Temp_Mapped && !x86Protected(x86_EAX)) { Reg = x86_EAX; }
else if (x86Mapped(x86_EBX) == Temp_Mapped && !x86Protected(x86_EBX)) { Reg = x86_EBX; }
else if (x86Mapped(x86_ECX) == Temp_Mapped && !x86Protected(x86_ECX)) { Reg = x86_ECX; }
else if (x86Mapped(x86_EDX) == Temp_Mapped && !x86Protected(x86_EDX)) { Reg = x86_EDX; }
if (Reg == x86_Any8Bit)
{
Reg = Free8BitX86Reg();
if (Reg < 0) {
WriteTrace(TraceError,"CRegInfo::Map_TempReg: Failed to find a free 8 bit register");
_Notify->BreakPoint(__FILE__,__LINE__);
return x86_Unknown;
}
}
} else if (x86Mapped(Reg) == GPR_Mapped) {
if (x86Protected(Reg))
{
WriteTrace(TraceError,"CRegInfo::Map_TempReg: Register is protected");
_Notify->BreakPoint(__FILE__,__LINE__);
return x86_Unknown;
}
x86Protected(Reg) = true;
x86Reg NewReg = FreeX86Reg();
for (count = 1; count < 32; count ++)
{
if (!IsMapped(count))
{
continue;
}
if (cMipsRegMapLo(count) == Reg)
{
if (NewReg == x86_Unknown)
{
UnMap_GPR(count,TRUE);
break;
}
CPU_Message(" regcache: change allocation of %s from %s to %s",CRegName::GPR[count],x86_Name(Reg),x86_Name(NewReg));
x86Mapped(NewReg) = GPR_Mapped;
x86MapOrder(NewReg) = x86MapOrder(Reg);
MipsRegMapLo(count) = NewReg;
MoveX86RegToX86Reg(Reg,NewReg);
if (MipsReg == count && LoadHiWord == FALSE) { MipsReg = -1; }
break;
}
if (Is64Bit(count) && cMipsRegMapHi(count) == Reg)
{
if (NewReg == x86_Unknown)
{
UnMap_GPR(count,TRUE);
break;
}
CPU_Message(" regcache: change allocation of %s from %s to %s",CRegName::GPR_Hi[count],x86_Name(Reg),x86_Name(NewReg));
x86Mapped(NewReg) = GPR_Mapped;
x86MapOrder(NewReg) = x86MapOrder(Reg);
MipsRegMapHi(count) = NewReg;
MoveX86RegToX86Reg(Reg,NewReg);
if (MipsReg == count && LoadHiWord == TRUE) { MipsReg = -1; }
break;
}
}
}
else if (x86Mapped(Reg) == Stack_Mapped)
{
UnMap_X86reg(Reg);
}
CPU_Message(" regcache: allocate %s as temp storage",x86_Name(Reg));
if (MipsReg >= 0) {
if (LoadHiWord) {
if (IsUnknown(MipsReg))
{
MoveVariableToX86reg(&_GPR[MipsReg].UW[1],CRegName::GPR_Hi[MipsReg],Reg);
}
else if (IsMapped(MipsReg))
{
if (Is64Bit(MipsReg)) {
MoveX86RegToX86Reg(cMipsRegMapHi(MipsReg),Reg);
} else if (IsSigned(MipsReg)){
MoveX86RegToX86Reg(cMipsRegMapLo(MipsReg),Reg);
ShiftRightSignImmed(Reg,31);
} else {
MoveConstToX86reg(0,Reg);
}
} else {
if (Is64Bit(MipsReg))
{
MoveConstToX86reg(MipsRegHi(MipsReg),Reg);
} else {
MoveConstToX86reg((int)MipsRegLo(MipsReg) >> 31,Reg);
}
}
} else {
if (IsUnknown(MipsReg)) {
MoveVariableToX86reg(&_GPR[MipsReg].UW[0],CRegName::GPR_Lo[MipsReg],Reg);
} else if (IsMapped(MipsReg)) {
MoveX86RegToX86Reg(MipsRegMapLo(MipsReg),Reg);
} else {
MoveConstToX86reg(MipsRegMapLo(MipsReg),Reg);
}
}
}
x86Mapped(Reg) = Temp_Mapped;
x86Protected(Reg) = TRUE;
for (count = 0; count < 10; count ++) {
if (x86MapOrder(count) > 0) {
x86MapOrder(count) += 1;
}
}
x86MapOrder(Reg) = 1;
return Reg;
}
void CRegInfo::ProtectGPR(DWORD Reg) {
if (IsUnknown(Reg)) { return; }
if (IsConst(Reg)) { return; }
if (Is64Bit(Reg)) {
x86Protected(MipsRegMapHi(Reg)) = TRUE;
}
x86Protected(MipsRegMapLo(Reg)) = TRUE;
}
void CRegInfo::ResetX86Protection (void)
{
for (int count = 1; count < 10; count ++)
{
x86Protected(count) = false;
}
}
void CRegInfo::UnMap_AllFPRs ( void )
{
DWORD StackPos;
for (;;) {
int i, StartPos;
StackPos = StackTopPos();
if (FpuMappedTo(StackTopPos()) != -1 ) {
UnMap_FPR(FpuMappedTo(StackTopPos()),TRUE);
continue;
}
//see if any more registers mapped
StartPos = StackTopPos();
for (i = 0; i < 8; i++) {
if (FpuMappedTo((StartPos + i) & 7) != -1 ) { fpuIncStack(&StackTopPos()); }
}
if (StackPos != StackTopPos()) { continue; }
return;
}
}
void CRegInfo::UnMap_FPR (int Reg, int WriteBackValue )
{
char Name[50];
int i;
if (Reg < 0) { return; }
for (i = 0; i < 8; i++) {
if (FpuMappedTo(i) != (DWORD)Reg) { continue; }
CPU_Message(" regcache: unallocate %s from ST(%d)",CRegName::FPR[Reg],(i - StackTopPos() + 8) & 7);
if (WriteBackValue) {
int RegPos;
if (((i - StackTopPos() + 8) & 7) != 0) {
CRegInfo::FPU_ROUND RoundingModel = FpuRoundingModel(StackTopPos());
CRegInfo::FPU_STATE RegState = FpuState(StackTopPos());
DWORD MappedTo = FpuMappedTo(StackTopPos());
FpuRoundingModel(StackTopPos()) = FpuRoundingModel(i);
FpuMappedTo(StackTopPos()) = FpuMappedTo(i);
FpuState(StackTopPos()) = FpuState(i);
FpuRoundingModel(i) = RoundingModel;
FpuMappedTo(i) = MappedTo;
FpuState(i) = RegState;
fpuExchange((x86FpuValues)((i - StackTopPos()) & 7));
}
CPU_Message("CurrentRoundingModel: %d FpuRoundingModel(i): %d",
CurrentRoundingModel(),FpuRoundingModel(i));
FixRoundModel(FpuRoundingModel(i));
RegPos = StackTopPos();
x86Reg TempReg = Map_TempReg(x86_Any,-1,FALSE);
switch (FpuState(StackTopPos())) {
case CRegInfo::FPU_Dword:
sprintf(Name,"_FPRFloatLocation[%d]",FpuMappedTo(StackTopPos()));
MoveVariableToX86reg(&_FPRFloatLocation[FpuMappedTo(StackTopPos())],Name,TempReg);
fpuStoreIntegerDwordFromX86Reg(&StackTopPos(),TempReg, TRUE);
break;
case CRegInfo::FPU_Qword:
sprintf(Name,"_FPRDoubleLocation[%d]",FpuMappedTo(StackTopPos()));
MoveVariableToX86reg(&_FPRDoubleLocation[FpuMappedTo(StackTopPos())],Name,TempReg);
fpuStoreIntegerQwordFromX86Reg(&StackTopPos(),TempReg, TRUE);
break;
case CRegInfo::FPU_Float:
sprintf(Name,"_FPRFloatLocation[%d]",FpuMappedTo(StackTopPos()));
MoveVariableToX86reg(&_FPRFloatLocation[FpuMappedTo(StackTopPos())],Name,TempReg);
fpuStoreDwordFromX86Reg(&StackTopPos(),TempReg, TRUE);
break;
case CRegInfo::FPU_Double:
sprintf(Name,"_FPRDoubleLocation[%d]",FpuMappedTo(StackTopPos()));
MoveVariableToX86reg(&_FPRDoubleLocation[FpuMappedTo(StackTopPos())],Name,TempReg);
fpuStoreQwordFromX86Reg(&StackTopPos(),TempReg, TRUE);
break;
#ifndef EXTERNAL_RELEASE
default:
DisplayError("UnMap_FPR\nUnknown format to load %d",FpuState(StackTopPos()));
#endif
}
x86Protected(TempReg) = FALSE;
FpuRoundingModel(RegPos) = CRegInfo::RoundDefault;
FpuMappedTo(RegPos) = -1;
FpuState(RegPos) = CRegInfo::FPU_Unkown;
} else {
fpuFree((x86FpuValues)((i - StackTopPos()) & 7));
FpuRoundingModel(i) = CRegInfo::RoundDefault;
FpuMappedTo(i) = -1;
FpuState(i) = CRegInfo::FPU_Unkown;
}
return;
}
}
void CRegInfo::UnMap_GPR (DWORD Reg, bool WriteBackValue)
{
if (Reg == 0) {
#ifndef EXTERNAL_RELEASE
DisplayError("UnMap_GPR\n\nWhy are you trying to unmap reg 0");
#endif
return;
}
if (IsUnknown(Reg)) { return; }
//CPU_Message("UnMap_GPR: State: %X\tReg: %s\tWriteBack: %s",State,CRegName::GPR[Reg],WriteBackValue?"TRUE":"FALSE");
if (IsConst(Reg)) {
if (!WriteBackValue) {
MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
return;
}
if (Is64Bit(Reg)) {
MoveConstToVariable(MipsRegHi(Reg),&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
MoveConstToVariable(MipsRegLo(Reg),&_GPR[Reg].UW[0],CRegName::GPR_Lo[Reg]);
MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
return;
}
if ((MipsRegLo(Reg) & 0x80000000) != 0) {
MoveConstToVariable(0xFFFFFFFF,&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
} else {
MoveConstToVariable(0,&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
}
MoveConstToVariable(MipsRegLo(Reg),&_GPR[Reg].UW[0],CRegName::GPR_Lo[Reg]);
MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
return;
}
if (Is64Bit(Reg)) {
CPU_Message(" regcache: unallocate %s from %s",x86_Name(MipsRegMapHi(Reg)),CRegName::GPR_Hi[Reg]);
x86Mapped(MipsRegHi(Reg)) = NotMapped;
x86Protected(MipsRegHi(Reg)) = FALSE;
}
CPU_Message(" regcache: unallocate %s from %s",x86_Name(MipsRegMapLo(Reg)),CRegName::GPR_Lo[Reg]);
x86Mapped(MipsRegLo(Reg)) = NotMapped;
x86Protected(MipsRegLo(Reg)) = FALSE;
if (!WriteBackValue) {
MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
return;
}
MoveX86regToVariable(MipsRegMapLo(Reg),&_GPR[Reg].UW[0],CRegName::GPR_Lo[Reg]);
if (Is64Bit(Reg)) {
MoveX86regToVariable(MipsRegMapHi(Reg),&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
} else {
if (IsSigned(Reg)) {
ShiftRightSignImmed(MipsRegMapLo(Reg),31);
MoveX86regToVariable(MipsRegMapLo(Reg),&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
} else {
MoveConstToVariable(0,&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
}
}
MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
}
CX86Ops::x86Reg CRegInfo::UnMap_TempReg ( void )
{
CX86Ops::x86Reg Reg = x86_Unknown;
if (x86Mapped(x86_EAX) == Temp_Mapped && !x86Protected(x86_EAX)) { Reg = x86_EAX; }
else if (x86Mapped(x86_EBX) == Temp_Mapped && !x86Protected(x86_EBX)) { Reg = x86_EBX; }
else if (x86Mapped(x86_ECX) == Temp_Mapped && !x86Protected(x86_ECX)) { Reg = x86_ECX; }
else if (x86Mapped(x86_EDX) == Temp_Mapped && !x86Protected(x86_EDX)) { Reg = x86_EDX; }
else if (x86Mapped(x86_ESI) == Temp_Mapped && !x86Protected(x86_ESI)) { Reg = x86_ESI; }
else if (x86Mapped(x86_EDI) == Temp_Mapped && !x86Protected(x86_EDI)) { Reg = x86_EDI; }
else if (x86Mapped(x86_EBP) == Temp_Mapped && !x86Protected(x86_EBP)) { Reg = x86_EBP; }
else if (x86Mapped(x86_ESP) == Temp_Mapped && !x86Protected(x86_ESP)) { Reg = x86_ESP; }
if (Reg != x86_Unknown)
{
CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(Reg));
x86Mapped(Reg) = NotMapped;
}
return Reg;
}
bool CRegInfo::UnMap_X86reg ( CX86Ops::x86Reg Reg )
{
int count;
if (x86Mapped(Reg) == NotMapped && x86Protected(Reg) == FALSE) { return TRUE; }
if (x86Mapped(Reg) == CRegInfo::Temp_Mapped) {
if (x86Protected(Reg) == FALSE) {
CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(Reg));
x86Mapped(Reg) = NotMapped;
return TRUE;
}
return FALSE;
}
for (count = 1; count < 32; count ++)
{
if (!IsMapped(count))
{
continue;
}
if (Is64Bit(count) && MipsRegMapHi(count) == Reg)
{
if (x86Protected(Reg) == FALSE)
{
UnMap_GPR(count,TRUE);
return TRUE;
}
break;
}
if (MipsRegMapLo(count) == Reg)
{
if (x86Protected(Reg) == FALSE)
{
UnMap_GPR(count,TRUE);
return TRUE;
}
break;
}
}
if (x86Mapped(Reg) == CRegInfo::Stack_Mapped) {
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
CPU_Message(" regcache: unallocate %s from Memory Stack",x86_Name(Reg));
MoveX86regToVariable(Reg,g_MemoryStack,"MemoryStack");
x86Mapped(Reg) = NotMapped;
return TRUE;
#endif
}
return FALSE;
}
void CRegInfo::WriteBackRegisters (void)
{
int count;
BOOL bEdiZero = FALSE;
BOOL bEsiSign = FALSE;
/*** coming soon ***/
BOOL bEaxGprLo = FALSE;
BOOL bEbxGprHi = FALSE;
for (count = 1; count < 10; count ++) { x86Protected(count) = FALSE; }
for (count = 1; count < 10; count ++) { UnMap_X86reg ((CX86Ops::x86Reg)count); }
/*************************************/
for (count = 1; count < 32; count ++) {
switch (MipsRegState(count)) {
case CRegInfo::STATE_UNKNOWN: break;
case CRegInfo::STATE_CONST_32:
if (!bEdiZero && (!MipsRegLo(count) || !(MipsRegLo(count) & 0x80000000))) {
XorX86RegToX86Reg(x86_EDI, x86_EDI);
bEdiZero = TRUE;
}
if (!bEsiSign && (MipsRegLo(count) & 0x80000000)) {
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
bEsiSign = TRUE;
}
if ((MipsRegLo(count) & 0x80000000) != 0) {
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
} else {
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
}
if (MipsRegLo(count) == 0) {
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
} else if (MipsRegLo(count) == 0xFFFFFFFF) {
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
} else
MoveConstToVariable(MipsRegLo(count),&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
MipsRegState(count) = CRegInfo::STATE_UNKNOWN;
break;
case CRegInfo::STATE_CONST_64:
if (MipsRegLo(count) == 0 || MipsRegHi(count) == 0) {
XorX86RegToX86Reg(x86_EDI, x86_EDI);
bEdiZero = TRUE;
}
if (MipsRegLo(count) == 0xFFFFFFFF || MipsRegHi(count) == 0xFFFFFFFF) {
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
bEsiSign = TRUE;
}
if (MipsRegHi(count) == 0) {
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
} else if (MipsRegLo(count) == 0xFFFFFFFF) {
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
} else {
MoveConstToVariable(MipsRegHi(count),&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
}
if (MipsRegLo(count) == 0) {
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
} else if (MipsRegLo(count) == 0xFFFFFFFF) {
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
} else {
MoveConstToVariable(MipsRegLo(count),&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
}
MipsRegState(count) = CRegInfo::STATE_UNKNOWN;
break;
#ifndef EXTERNAL_RELEASE
default:
DisplayError("Unknown State: %d\nin WriteBackRegisters",MipsRegState(count));
#endif
}
}
UnMap_AllFPRs();
}

View File

@ -0,0 +1,132 @@
class CRegInfo :
private CX86Ops
{
public:
//enums
enum REG_STATE {
STATE_UNKNOWN = 0,
STATE_KNOWN_VALUE = 1,
STATE_X86_MAPPED = 2,
STATE_SIGN = 4,
STATE_32BIT = 8,
STATE_MAPPED_64 = (STATE_KNOWN_VALUE | STATE_X86_MAPPED), // = 3
STATE_MAPPED_32_ZERO = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT), // = 11
STATE_MAPPED_32_SIGN = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT | STATE_SIGN), // = 15
STATE_CONST_32 = (STATE_KNOWN_VALUE | STATE_32BIT | STATE_SIGN), // = 13
STATE_CONST_64 = (STATE_KNOWN_VALUE), // = 1
};
enum REG_MAPPED {
NotMapped = 0,
GPR_Mapped = 1,
Temp_Mapped = 2,
Stack_Mapped = 3,
};
enum FPU_STATE {
FPU_Unkown,FPU_Dword, FPU_Qword, FPU_Float, FPU_Double
};
enum FPU_ROUND {
RoundUnknown, RoundDefault, RoundTruncate, RoundNearest, RoundDown, RoundUp
};
public:
bool operator==(const CRegInfo& right) const;
bool operator!=(const CRegInfo& right) const;
static REG_STATE ConstantsType ( __int64 Value );
void Initilize ( void );
void FixRoundModel ( FPU_ROUND RoundMethod );
x86Reg FreeX86Reg ( void );
x86Reg Free8BitX86Reg ( void );
void Map_GPR_32bit ( int MipsReg, BOOL SignValue, int MipsRegToLoad );
void Map_GPR_64bit ( int MipsReg, int MipsRegToLoad );
x86Reg Map_TempReg ( x86Reg Reg, int MipsReg, BOOL LoadHiWord );
void ProtectGPR ( DWORD Reg );
void ResetX86Protection ( void );
void UnMap_AllFPRs ( void );
void UnMap_FPR ( int Reg, int WriteBackValue );
x86Reg UnMap_TempReg ( void );
void UnMap_GPR ( DWORD Reg, bool WriteBackValue );
bool UnMap_X86reg ( x86Reg Reg );
void WriteBackRegisters ( void );
inline bool IsKnown(int Reg) const { return ((cMipsRegState(Reg) & STATE_KNOWN_VALUE) != 0); }
inline bool IsUnknown(int Reg) const { return ((cMipsRegState(Reg) & STATE_KNOWN_VALUE) == 0); }
inline bool IsMapped(int Reg) const { return ((cMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_X86_MAPPED)); }
inline bool IsConst(int Reg) const { return ((cMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_X86_MAPPED)) == STATE_KNOWN_VALUE); }
inline bool IsSigned(int Reg) const { return ((cMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_SIGN)) == (STATE_KNOWN_VALUE | STATE_SIGN)); }
inline bool IsUnsigned(int Reg) const { return ((cMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_SIGN)) == STATE_KNOWN_VALUE); }
inline bool Is32Bit(int Reg) const { return ((cMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT)) == (STATE_KNOWN_VALUE | STATE_32BIT)); }
inline bool Is64Bit(int Reg) const { return ((cMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT)) == STATE_KNOWN_VALUE); }
inline bool Is32BitMapped(int Reg) const { return ((cMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)); }
inline bool Is64BitMapped(int Reg) const { return ((cMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_X86_MAPPED)); }
inline REG_STATE cMipsRegState ( int Reg ) const { return MIPS_RegState[Reg]; }
inline unsigned _int64 cMipsReg ( int Reg ) const { return MIPS_RegVal[Reg].UDW; }
inline _int64 cMipsReg_S ( int Reg ) const { return MIPS_RegVal[Reg].DW; }
inline DWORD cMipsRegLo ( int Reg ) const { return MIPS_RegVal[Reg].UW[0]; }
inline long cMipsRegLo_S ( int Reg ) const { return MIPS_RegVal[Reg].W[0]; }
inline DWORD cMipsRegHi ( int Reg ) const { return MIPS_RegVal[Reg].UW[1]; }
inline long cMipsRegHi_S ( int Reg ) const { return MIPS_RegVal[Reg].W[1]; }
inline CX86Ops::x86Reg cMipsRegMapLo ( int Reg ) const { return RegMapLo[Reg]; }
inline CX86Ops::x86Reg cMipsRegMapHi ( int Reg ) const { return RegMapHi[Reg]; }
inline REG_STATE & MipsRegState ( int Reg ) { return MIPS_RegState[Reg]; }
inline unsigned _int64 & MipsReg ( int Reg ) { return MIPS_RegVal[Reg].UDW; }
inline _int64 & MipsReg_S ( int Reg ) { return MIPS_RegVal[Reg].DW; }
inline DWORD & MipsRegLo ( int Reg ) { return MIPS_RegVal[Reg].UW[0]; }
inline long & MipsRegLo_S ( int Reg ) { return MIPS_RegVal[Reg].W[0]; }
inline DWORD & MipsRegHi ( int Reg ) { return MIPS_RegVal[Reg].UW[1]; }
inline long & MipsRegHi_S ( int Reg ) { return MIPS_RegVal[Reg].W[1]; }
inline CX86Ops::x86Reg & MipsRegMapLo ( int Reg ) { return RegMapLo[Reg]; }
inline CX86Ops::x86Reg & MipsRegMapHi ( int Reg ) { return RegMapHi[Reg]; }
inline DWORD & x86MapOrder( int Reg ) { return x86reg_MapOrder[Reg]; }
inline bool & x86Protected( int Reg ) { return x86reg_Protected[Reg]; }
inline REG_MAPPED & x86Mapped(int Reg) { return x86reg_MappedTo[Reg]; }
inline DWORD GetBlockCycleCount ( void ) const { return m_CycleCount; }
inline void SetBlockCycleCount ( DWORD CyleCount ) { m_CycleCount = CyleCount; }
inline int & StackTopPos ( void ) { return Stack_TopPos; }
inline DWORD & FpuMappedTo( int Reg) { return x86fpu_MappedTo[Reg]; }
inline FPU_STATE & FpuState(int Reg) { return x86fpu_State[Reg]; }
inline FPU_ROUND & FpuRoundingModel(int Reg) { return x86fpu_RoundingModel[Reg]; }
inline bool & FpuBeenUsed (void ) { return Fpu_Used; }
inline FPU_ROUND & CurrentRoundingModel ( void ) { return RoundingModel; }
private:
//r4k
REG_STATE MIPS_RegState[32];
MIPS_DWORD MIPS_RegVal[32];
x86Reg RegMapHi[32];
x86Reg RegMapLo[32];
REG_MAPPED x86reg_MappedTo[10];
DWORD x86reg_MapOrder[10];
bool x86reg_Protected[10];
DWORD m_CycleCount;
//FPU
int Stack_TopPos;
DWORD x86fpu_MappedTo[8];
FPU_STATE x86fpu_State[8];
FPU_ROUND x86fpu_RoundingModel[8];
bool Fpu_Used;
FPU_ROUND RoundingModel;
bool compare(const CRegInfo& right) const;
static unsigned int m_fpuControl;
};

View File

@ -1,20 +1,17 @@
#include "..\..\N64 System.h"
#pragma warning(disable:4355) // Disable 'this' : used in base member initializer list
#include "stdafx.h"
CBlockInfo::CBlockInfo(DWORD VAddr, BYTE * RecompPos) :
StartVAddr(VAddr),
EndVAddr(VAddr),
CompiledLocation(RecompPos),
NoOfSections(1),
ParentSection(this, VAddr,1)
CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos) :
m_VAddrEnter(VAddrEnter),
m_VAddrFirst(VAddrEnter),
m_VAddrLast(VAddrEnter),
m_CompiledLocation(RecompPos),
m_NoOfSections(1),
m_EnterSection(this, VAddrEnter, 1)
{
ParentSection.AddParent(NULL);
ParentSection.LinkAllowed = false;
AnalyseBlock();
}
void CBlockInfo::AnalyseBlock ( void )
void CCodeBlock::AnalyseBlock ( void )
{
/*if (bLinkBlocks())
{
@ -26,6 +23,39 @@ void CBlockInfo::AnalyseBlock ( void )
return true;*/
}
bool CCodeBlock::Compile()
{
CPU_Message("====== Code Block ======");
CPU_Message("x86 code at: %X",CompiledLocation());
CPU_Message("Start of Block: %X",VAddrEnter() );
CPU_Message("No of Sections: %d",NoOfSections() );
CPU_Message("====== recompiled code ======");
#ifdef tofix
if (bLinkBlocks()) {
for (int count = 0; count < BlockInfo.NoOfSections; count ++) {
DisplaySectionInformation(&BlockInfo.ParentSection,count + 1,CBlockSection::GetNewTestValue());
}
}
if (m_SyncSystem) {
//if ((DWORD)BlockInfo.CompiledLocation == 0x60A7B73B) { X86BreakPoint(__FILE__,__LINE__); }
//MoveConstToVariable((DWORD)BlockInfo.CompiledLocation,&CurrentBlock,"CurrentBlock");
}
#endif
#ifdef tofix
if (bLinkBlocks()) {
while (GenerateX86Code(BlockInfo,&BlockInfo.ParentSection,CBlockSection::GetNewTestValue()));
} else {
#endif
m_EnterSection.GenerateX86Code(m_EnterSection.m_Test + 1);
#ifdef tofix
}
CompileExitCode(BlockInfo);
#endif
return false;
}
CJumpInfo::CJumpInfo()
{
TargetPC = (DWORD)-1;
@ -37,23 +67,7 @@ CJumpInfo::CJumpInfo()
DoneDelaySlot = false;
}
CCodeSection::CCodeSection( CBlockInfo * _BlockInfo, DWORD StartAddr, DWORD ID) :
BlockInfo(_BlockInfo)
{
JumpSection = NULL;
ContinueSection = NULL;
CompiledLocation = NULL;
SectionID = ID;
Test = 0;
Test2 = 0;
InLoop = false;
LinkAllowed = true;
DelaySlotSection = false;
StartPC = StartAddr;
m_CompilePC = StartAddr;
}
#ifdef tofix
bool CCodeSection::IsAllParentLoops(CCodeSection * Parent, bool IgnoreIfCompiled, DWORD Test)
{
@ -234,14 +248,6 @@ void CCodeSection::AddParent(CCodeSection * Parent )
}
}
void CCodeSection::ResetX86Protection (void)
{
for (int count = 1; count < 10; count ++)
{
RegWorking.x86Protected(count) = false;
}
}
void CRegInfo::Initilize ( void )
{
int count;
@ -271,6 +277,8 @@ void CRegInfo::Initilize ( void )
RoundingModel = RoundUnknown;
}
#endif
CRegInfo::REG_STATE CRegInfo::ConstantsType (__int64 Value)
{
if (((Value >> 32) == -1) && ((Value & 0x80000000) != 0)) { return STATE_CONST_32; }
@ -301,8 +309,7 @@ bool CRegInfo::compare(const CRegInfo& right) const
if (x86reg_Protected[count] != right.x86reg_Protected[count]) { return false; }
if (x86reg_MapOrder[count] != right.x86reg_MapOrder[count]) { return false; }
}
if (CycleCount != right.CycleCount) { return false; }
if (RandomModifier != right.RandomModifier) { return false; }
if (m_CycleCount != right.m_CycleCount) { return false; }
if (Stack_TopPos != right.Stack_TopPos) { return false; }
for (count = 0; count < 8; count ++ ) {
@ -319,3 +326,5 @@ bool CRegInfo::operator!=(const CRegInfo& right) const
{
return !compare(right);
}

View File

@ -1,248 +1,9 @@
class CCodeSection;
typedef std::list<CCodeSection *> SECTION_LIST;
class CRegInfo
{
public:
//enums
enum REG_STATE {
STATE_UNKNOWN = 0,
STATE_KNOWN_VALUE = 1,
STATE_X86_MAPPED = 2,
STATE_SIGN = 4,
STATE_32BIT = 8,
STATE_MAPPED_64 = (STATE_KNOWN_VALUE | STATE_X86_MAPPED), // = 3
STATE_MAPPED_32_ZERO = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT), // = 11
STATE_MAPPED_32_SIGN = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT | STATE_SIGN), // = 15
class CCodeBlock;
STATE_CONST_32 = (STATE_KNOWN_VALUE | STATE_32BIT | STATE_SIGN), // = 13
STATE_CONST_64 = (STATE_KNOWN_VALUE), // = 1
};
enum REG_MAPPED {
NotMapped = 0,
GPR_Mapped = 1,
Temp_Mapped = 2,
Stack_Mapped = 3,
};
enum FPU_STATE {
FPU_Unkown,FPU_Dword, FPU_Qword, FPU_Float, FPU_Double
};
enum FPU_ROUND {
RoundUnknown, RoundDefault, RoundTruncate, RoundNearest, RoundDown, RoundUp
};
private:
//r4k
REG_STATE MIPS_RegState[32];
MIPS_DWORD MIPS_RegVal[32];
REG_MAPPED x86reg_MappedTo[10];
DWORD x86reg_MapOrder[10];
bool x86reg_Protected[10];
DWORD CycleCount;
DWORD RandomModifier;
//FPU
int Stack_TopPos;
DWORD x86fpu_MappedTo[8];
FPU_STATE x86fpu_State[8];
FPU_ROUND x86fpu_RoundingModel[8];
bool Fpu_Used;
FPU_ROUND RoundingModel;
bool compare(const CRegInfo& right) const;
public:
bool operator==(const CRegInfo& right) const;
bool operator!=(const CRegInfo& right) const;
static REG_STATE ConstantsType ( __int64 Value );
void Initilize ( void );
inline bool IsKnown(int Reg) { return ((MipsRegState(Reg) & STATE_KNOWN_VALUE) != 0); }
inline bool IsUnknown(int Reg) { return (!IsKnown(Reg)); }
inline bool IsMapped(int Reg) { return (IsKnown(Reg) && (MipsRegState(Reg) & STATE_X86_MAPPED) != 0); }
inline bool IsConst(int Reg) { return (IsKnown(Reg) && !IsMapped(Reg)); }
inline bool IsSigned(int Reg) { return (IsKnown(Reg) && (MipsRegState(Reg) & STATE_SIGN) != 0); }
inline bool IsUnsigned(int Reg) { return (IsKnown(Reg) && !IsSigned(Reg)); }
inline bool Is32Bit(int Reg) { return (IsKnown(Reg) && (MipsRegState(Reg) & STATE_32BIT) != 0); }
inline bool Is64Bit(int Reg) { return (IsKnown(Reg) && !Is32Bit(Reg)); }
inline bool Is32BitMapped(int Reg) { return (Is32Bit(Reg) && (MipsRegState(Reg) & STATE_X86_MAPPED) != 0); }
inline bool Is64BitMapped(int Reg) { return (Is64Bit(Reg) && !Is32BitMapped(Reg)); }
inline REG_STATE & MipsRegState ( int Reg ) { return MIPS_RegState[Reg]; }
inline unsigned _int64 & MipsReg ( int Reg ) { return MIPS_RegVal[Reg].UDW; }
inline _int64 & MipsReg_S ( int Reg ) { return MIPS_RegVal[Reg].DW; }
inline DWORD & MipsRegLo ( int Reg ) { return MIPS_RegVal[Reg].UW[0]; }
inline long & MipsRegLo_S ( int Reg ) { return MIPS_RegVal[Reg].W[0]; }
inline DWORD & MipsRegHi ( int Reg ) { return MIPS_RegVal[Reg].UW[1]; }
inline long & MipsRegHi_S ( int Reg ) { return MIPS_RegVal[Reg].W[1]; }
inline DWORD & x86MapOrder( int Reg ) { return x86reg_MapOrder[Reg]; }
inline bool & x86Protected( int Reg ) { return x86reg_Protected[Reg]; }
inline REG_MAPPED & x86Mapped(int Reg) { return x86reg_MappedTo[Reg]; }
inline DWORD & BlockCycleCount(void) { return CycleCount; }
inline DWORD & BlockRandomModifier(void) { return RandomModifier; }
inline int & StackTopPos ( void ) { return Stack_TopPos; }
inline DWORD & FpuMappedTo( int Reg) { return x86fpu_MappedTo[Reg]; }
inline FPU_STATE & FpuState(int Reg) { return x86fpu_State[Reg]; }
inline FPU_ROUND & FpuRoundingModel(int Reg) { return x86fpu_RoundingModel[Reg]; }
inline bool & FpuBeenUsed (void ) { return Fpu_Used; }
inline FPU_ROUND & CurrentRoundingModel ( void ) { return RoundingModel; }
};
class CJumpInfo
{
public:
CJumpInfo();
DWORD TargetPC;
char * BranchLabel;
BYTE * LinkLocation;
BYTE * LinkLocation2;
BOOL FallThrough;
BOOL PermLoop;
BOOL DoneDelaySlot;
CRegInfo RegSet;
};
class CBlockInfo;
class CCodeSection
{
public:
CCodeSection( CBlockInfo * _BlockInfo, DWORD StartAddr, DWORD ID);
~CCodeSection( void );
CBlockInfo * const BlockInfo;
/* Block Connection info */
SECTION_LIST ParentSection;
CCodeSection * ContinueSection;
CCodeSection * JumpSection;
BYTE * CompiledLocation;
DWORD SectionID;
DWORD Test;
DWORD Test2;
bool InLoop;
bool LinkAllowed; // are other sections allowed to find block to link to it
bool DelaySlotSection;
DWORD StartPC;
/* Register Info */
CRegInfo RegStart;
CRegInfo RegWorking;
/* Jump Info */
CJumpInfo Jump;
CJumpInfo Cont;
//Information about the opcode current being compiled
DWORD m_CompilePC;
OPCODE m_CompileOpcode;
void AddParent ( CCodeSection * Parent );
void UnlinkParent ( CCodeSection * Parent, bool AllowDelete, bool ContinueLink );
bool IsAllParentLoops ( CCodeSection * Parent, bool IgnoreIfCompiled, DWORD Test );
void ResetX86Protection ( void );
static DWORD GetNewTestValue ( void );
static void TestRegConstantStates ( CRegInfo & Base, CRegInfo & Reg );
//Handy Functions
inline CRegInfo::REG_STATE & MipsRegState ( int Reg ) { return RegWorking.MipsRegState(Reg); }
inline unsigned _int64 & MipsReg ( int Reg ) { return RegWorking.MipsReg(Reg); }
inline _int64 & MipsReg_S ( int Reg ) { return RegWorking.MipsReg_S(Reg); }
inline DWORD & MipsRegLo ( int Reg ) { return RegWorking.MipsRegLo(Reg); }
inline long & MipsRegLo_S ( int Reg ) { return RegWorking.MipsRegLo_S(Reg); }
inline DWORD & MipsRegHi ( int Reg ) { return RegWorking.MipsRegHi(Reg); }
inline long & MipsRegHi_S ( int Reg ) { return RegWorking.MipsRegHi_S(Reg); }
inline DWORD & BlockCycleCount(void) { return RegWorking.BlockCycleCount(); }
inline DWORD & BlockRandomModifier(void) { return RegWorking.BlockRandomModifier(); }
inline DWORD & x86MapOrder( int Reg ) { return RegWorking.x86MapOrder(Reg); }
inline bool & x86Protected( int Reg ) { return RegWorking.x86Protected(Reg); }
inline CRegInfo::REG_MAPPED & x86Mapped(int Reg) { return RegWorking.x86Mapped(Reg); }
inline bool IsKnown(int Reg) { return RegWorking.IsKnown(Reg); }
inline bool IsUnknown(int Reg) { return RegWorking.IsUnknown(Reg); }
inline bool IsMapped(int Reg) { return RegWorking.IsMapped(Reg); }
inline bool IsConst(int Reg) { return RegWorking.IsConst(Reg); }
inline bool IsSigned(int Reg) { return RegWorking.IsSigned(Reg); }
inline bool IsUnsigned(int Reg) { return RegWorking.IsUnsigned(Reg); }
inline bool Is32Bit(int Reg) { return RegWorking.Is32Bit(Reg); }
inline bool Is64Bit(int Reg) { return RegWorking.Is64Bit(Reg); }
inline bool Is32BitMapped(int Reg) { return RegWorking.Is32BitMapped(Reg); }
inline bool Is64BitMapped(int Reg) { return RegWorking.Is64BitMapped(Reg); }
inline int & StackTopPos ( void ) { return RegWorking.StackTopPos(); }
inline DWORD & FpuMappedTo( int Reg) { return RegWorking.FpuMappedTo(Reg); }
inline CRegInfo::FPU_STATE & FpuState(int Reg) { return RegWorking.FpuState(Reg); }
inline CRegInfo::FPU_ROUND & FpuRoundingModel(int Reg) { return RegWorking.FpuRoundingModel(Reg); }
inline bool & FpuBeenUsed (void ) { return RegWorking.FpuBeenUsed(); }
inline CRegInfo::FPU_ROUND & CurrentRoundingModel ( void ) { return RegWorking.CurrentRoundingModel(); }
};
class CExitInfo
{
public:
enum EXIT_REASON
{
Normal = 0,
Normal_NoSysCheck = 1,
DoCPU_Action = 2,
COP1_Unuseable = 3,
DoSysCall = 4,
TLBReadMiss = 5,
TLBWriteMiss = 6,
ExitResetRecompCode = 7,
};
DWORD ID;
DWORD TargetPC;
CRegInfo ExitRegSet;
EXIT_REASON reason;
STEP_TYPE NextInstruction;
BYTE * JumpLoc; //32bit jump
};
typedef std::list<CExitInfo> EXIT_LIST;
class CBlockInfo
{
public:
CBlockInfo(DWORD VAddr, BYTE * RecompPos);
DWORD StartVAddr;
DWORD EndVAddr;
BYTE * CompiledLocation;
int NoOfSections;
CCodeSection ParentSection;
EXIT_LIST ExitInfo;
private:
void AnalyseBlock ( void );
};
typedef struct {
CCodeSection * Parent;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,281 @@
class CX86Ops
{
public:
enum x86Reg {
x86_EAX = 0,
x86_EBX = 3,
x86_ECX = 1,
x86_EDX = 2,
x86_ESI = 6,
x86_EDI = 7,
x86_EBP = 5,
x86_ESP = 4,
x86_Any8Bit = -3,
x86_Any = -2,
x86_Unknown = -1,
x86_AL = 0, x86_BL = 3, x86_CL = 1, x86_DL = 2,
x86_AH = 4, x86_BH = 7, x86_CH = 5, x86_DH = 6
};
enum x86FpuValues {
x86_ST0 = 0,
x86_ST1 = 1,
x86_ST2 = 2,
x86_ST3 = 3,
x86_ST4 = 4,
x86_ST5 = 5,
x86_ST6 = 6,
x86_ST7 = 7
};
enum Multipler
{
Multip_x1 = 1,
Multip_x2 = 2,
Multip_x4 = 4,
Multip_x8 = 8
};
static const char * x86_Name ( x86Reg Reg );
static const char * x86_ByteName ( x86Reg Reg );
static const char * x86_HalfName ( x86Reg Reg );
static const char * fpu_Name ( x86FpuValues Reg );
protected:
//Logging Functions
static void WriteX86Comment ( LPCSTR Comment );
static void WriteX86Label ( LPCSTR Label );
static void AdcX86regToVariable ( x86Reg reg, void * Variable, const char * VariableName );
static void AdcConstToVariable ( void *Variable, const char * VariableName, BYTE Constant );
static void AdcConstToX86Reg ( x86Reg Reg, DWORD Const );
static void AdcVariableToX86reg ( x86Reg reg, void * Variable, const char * VariableName );
static void AdcX86RegToX86Reg ( x86Reg Destination, x86Reg Source );
static void AddConstToVariable ( DWORD Const, void *Variable, const char * VariableName );
static void AddConstToX86Reg ( x86Reg Reg, DWORD Const );
static void AddVariableToX86reg ( x86Reg reg, void * Variable, const char * VariableName );
static void AddX86regToVariable ( x86Reg reg, void * Variable, const char * VariableName );
static void AddX86RegToX86Reg ( x86Reg Destination, x86Reg Source );
static void AndConstToVariable ( DWORD Const, void *Variable, const char * VariableName );
static void AndConstToX86Reg ( x86Reg Reg, DWORD Const );
static void AndVariableToX86Reg ( void * Variable, const char * VariableName, x86Reg Reg );
static void AndVariableDispToX86Reg ( void * Variable, const char * VariableName, x86Reg Reg, x86Reg AddrReg, Multipler Multiply);
static void AndX86RegToX86Reg ( x86Reg Destination, x86Reg Source );
static void X86BreakPoint ( LPCSTR FileName, int LineNumber );
static void Call_Direct ( void * FunctAddress, const char * FunctName );
static void Call_Indirect ( void * FunctAddress, const char * FunctName );
static void CompConstToVariable ( DWORD Const, void * Variable, const char * VariableName );
static void CompConstToX86reg ( x86Reg Reg, DWORD Const );
static void CompX86regToVariable ( x86Reg Reg, void * Variable, const char * VariableName );
static void CompVariableToX86reg ( x86Reg Reg, void * Variable, const char * VariableName );
static void CompX86RegToX86Reg ( x86Reg Destination, x86Reg Source );
static void DecX86reg ( x86Reg Reg );
static void DivX86reg ( x86Reg reg );
static void idivX86reg ( x86Reg reg );
static void imulX86reg ( x86Reg reg );
static void IncX86reg ( x86Reg Reg );
static void JaeLabel8 ( char * Label, BYTE Value );
static void JaeLabel32 ( char * Label, DWORD Value );
static void JaLabel8 ( char * Label, BYTE Value );
static void JaLabel32 ( char * Label, DWORD Value );
static void JbLabel8 ( char * Label, BYTE Value );
static void JbLabel32 ( char * Label, DWORD Value );
static void JecxzLabel8 ( char * Label, BYTE Value );
static void JeLabel8 ( char * Label, BYTE Value );
static void JeLabel32 ( char * Label, DWORD Value );
static void JgeLabel32 ( char * Label, DWORD Value );
static void JgLabel8 ( char * Label, BYTE Value );
static void JgLabel32 ( char * Label, DWORD Value );
static void JleLabel8 ( char * Label, BYTE Value );
static void JleLabel32 ( char * Label, DWORD Value );
static void JlLabel8 ( char * Label, BYTE Value );
static void JlLabel32 ( char * Label, DWORD Value );
static void JmpDirectReg ( x86Reg reg );
static void JmpIndirectLabel32 ( char * Label, DWORD location );
static void JmpIndirectReg ( x86Reg reg );
static void JmpLabel8 ( char * Label, BYTE Value );
static void JmpLabel32 ( char * Label, DWORD Value );
static void JneLabel8 ( char * Label, BYTE Value );
static void JneLabel32 ( char * Label, DWORD Value );
static void JnsLabel8 ( char * Label, BYTE Value );
static void JnsLabel32 ( char * Label, DWORD Value );
static void JsLabel32 ( char * Label, DWORD Value );
static void LeaRegReg ( x86Reg RegDest, x86Reg RegSrc, int multiplier );
static void LeaSourceAndOffset ( x86Reg x86DestReg, x86Reg x86SourceReg, int offset );
static void MoveConstByteToN64Mem ( BYTE Const, x86Reg AddrReg );
static void MoveConstHalfToN64Mem ( WORD Const, x86Reg AddrReg );
static void MoveConstByteToVariable ( BYTE Const, void * Variable, const char * VariableName );
static void MoveConstByteToX86regPointer ( BYTE Const, x86Reg AddrReg1, x86Reg AddrReg2 );
static void MoveConstHalfToVariable ( WORD Const, void * Variable, const char * VariableName );
static void MoveConstHalfToX86regPointer ( WORD Const, x86Reg AddrReg1, x86Reg AddrReg2 );
static void MoveConstToMemoryDisp ( DWORD Const, x86Reg AddrReg, DWORD Disp );
static void MoveConstToN64Mem ( DWORD Const, x86Reg AddrReg );
static void MoveConstToN64MemDisp ( DWORD Const, x86Reg AddrReg, BYTE Disp );
static void MoveConstToVariable ( DWORD Const, void * Variable, const char * VariableName );
static void MoveConstToX86Pointer ( DWORD Const, x86Reg X86Pointer );
static void MoveConstToX86reg ( DWORD Const, x86Reg reg );
static void MoveConstToX86regPointer ( DWORD Const, x86Reg AddrReg1, x86Reg AddrReg2 );
static void MoveN64MemDispToX86reg ( x86Reg reg, x86Reg AddrReg, BYTE Disp );
static void MoveN64MemToX86reg ( x86Reg reg, x86Reg AddrReg );
static void MoveN64MemToX86regByte ( x86Reg reg, x86Reg AddrReg );
static void MoveN64MemToX86regHalf ( x86Reg reg, x86Reg AddrReg );
static void MoveSxByteX86regPointerToX86reg ( x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg );
static void MoveSxHalfX86regPointerToX86reg ( x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg );
static void MoveSxN64MemToX86regByte ( x86Reg reg, x86Reg AddrReg );
static void MoveSxN64MemToX86regHalf ( x86Reg reg, x86Reg AddrReg );
static void MoveSxVariableToX86regByte ( void * Variable, const char * VariableName, x86Reg reg );
static void MoveSxVariableToX86regHalf ( void * Variable, const char * VariableName, x86Reg reg );
static void MoveVariableDispToX86Reg ( void * Variable, const char * VariableName, x86Reg Reg, x86Reg AddrReg, int Multiplier );
static void MoveVariableToX86reg ( void * Variable, const char * VariableName, x86Reg reg );
static void MoveVariableToX86regByte ( void * Variable, const char * VariableName, x86Reg reg );
static void MoveVariableToX86regHalf ( void * Variable, const char * VariableName, x86Reg reg );
static void MoveX86PointerToX86reg ( x86Reg reg, x86Reg X86Pointer );
static void MoveX86PointerToX86regDisp ( x86Reg reg, x86Reg X86Pointer, BYTE Disp );
static void MoveX86regByteToN64Mem ( x86Reg reg, x86Reg AddrReg );
static void MoveX86regByteToVariable ( x86Reg reg, void * Variable, const char * VariableName );
static void MoveX86regByteToX86regPointer ( x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2 );
static void MoveX86regHalfToN64Mem ( x86Reg reg, x86Reg AddrReg );
static void MoveX86regHalfToVariable ( x86Reg reg, void * Variable, const char * VariableName );
static void MoveX86regHalfToX86regPointer ( x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2 );
static void MoveX86regPointerToX86reg ( x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg );
static void MoveX86regPointerToX86regDisp8 ( x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg, BYTE offset );
static void MoveX86regToMemory ( x86Reg reg, x86Reg AddrReg, DWORD Disp );
static void MoveX86regToN64Mem ( x86Reg reg, x86Reg AddrReg );
static void MoveX86regToN64MemDisp ( x86Reg reg, x86Reg AddrReg, BYTE Disp );
static void MoveX86regToVariable ( x86Reg reg, void * Variable, const char * VariableName );
static void MoveX86RegToX86Reg ( x86Reg Source, x86Reg Destination );
static void MoveX86regToX86Pointer ( x86Reg reg, x86Reg X86Pointer );
static void MoveX86regToX86regPointer ( x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2 );
static void MoveZxByteX86regPointerToX86reg ( x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg );
static void MoveZxHalfX86regPointerToX86reg ( x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg );
static void MoveZxN64MemToX86regByte ( x86Reg reg, x86Reg AddrReg );
static void MoveZxN64MemToX86regHalf ( x86Reg reg, x86Reg AddrReg );
static void MoveZxVariableToX86regByte ( void * Variable, const char * VariableName, x86Reg reg );
static void MoveZxVariableToX86regHalf ( void * Variable, const char * VariableName, x86Reg reg );
static void MulX86reg ( x86Reg reg );
static void NotX86Reg ( x86Reg Reg );
static void OrConstToVariable ( DWORD Const, void * Variable, const char * VariableName );
static void OrConstToX86Reg ( DWORD Const, x86Reg reg );
static void OrVariableToX86Reg ( void * Variable, const char * VariableName, x86Reg Reg );
static void OrX86RegToVariable ( void * Variable, const char * VariableName, x86Reg Reg );
static void OrX86RegToX86Reg ( x86Reg Destination, x86Reg Source );
static void Popad ( void );
static void Pushad ( void );
static void Push ( x86Reg reg );
static void Pop ( x86Reg reg );
static void PushImm32 ( char * String, DWORD Value );
static void Ret ( void );
static void Seta ( x86Reg reg );
static void Setae ( x86Reg reg );
static void SetaVariable ( void * Variable, const char * VariableName );
static void Setb ( x86Reg reg );
static void SetbVariable ( void * Variable, const char * VariableName );
static void Setg ( x86Reg reg );
static void SetgVariable ( void * Variable, const char * VariableName );
static void Setl ( x86Reg reg );
static void SetlVariable ( void * Variable, const char * VariableName );
static void Setz ( x86Reg reg );
static void Setnz ( x86Reg reg );
static void ShiftLeftDouble ( x86Reg Destination, x86Reg Source );
static void ShiftLeftDoubleImmed ( x86Reg Destination, x86Reg Source, BYTE Immediate );
static void ShiftLeftSign ( x86Reg reg );
static void ShiftLeftSignImmed ( x86Reg reg, BYTE Immediate );
static void ShiftRightDouble ( x86Reg Destination, x86Reg Source );
static void ShiftRightDoubleImmed ( x86Reg Destination, x86Reg Source, BYTE Immediate );
static void ShiftRightSign ( x86Reg reg );
static void ShiftRightSignImmed ( x86Reg reg, BYTE Immediate );
static void ShiftRightUnsign ( x86Reg reg );
static void ShiftRightUnsignImmed ( x86Reg reg, BYTE Immediate );
static void SbbConstFromX86Reg ( x86Reg Reg, DWORD Const );
static void SbbVariableFromX86reg ( x86Reg reg, void * Variable, const char * VariableName );
static void SbbX86RegToX86Reg ( x86Reg Destination, x86Reg Source );
static void SubConstFromVariable ( DWORD Const, void * Variable, const char * VariableName );
static void SubConstFromX86Reg ( x86Reg Reg, DWORD Const );
static void SubVariableFromX86reg ( x86Reg reg, void * Variable, const char * VariableName );
static void SubX86RegToX86Reg ( x86Reg Destination, x86Reg Source );
static void TestConstToX86Reg ( DWORD Const, x86Reg reg );
static void TestVariable ( DWORD Const, void * Variable, const char * VariableName );
static void TestX86RegToX86Reg ( x86Reg Destination, x86Reg Source );
static void XorConstToX86Reg ( x86Reg Reg, DWORD Const );
static void XorX86RegToX86Reg ( x86Reg Source, x86Reg Destination );
static void XorVariableToX86reg ( void * Variable, const char * VariableName, x86Reg reg );
static void fpuAbs ( void );
static void fpuAddDword ( void * Variable, const char * VariableName );
static void fpuAddDwordRegPointer ( x86Reg x86Pointer );
static void fpuAddQword ( void * Variable, const char * VariableName );
static void fpuAddQwordRegPointer ( x86Reg X86Pointer );
static void fpuAddReg ( x86FpuValues reg );
static void fpuAddRegPop ( int * StackPos, x86FpuValues reg );
static void fpuComDword ( void * Variable, const char * VariableName, BOOL Pop );
static void fpuComDwordRegPointer ( x86Reg X86Pointer, BOOL Pop );
static void fpuComQword ( void * Variable, const char * VariableName, BOOL Pop );
static void fpuComQwordRegPointer ( x86Reg X86Pointer, BOOL Pop );
static void fpuComReg ( x86FpuValues reg, BOOL Pop );
static void fpuDivDword ( void * Variable, const char * VariableName );
static void fpuDivDwordRegPointer ( x86Reg X86Pointer );
static void fpuDivQword ( void * Variable, const char * VariableName );
static void fpuDivQwordRegPointer ( x86Reg X86Pointer );
static void fpuDivReg ( x86FpuValues Reg );
static void fpuDivRegPop ( x86FpuValues reg );
static void fpuExchange ( x86FpuValues Reg );
static void fpuFree ( x86FpuValues Reg );
static void fpuDecStack ( int * StackPos );
static void fpuIncStack ( int * StackPos );
static void fpuLoadControl ( void * Variable, const char * VariableName );
static void fpuLoadDword ( int * StackPos, void * Variable, const char * VariableName );
static void fpuLoadDwordFromX86Reg ( int * StackPos, x86Reg reg );
static void fpuLoadDwordFromN64Mem ( int * StackPos, x86Reg reg );
static void fpuLoadInt32bFromN64Mem ( int * StackPos, x86Reg reg );
static void fpuLoadIntegerDword ( int * StackPos, void * Variable, const char * VariableName );
static void fpuLoadIntegerDwordFromX86Reg ( int * StackPos,x86Reg Reg );
static void fpuLoadIntegerQword ( int * StackPos, void * Variable, const char * VariableName );
static void fpuLoadIntegerQwordFromX86Reg ( int * StackPos,x86Reg Reg );
static void fpuLoadQword ( int * StackPos, void * Variable, const char * VariableName );
static void fpuLoadQwordFromX86Reg ( int * StackPos, x86Reg Reg );
static void fpuLoadQwordFromN64Mem ( int * StackPos, x86Reg reg );
static void fpuLoadReg ( int * StackPos, x86FpuValues Reg );
static void fpuMulDword ( void * Variable, const char * VariableName);
static void fpuMulDwordRegPointer ( x86Reg X86Pointer );
static void fpuMulQword ( void * Variable, const char * VariableName);
static void fpuMulQwordRegPointer ( x86Reg X86Pointer );
static void fpuMulReg ( x86FpuValues reg );
static void fpuMulRegPop ( x86FpuValues reg );
static void fpuNeg ( void );
static void fpuRound ( void );
static void fpuSqrt ( void );
static void fpuStoreControl ( void * Variable, const char * VariableName );
static void fpuStoreDword ( int * StackPos, void * Variable, const char * VariableName, BOOL pop );
static void fpuStoreDwordFromX86Reg ( int * StackPos,x86Reg Reg, BOOL pop );
static void fpuStoreDwordToN64Mem ( int * StackPos, x86Reg reg, BOOL Pop );
static void fpuStoreIntegerDword ( int * StackPos, void * Variable, const char * VariableName, BOOL pop );
static void fpuStoreIntegerDwordFromX86Reg ( int * StackPos,x86Reg Reg, BOOL pop );
static void fpuStoreIntegerQword ( int * StackPos, void * Variable, const char * VariableName, BOOL pop );
static void fpuStoreIntegerQwordFromX86Reg ( int * StackPos, x86Reg Reg, BOOL pop );
static void fpuStoreQword ( int * StackPos, void * Variable, const char * VariableName, BOOL pop );
static void fpuStoreQwordFromX86Reg ( int * StackPos, x86Reg Reg, BOOL pop );
static void fpuStoreStatus ( void );
static void fpuSubDword ( void * Variable, const char * VariableName );
static void fpuSubDwordRegPointer ( x86Reg X86Pointer );
static void fpuSubDwordReverse ( void * Variable, const char * VariableName );
static void fpuSubQword ( void * Variable, const char * VariableName );
static void fpuSubQwordRegPointer ( x86Reg X86Pointer );
static void fpuSubQwordReverse ( void * Variable, const char * VariableName );
static void fpuSubReg ( x86FpuValues reg );
static void fpuSubRegPop ( x86FpuValues reg );
static BYTE CalcMultiplyCode ( Multipler Multiply );
static BYTE * m_RecompPos;
static void * GetAddressOf(int value, ...);
static void SetJump32(DWORD * Loc, DWORD * JumpLoc );
static void SetJump8(BYTE * Loc, BYTE * JumpLoc);
private:
static void BreakPointNotification (const char * const FileName, const int LineNumber);
static char m_fpupop[2][2];
};
#define AddressOf(Addr) CX86Ops::GetAddressOf(5,(Addr))

View File

@ -498,6 +498,14 @@ SOURCE=".\N64 System\C Core\X86.cpp"
# PROP Default_Filter ""
# Begin Source File
SOURCE=".\N64 System\Recompiler\Code Block.cpp"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\Code Section.cpp"
# End Source File
# Begin Source File
SOURCE="N64 System\Recompiler\Delay Slot Map Class.cpp"
# End Source File
# Begin Source File
@ -510,6 +518,10 @@ SOURCE="N64 System\Recompiler\Function Map Class.cpp"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\Jump Info.cpp"
# End Source File
# Begin Source File
SOURCE="N64 System\Recompiler\Recompiler Class.cpp"
# End Source File
# Begin Source File
@ -522,8 +534,16 @@ SOURCE=".\N64 System\Recompiler\Recompiler Ops.cpp"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\Reg Info.cpp"
# End Source File
# Begin Source File
SOURCE="N64 System\Recompiler\Section Info.cpp"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\X86ops.cpp"
# End Source File
# End Group
# Begin Group "Interpreter Files"
@ -1130,10 +1150,22 @@ SOURCE="N64 System\Debugger\debugger.h"
# PROP Default_Filter ""
# Begin Source File
SOURCE=".\N64 System\Recompiler\Code Block.h"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\Code Section.h"
# End Source File
# Begin Source File
SOURCE="N64 System\Recompiler\Delay Slot Map Class.h"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\Exit Info.h"
# End Source File
# Begin Source File
SOURCE="N64 System\Recompiler\Function Info.h"
# End Source File
# Begin Source File
@ -1142,6 +1174,10 @@ SOURCE="N64 System\Recompiler\Function Map Class.h"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\Jump Info.h"
# End Source File
# Begin Source File
SOURCE="N64 System\Recompiler\Recompiler Class.h"
# End Source File
# Begin Source File
@ -1154,8 +1190,16 @@ SOURCE=".\N64 System\Recompiler\Recompiler Ops.h"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\Reg Info.h"
# End Source File
# Begin Source File
SOURCE="N64 System\Recompiler\Section Info.h"
# End Source File
# Begin Source File
SOURCE=".\N64 System\Recompiler\X86ops.h"
# End Source File
# End Group
# Begin Group "Interpreter Headers"