git-svn-id: https://localhost/svn/Project64/trunk@30 111125ac-702d-7242-af9c-5ba8ae61c1ef
This commit is contained in:
parent
142187aafb
commit
ce1ff4d421
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#ifdef tofix
|
||||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
|
@ -1166,3 +1167,5 @@ void Compile_R4300i_COP1_L_CVT_D (CCodeSection * Section) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifdef tofix
|
||||
|
||||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
|
@ -3009,3 +3011,5 @@ void * GetAddressOf(int value, ...) {
|
|||
|
||||
return Address;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifdef toremove
|
||||
|
||||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
|
@ -281,3 +283,5 @@ void fpuSubRegPop ( int x86reg );
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
@ -862,3 +116,5 @@ void fpuSetupDouble(void) {
|
|||
fldcw word ptr [temp]
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -309,6 +301,8 @@ void CInterpreterCPU::StartInterpreterCPU (void )
|
|||
{
|
||||
R4300iOp::m_TestTimer = FALSE;
|
||||
R4300iOp::m_NextInstruction = NORMAL;
|
||||
R4300iOp::m_JumpToLocation = 0;
|
||||
|
||||
DWORD CountPerOp = _Settings->LoadDword(Game_CounterFactor);
|
||||
|
||||
bool & Done = _N64System->m_EndEmulation;
|
||||
|
@ -318,6 +312,7 @@ void CInterpreterCPU::StartInterpreterCPU (void )
|
|||
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;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
class CInterpreterCPU
|
||||
class CInterpreterCPU :
|
||||
private R4300iOp
|
||||
{
|
||||
public:
|
||||
CInterpreterCPU();
|
||||
|
|
|
@ -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))
|
||||
if (LogOptions.GenerateLog)
|
||||
{
|
||||
Log_LW((*_PROGRAM_COUNTER),Address);
|
||||
#endif
|
||||
}
|
||||
|
||||
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))
|
||||
if (LogOptions.GenerateLog)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -1,3 +1,5 @@
|
|||
#ifdef tofix
|
||||
|
||||
class COpcodeAnalysis
|
||||
{
|
||||
OPCODE &m_opcode;
|
||||
|
@ -28,3 +30,5 @@ public:
|
|||
//Stops execution
|
||||
bool TerminateExecution ( void );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -1,10 +1,6 @@
|
|||
#ifndef __OPCODE__H__
|
||||
#define __OPCODE__H__
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
DWORD VirtualAddress;
|
||||
|
||||
union {
|
||||
typedef union {
|
||||
unsigned long Hex;
|
||||
unsigned char Ascii[4];
|
||||
|
||||
|
@ -44,7 +40,6 @@ typedef struct {
|
|||
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
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
class CTransVaddr
|
||||
{
|
||||
public:
|
||||
virtual bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const = 0;
|
||||
virtual bool ValidVaddr ( DWORD VAddr ) const = 0;
|
||||
};
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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:
|
||||
|
||||
};
|
||||
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
|
@ -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
|
|
@ -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;
|
||||
//constructor
|
||||
CCompiledFunc ( void ); // not implemented
|
||||
|
||||
public:
|
||||
//constructor
|
||||
CCompiledFunc (DWORD VirtualStartAddress, DWORD PhysicalStartAddress );
|
||||
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; }
|
||||
|
||||
//Set Private Information
|
||||
inline void SetVEndPC ( DWORD VEndPC ) { m_VEndPC = VEndPC; }
|
||||
inline void SetFunctionAddr ( RECOMP_FUNC FunctionAddr ) { m_Function = FunctionAddr; }
|
||||
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
|
||||
|
||||
|
||||
//Functions
|
||||
bool CompilerCodeBlock ( void );
|
||||
//From querying the recompiler get information about the function
|
||||
Func m_Function;
|
||||
|
||||
//Validation
|
||||
QWORD MemContents[2], * MemLocation[2];
|
||||
|
||||
CCompiledFunc * Next;
|
||||
//QWORD MemContents[2], * MemLocation[2];
|
||||
};
|
||||
|
|
|
@ -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
|
@ -21,11 +21,7 @@ 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 );
|
||||
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
||||
CRecompilerOps( CCodeSection * Section );
|
||||
typedef void ( * BranchFunction )();
|
||||
|
||||
/************************** 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 );
|
||||
|
||||
private:
|
||||
CCodeSection * m_Section;
|
||||
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 );
|
||||
|
||||
|
||||
|
||||
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; }
|
||||
};
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
@ -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))
|
|
@ -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"
|
||||
|
||||
|
|
Loading…
Reference in New Issue