core: convert xCALL to xFastCall

SuperVU wasn't converted (unlikely to be ported to 64 bits)
A couple of calls weren't converted because they require extra work
but there are not mandatory (debug/MTVU/...)
This commit is contained in:
Gregory Hainaut 2016-01-11 08:26:00 +01:00
parent 859d62d2a7
commit e3d5eb5a4e
15 changed files with 88 additions and 120 deletions

View File

@ -112,7 +112,7 @@ void recDI()
//xMOV(eax, ptr[&cpuRegs.cycle ]); //xMOV(eax, ptr[&cpuRegs.cycle ]);
//xMOV(ptr[&g_nextBranchCycle], eax); //xMOV(ptr[&g_nextBranchCycle], eax);
//xCALL((void*)(uptr)Interp::DI ); //xFastCall((void*)(uptr)Interp::DI );
xMOV(eax, ptr[&cpuRegs.CP0.n.Status]); xMOV(eax, ptr[&cpuRegs.CP0.n.Status]);
xTEST(eax, 0x20006); // EXL | ERL | EDI xTEST(eax, 0x20006); // EXL | ERL | EDI
@ -170,12 +170,12 @@ void recMFC0()
case 1: case 1:
iFlushCall(FLUSH_INTERPRETER); iFlushCall(FLUSH_INTERPRETER);
xCALL( COP0_UpdatePCCR ); xFastCall(COP0_UpdatePCCR );
xMOV(eax, ptr[&cpuRegs.PERF.n.pcr0]); xMOV(eax, ptr[&cpuRegs.PERF.n.pcr0]);
break; break;
case 3: case 3:
iFlushCall(FLUSH_INTERPRETER); iFlushCall(FLUSH_INTERPRETER);
xCALL( COP0_UpdatePCCR ); xFastCall(COP0_UpdatePCCR );
xMOV(eax, ptr[&cpuRegs.PERF.n.pcr1]); xMOV(eax, ptr[&cpuRegs.PERF.n.pcr1]);
break; break;
} }
@ -207,8 +207,7 @@ void recMTC0()
{ {
case 12: case 12:
iFlushCall(FLUSH_INTERPRETER); iFlushCall(FLUSH_INTERPRETER);
xMOV( ecx, g_cpuConstRegs[_Rt_].UL[0] ); xFastCall(WriteCP0Status, g_cpuConstRegs[_Rt_].UL[0] );
xCALL( WriteCP0Status );
break; break;
case 9: case 9:
@ -222,9 +221,9 @@ void recMTC0()
{ {
case 0: case 0:
iFlushCall(FLUSH_INTERPRETER); iFlushCall(FLUSH_INTERPRETER);
xCALL( COP0_UpdatePCCR ); xFastCall(COP0_UpdatePCCR );
xMOV( ptr32[&cpuRegs.PERF.n.pccr], g_cpuConstRegs[_Rt_].UL[0] ); xMOV( ptr32[&cpuRegs.PERF.n.pccr], g_cpuConstRegs[_Rt_].UL[0] );
xCALL( COP0_DiagnosticPCCR ); xFastCall(COP0_DiagnosticPCCR );
break; break;
case 1: case 1:
@ -257,7 +256,7 @@ void recMTC0()
case 12: case 12:
iFlushCall(FLUSH_INTERPRETER); iFlushCall(FLUSH_INTERPRETER);
_eeMoveGPRtoR(ecx, _Rt_); _eeMoveGPRtoR(ecx, _Rt_);
xCALL( WriteCP0Status ); xFastCall(WriteCP0Status, ecx );
break; break;
case 9: case 9:
@ -271,9 +270,9 @@ void recMTC0()
{ {
case 0: case 0:
iFlushCall(FLUSH_INTERPRETER); iFlushCall(FLUSH_INTERPRETER);
xCALL( COP0_UpdatePCCR ); xFastCall(COP0_UpdatePCCR );
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_); _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_);
xCALL( COP0_DiagnosticPCCR ); xFastCall(COP0_DiagnosticPCCR );
break; break;
case 1: case 1:

View File

@ -92,7 +92,7 @@ static const __aligned16 u32 s_pos[4] = { 0x7fffffff, 0xffffffff, 0xffffffff, 0x
void f(); \ void f(); \
void rec##f() { \ void rec##f() { \
iFlushCall(FLUSH_INTERPRETER); \ iFlushCall(FLUSH_INTERPRETER); \
xCALL((void*)(uptr)R5900::Interpreter::OpcodeImpl::COP1::f); \ xFastCall((void*)(uptr)R5900::Interpreter::OpcodeImpl::COP1::f); \
branch = 2; \ branch = 2; \
} }
@ -100,7 +100,7 @@ static const __aligned16 u32 s_pos[4] = { 0x7fffffff, 0xffffffff, 0xffffffff, 0x
void f(); \ void f(); \
void rec##f() { \ void rec##f() { \
iFlushCall(FLUSH_INTERPRETER); \ iFlushCall(FLUSH_INTERPRETER); \
xCALL((void*)(uptr)R5900::Interpreter::OpcodeImpl::COP1::f); \ xFastCall((void*)(uptr)R5900::Interpreter::OpcodeImpl::COP1::f); \
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -550,7 +550,7 @@ void FPU_MUL(int regd, int regt, bool reverseOperands)
{ {
xMOVD(ecx, xRegisterSSE(reverseOperands ? regt : regd)); xMOVD(ecx, xRegisterSSE(reverseOperands ? regt : regd));
xMOVD(edx, xRegisterSSE(reverseOperands ? regd : regt)); xMOVD(edx, xRegisterSSE(reverseOperands ? regd : regt));
xCALL((void*)(uptr)&FPU_MUL_HACK ); //returns the hacked result or 0 xFastCall((void*)(uptr)&FPU_MUL_HACK, ecx, edx); //returns the hacked result or 0
xTEST(eax, eax); xTEST(eax, eax);
noHack = JZ8(0); noHack = JZ8(0);
xMOVDZX(xRegisterSSE(regd), eax); xMOVDZX(xRegisterSSE(regd), eax);

View File

@ -89,20 +89,6 @@ namespace DOUBLE {
#define FPUflagSO 0X00000010 #define FPUflagSO 0X00000010
#define FPUflagSU 0X00000008 #define FPUflagSU 0X00000008
#define REC_FPUBRANCH(f) \
void f(); \
void rec##f() { \
iFlushCall(FLUSH_INTERPRETER); \
xCALL((void*)(uptr)R5900::Interpreter::OpcodeImpl::COP1::f); \
branch = 2; \
}
#define REC_FPUFUNC(f) \
void f(); \
void rec##f() { \
iFlushCall(FLUSH_INTERPRETER); \
xCALL((void*)(uptr)R5900::Interpreter::OpcodeImpl::COP1::f); \
}
//------------------------------------------------------------------ //------------------------------------------------------------------
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -416,7 +402,7 @@ void FPU_MUL(int info, int regd, int sreg, int treg, bool acc)
{ {
xMOVD(ecx, xRegisterSSE(sreg)); xMOVD(ecx, xRegisterSSE(sreg));
xMOVD(edx, xRegisterSSE(treg)); xMOVD(edx, xRegisterSSE(treg));
xCALL((void*)(uptr)&FPU_MUL_HACK ); //returns the hacked result or 0 xFastCall((void*)(uptr)&FPU_MUL_HACK, ecx, edx); //returns the hacked result or 0
xTEST(eax, eax); xTEST(eax, eax);
noHack = JZ8(0); noHack = JZ8(0);
xMOVDZX(xRegisterSSE(regd), eax); xMOVDZX(xRegisterSSE(regd), eax);

View File

@ -185,7 +185,7 @@ void recPMFHL()
// fall to interp // fall to interp
_deleteEEreg(_Rd_, 0); _deleteEEreg(_Rd_, 0);
iFlushCall(FLUSH_INTERPRETER); // since calling CALLFunc iFlushCall(FLUSH_INTERPRETER); // since calling CALLFunc
xCALL((void*)(uptr)R5900::Interpreter::OpcodeImpl::MMI::PMFHL ); xFastCall((void*)(uptr)R5900::Interpreter::OpcodeImpl::MMI::PMFHL );
break; break;
case 0x03: // LH case 0x03: // LH

View File

@ -128,8 +128,7 @@ static DynGenFunc* _DynGen_JITCompile()
u8* retval = xGetPtr(); u8* retval = xGetPtr();
xMOV( ecx, ptr[&psxRegs.pc] ); xFastCall(iopRecRecompile, ptr[&psxRegs.pc] );
xCALL( iopRecRecompile );
xMOV( eax, ptr[&psxRegs.pc] ); xMOV( eax, ptr[&psxRegs.pc] );
xMOV( ebx, eax ); xMOV( ebx, eax );
@ -199,7 +198,7 @@ static void _DynGen_Dispatchers()
// Place the EventTest and DispatcherReg stuff at the top, because they get called the // Place the EventTest and DispatcherReg stuff at the top, because they get called the
// most and stand to benefit from strong alignment and direct referencing. // most and stand to benefit from strong alignment and direct referencing.
iopDispatcherEvent = (DynGenFunc*)xGetPtr(); iopDispatcherEvent = (DynGenFunc*)xGetPtr();
xCALL( recEventTest ); xFastCall(recEventTest );
iopDispatcherReg = _DynGen_DispatcherReg(); iopDispatcherReg = _DynGen_DispatcherReg();
iopJITCompile = _DynGen_JITCompile(); iopJITCompile = _DynGen_JITCompile();
@ -523,11 +522,11 @@ void psxRecompileCodeConst1(R3000AFNPTR constcode, R3000AFNPTR_INFO noconstcode)
} }
if (debug) if (debug)
xCALL(debug); xFastCall(debug);
#endif #endif
irxHLE hle = irxImportHLE(libname, index); irxHLE hle = irxImportHLE(libname, index);
if (hle) { if (hle) {
xCALL(hle); xFastCall(hle);
xCMP(eax, 0); xCMP(eax, 0);
xJNE(iopDispatcherReg); xJNE(iopDispatcherReg);
} }
@ -907,7 +906,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
xSUB(ptr32[&iopCycleEE], eax); xSUB(ptr32[&iopCycleEE], eax);
xJLE(iopExitRecompiledCode); xJLE(iopExitRecompiledCode);
xCALL(iopEventTest); xFastCall(iopEventTest);
if( newpc != 0xffffffff ) if( newpc != 0xffffffff )
{ {
@ -929,7 +928,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
xSUB(eax, ptr32[&g_iopNextEventCycle]); xSUB(eax, ptr32[&g_iopNextEventCycle]);
xForwardJS<u8> nointerruptpending; xForwardJS<u8> nointerruptpending;
xCALL(iopEventTest); xFastCall(iopEventTest);
if( newpc != 0xffffffff ) { if( newpc != 0xffffffff ) {
xCMP(ptr32[&psxRegs.pc], newpc); xCMP(ptr32[&psxRegs.pc], newpc);
@ -964,9 +963,9 @@ void rpsxSYSCALL()
xMOV(ptr32[&psxRegs.pc], psxpc - 4); xMOV(ptr32[&psxRegs.pc], psxpc - 4);
_psxFlushCall(FLUSH_NODESTROY); _psxFlushCall(FLUSH_NODESTROY);
xMOV( ecx, 0x20 ); // exception code //xMOV( ecx, 0x20 ); // exception code
xMOV( edx, psxbranch==1 ); // branch delay slot? //xMOV( edx, psxbranch==1 ); // branch delay slot?
xCALL( psxException ); xFastCall(psxException, 0x20, psxbranch == 1 );
xCMP(ptr32[&psxRegs.pc], psxpc-4); xCMP(ptr32[&psxRegs.pc], psxpc-4);
j8Ptr[0] = JE8(0); j8Ptr[0] = JE8(0);
@ -987,9 +986,9 @@ void rpsxBREAK()
xMOV(ptr32[&psxRegs.pc], psxpc - 4); xMOV(ptr32[&psxRegs.pc], psxpc - 4);
_psxFlushCall(FLUSH_NODESTROY); _psxFlushCall(FLUSH_NODESTROY);
xMOV( ecx, 0x24 ); // exception code //xMOV( ecx, 0x24 ); // exception code
xMOV( edx, psxbranch==1 ); // branch delay slot? //xMOV( edx, psxbranch==1 ); // branch delay slot?
xCALL( psxException ); xFastCall(psxException, 0x24, psxbranch == 1 );
xCMP(ptr32[&psxRegs.pc], psxpc-4); xCMP(ptr32[&psxRegs.pc], psxpc-4);
j8Ptr[0] = JE8(0); j8Ptr[0] = JE8(0);
@ -1102,8 +1101,7 @@ static void __fastcall iopRecRecompile( const u32 startpc )
if( IsDebugBuild ) if( IsDebugBuild )
{ {
xMOV(ecx, psxpc); xFastCall(PreBlockCheck, psxpc);
xCALL(PreBlockCheck);
} }
// go until the next branch // go until the next branch

View File

@ -32,7 +32,7 @@ extern u32 g_psxMaxRecMem;
static void rpsx##f() { \ static void rpsx##f() { \
xMOV(ptr32[&psxRegs.code], (u32)psxRegs.code); \ xMOV(ptr32[&psxRegs.code], (u32)psxRegs.code); \
_psxFlushCall(FLUSH_EVERYTHING); \ _psxFlushCall(FLUSH_EVERYTHING); \
xCALL((void*)(uptr)psx##f); \ xFastCall((void*)(uptr)psx##f); \
PSX_DEL_CONST(_Rt_); \ PSX_DEL_CONST(_Rt_); \
/* branch = 2; */\ /* branch = 2; */\
} }
@ -626,7 +626,7 @@ static void rpsxLB()
xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]); xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]);
if (_Imm_) xADD(ecx, _Imm_); if (_Imm_) xADD(ecx, _Imm_);
xCALL( iopMemRead8 ); // returns value in EAX xFastCall(iopMemRead8, ecx ); // returns value in EAX
if (_Rt_) { if (_Rt_) {
xMOVSX(eax, al); xMOVSX(eax, al);
xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax); xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax);
@ -642,7 +642,7 @@ static void rpsxLBU()
xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]); xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]);
if (_Imm_) xADD(ecx, _Imm_); if (_Imm_) xADD(ecx, _Imm_);
xCALL( iopMemRead8 ); // returns value in EAX xFastCall(iopMemRead8, ecx ); // returns value in EAX
if (_Rt_) { if (_Rt_) {
xMOVZX(eax, al); xMOVZX(eax, al);
xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax); xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax);
@ -658,7 +658,7 @@ static void rpsxLH()
xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]); xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]);
if (_Imm_) xADD(ecx, _Imm_); if (_Imm_) xADD(ecx, _Imm_);
xCALL( iopMemRead16 ); // returns value in EAX xFastCall(iopMemRead16, ecx ); // returns value in EAX
if (_Rt_) { if (_Rt_) {
xMOVSX(eax, ax); xMOVSX(eax, ax);
xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax); xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax);
@ -674,7 +674,7 @@ static void rpsxLHU()
xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]); xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]);
if (_Imm_) xADD(ecx, _Imm_); if (_Imm_) xADD(ecx, _Imm_);
xCALL( iopMemRead16 ); // returns value in EAX xFastCall(iopMemRead16, ecx ); // returns value in EAX
if (_Rt_) { if (_Rt_) {
xMOVZX(eax, ax); xMOVZX(eax, ax);
xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax); xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax);
@ -695,7 +695,7 @@ static void rpsxLW()
xTEST(ecx, 0x10000000); xTEST(ecx, 0x10000000);
j8Ptr[0] = JZ8(0); j8Ptr[0] = JZ8(0);
xCALL( iopMemRead32 ); // returns value in EAX xFastCall(iopMemRead32, ecx ); // returns value in EAX
if (_Rt_) { if (_Rt_) {
xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax); xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax);
} }
@ -721,7 +721,7 @@ static void rpsxSB()
xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]); xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]);
if (_Imm_) xADD(ecx, _Imm_); if (_Imm_) xADD(ecx, _Imm_);
xMOV( edx, ptr[&psxRegs.GPR.r[_Rt_]] ); xMOV( edx, ptr[&psxRegs.GPR.r[_Rt_]] );
xCALL( iopMemWrite8 ); xFastCall(iopMemWrite8, ecx, edx );
} }
static void rpsxSH() static void rpsxSH()
@ -732,7 +732,7 @@ static void rpsxSH()
xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]); xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]);
if (_Imm_) xADD(ecx, _Imm_); if (_Imm_) xADD(ecx, _Imm_);
xMOV( edx, ptr[&psxRegs.GPR.r[_Rt_]] ); xMOV( edx, ptr[&psxRegs.GPR.r[_Rt_]] );
xCALL( iopMemWrite16 ); xFastCall(iopMemWrite16, ecx, edx );
} }
static void rpsxSW() static void rpsxSW()
@ -743,7 +743,7 @@ static void rpsxSW()
xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]); xMOV(ecx, ptr[&psxRegs.GPR.r[_Rs_]]);
if (_Imm_) xADD(ecx, _Imm_); if (_Imm_) xADD(ecx, _Imm_);
xMOV( edx, ptr[&psxRegs.GPR.r[_Rt_]] ); xMOV( edx, ptr[&psxRegs.GPR.r[_Rt_]] );
xCALL( iopMemWrite32 ); xFastCall(iopMemWrite32, ecx, edx );
} }
//// SLL //// SLL
@ -1371,7 +1371,7 @@ void rpsxRFE()
// Test the IOP's INTC status, so that any pending ints get raised. // Test the IOP's INTC status, so that any pending ints get raised.
_psxFlushCall(0); _psxFlushCall(0);
xCALL((void*)(uptr)&iopTestIntc ); xFastCall((void*)(uptr)&iopTestIntc );
} }
// R3000A tables // R3000A tables

View File

@ -71,7 +71,7 @@ namespace OpcodeImpl {
// xMOV(ptr32[&cpuRegs.code], cpuRegs.code ); // xMOV(ptr32[&cpuRegs.code], cpuRegs.code );
// xMOV(ptr32[&cpuRegs.pc], pc ); // xMOV(ptr32[&cpuRegs.pc], pc );
// iFlushCall(FLUSH_EVERYTHING); // iFlushCall(FLUSH_EVERYTHING);
// xCALL((void*)(uptr)CACHE ); // xFastCall((void*)(uptr)CACHE );
// //branch = 2; // //branch = 2;
// //
// xCMP(ptr32[(u32*)((int)&cpuRegs.pc)], pc); // xCMP(ptr32[(u32*)((int)&cpuRegs.pc)], pc);
@ -203,7 +203,7 @@ void recMTSAH()
//xMOV(ptr32[&cpuRegs.code], (u32)cpuRegs.code ); //xMOV(ptr32[&cpuRegs.code], (u32)cpuRegs.code );
//xMOV(ptr32[&cpuRegs.pc], (u32)pc ); //xMOV(ptr32[&cpuRegs.pc], (u32)pc );
//iFlushCall(FLUSH_EVERYTHING); //iFlushCall(FLUSH_EVERYTHING);
//xCALL((void*)(uptr)R5900::Interpreter::OpcodeImpl::CACHE ); //xFastCall((void*)(uptr)R5900::Interpreter::OpcodeImpl::CACHE );
//branch = 2; //branch = 2;
} }

View File

@ -340,7 +340,7 @@ void recBranchCall( void (*func)() )
void recCall( void (*func)() ) void recCall( void (*func)() )
{ {
iFlushCall(FLUSH_INTERPRETER); iFlushCall(FLUSH_INTERPRETER);
xCALL(func); xFastCall(func);
} }
// ===================================================================================================== // =====================================================================================================
@ -380,8 +380,7 @@ static DynGenFunc* _DynGen_JITCompile()
u8* retval = xGetAlignedCallTarget(); u8* retval = xGetAlignedCallTarget();
xMOV( ecx, ptr[&cpuRegs.pc] ); xFastCall(recRecompile, ptr[&cpuRegs.pc] );
xCALL( recRecompile );
xMOV( eax, ptr[&cpuRegs.pc] ); xMOV( eax, ptr[&cpuRegs.pc] );
xMOV( ebx, eax ); xMOV( ebx, eax );
@ -417,7 +416,7 @@ static DynGenFunc* _DynGen_DispatcherEvent()
{ {
u8* retval = xGetPtr(); u8* retval = xGetPtr();
xCALL( recEventTest ); xFastCall(recEventTest );
return (DynGenFunc*)retval; return (DynGenFunc*)retval;
} }
@ -446,7 +445,7 @@ static DynGenFunc* _DynGen_DispatchBlockDiscard()
{ {
u8* retval = xGetPtr(); u8* retval = xGetPtr();
xEMMS(); xEMMS();
xCALL(dyna_block_discard); xFastCall(dyna_block_discard);
xJMP(ExitRecompiledCode); xJMP(ExitRecompiledCode);
return (DynGenFunc*)retval; return (DynGenFunc*)retval;
} }
@ -455,7 +454,7 @@ static DynGenFunc* _DynGen_DispatchPageReset()
{ {
u8* retval = xGetPtr(); u8* retval = xGetPtr();
xEMMS(); xEMMS();
xCALL(dyna_page_reset); xFastCall(dyna_page_reset);
xJMP(ExitRecompiledCode); xJMP(ExitRecompiledCode);
return (DynGenFunc*)retval; return (DynGenFunc*)retval;
} }
@ -916,7 +915,7 @@ void SetBranchReg( u32 reg )
// xCMP(ptr32[&cpuRegs.pc], 0); // xCMP(ptr32[&cpuRegs.pc], 0);
// j8Ptr[5] = JNE8(0); // j8Ptr[5] = JNE8(0);
// xCALL((void*)(uptr)tempfn); // xFastCall((void*)(uptr)tempfn);
// x86SetJ8( j8Ptr[5] ); // x86SetJ8( j8Ptr[5] );
iFlushCall(FLUSH_EVERYTHING); iFlushCall(FLUSH_EVERYTHING);
@ -1201,11 +1200,11 @@ void recMemcheck(u32 op, u32 bits, bool store)
if (bits == 128) if (bits == 128)
xAND(ecx, ~0x0F); xAND(ecx, ~0x0F);
xCALL(standardizeBreakpointAddress); xFastCall(standardizeBreakpointAddress, ecx);
xMOV(ecx,eax); xMOV(ecx,eax);
xMOV(edx,eax); xMOV(edx,eax);
xADD(edx,bits/8); xADD(edx,bits/8);
// ecx = access address // ecx = access address
// edx = access address+size // edx = access address+size
@ -1220,11 +1219,11 @@ void recMemcheck(u32 op, u32 bits, bool store)
continue; continue;
// logic: memAddress < bpEnd && bpStart < memAddress+memSize // logic: memAddress < bpEnd && bpStart < memAddress+memSize
xMOV(eax,standardizeBreakpointAddress(checks[i].end)); xMOV(eax,standardizeBreakpointAddress(checks[i].end));
xCMP(ecx,eax); // address < end xCMP(ecx,eax); // address < end
xForwardJGE8 next1; // if address >= end then goto next1 xForwardJGE8 next1; // if address >= end then goto next1
xMOV(eax,standardizeBreakpointAddress(checks[i].start)); xMOV(eax,standardizeBreakpointAddress(checks[i].start));
xCMP(eax,edx); // start < address+size xCMP(eax,edx); // start < address+size
xForwardJGE8 next2; // if start >= address+size then goto next2 xForwardJGE8 next2; // if start >= address+size then goto next2
@ -1232,10 +1231,10 @@ void recMemcheck(u32 op, u32 bits, bool store)
// hit the breakpoint // hit the breakpoint
if (checks[i].result & MEMCHECK_LOG) { if (checks[i].result & MEMCHECK_LOG) {
xMOV(edx, store); xMOV(edx, store);
xCALL(&dynarecMemLogcheck); xFastCall(dynarecMemLogcheck, ecx, edx);
} }
if (checks[i].result & MEMCHECK_BREAK) { if (checks[i].result & MEMCHECK_BREAK) {
xCALL(&dynarecMemcheck); xFastCall(dynarecMemcheck);
} }
next1.SetTarget(); next1.SetTarget();
@ -1248,7 +1247,7 @@ void encodeBreakpoint()
if (isBreakpointNeeded(pc) != 0) if (isBreakpointNeeded(pc) != 0)
{ {
iFlushCall(FLUSH_EVERYTHING|FLUSH_PC); iFlushCall(FLUSH_EVERYTHING|FLUSH_PC);
xCALL(&dynarecCheckBreakpoint); xFastCall(dynarecCheckBreakpoint);
} }
} }
@ -1297,7 +1296,7 @@ void recompileNextInstruction(int delayslot)
s_pCode = (int *)PSM( pc ); s_pCode = (int *)PSM( pc );
pxAssert(s_pCode); pxAssert(s_pCode);
if( IsDebugBuild ) if( IsDebugBuild )
xMOV(eax, pc); // acts as a tag for delimiting recompiled instructions when viewing x86 disasm. xMOV(eax, pc); // acts as a tag for delimiting recompiled instructions when viewing x86 disasm.
@ -1660,7 +1659,7 @@ static void __fastcall recRecompile( const u32 startpc )
if (0x8000d618 == startpc) if (0x8000d618 == startpc)
DbgCon.WriteLn("Compiling block @ 0x%08x", startpc); DbgCon.WriteLn("Compiling block @ 0x%08x", startpc);
s_pCurBlock = PC_GETBLOCK(startpc); s_pCurBlock = PC_GETBLOCK(startpc);
pxAssert(s_pCurBlock->GetFnptr() == (uptr)JITCompile pxAssert(s_pCurBlock->GetFnptr() == (uptr)JITCompile
@ -1674,14 +1673,14 @@ static void __fastcall recRecompile( const u32 startpc )
pxAssert(s_pCurBlockEx); pxAssert(s_pCurBlockEx);
if (g_SkipBiosHack && HWADDR(startpc) == EELOAD_START) { if (g_SkipBiosHack && HWADDR(startpc) == EELOAD_START) {
xCALL(eeloadReplaceOSDSYS); xFastCall(eeloadReplaceOSDSYS);
xCMP(ptr32[&cpuRegs.pc], startpc); xCMP(ptr32[&cpuRegs.pc], startpc);
xJNE(DispatcherReg); xJNE(DispatcherReg);
} }
// this is the only way patches get applied, doesn't depend on a hack // this is the only way patches get applied, doesn't depend on a hack
if (HWADDR(startpc) == ElfEntry) { if (HWADDR(startpc) == ElfEntry) {
xCALL(eeGameStarting); xFastCall(eeGameStarting);
// Apply patch as soon as possible. Normally it is done in // Apply patch as soon as possible. Normally it is done in
// eeGameStarting but first block is already compiled. // eeGameStarting but first block is already compiled.
// //
@ -1711,20 +1710,18 @@ static void __fastcall recRecompile( const u32 startpc )
// [TODO] : These must be enabled from the GUI or INI to be used, otherwise the // [TODO] : These must be enabled from the GUI or INI to be used, otherwise the
// code that calls PreBlockCheck will not be generated. // code that calls PreBlockCheck will not be generated.
xMOV(ecx, pc); xFastCall(PreBlockCheck, pc);
xCALL(PreBlockCheck);
} }
if (EmuConfig.Gamefixes.GoemonTlbHack) { if (EmuConfig.Gamefixes.GoemonTlbHack) {
if (pc == 0x33ad48 || pc == 0x35060c) { if (pc == 0x33ad48 || pc == 0x35060c) {
// 0x33ad48 and 0x35060c are the return address of the function (0x356250) that populate the TLB cache // 0x33ad48 and 0x35060c are the return address of the function (0x356250) that populate the TLB cache
xCALL(GoemonPreloadTlb); xFastCall(GoemonPreloadTlb);
} else if (pc == 0x3563b8) { } else if (pc == 0x3563b8) {
// Game will unmap some virtual addresses. If a constant address were hardcoded in the block, we would be in a bad situation. // Game will unmap some virtual addresses. If a constant address were hardcoded in the block, we would be in a bad situation.
AtomicExchange( eeRecNeedsReset, true ); AtomicExchange( eeRecNeedsReset, true );
// 0x3563b8 is the start address of the function that invalidate entry in TLB cache // 0x3563b8 is the start address of the function that invalidate entry in TLB cache
xMOV(ecx, ptr[&cpuRegs.GPR.n.a0.UL[ 0 ] ]); xFastCall(GoemonUnloadTlb, ptr[&cpuRegs.GPR.n.a0.UL[0]]);
xCALL(GoemonUnloadTlb);
} }
} }
@ -1745,7 +1742,7 @@ static void __fastcall recRecompile( const u32 startpc )
while(1) { while(1) {
BASEBLOCK* pblock = PC_GETBLOCK(i); BASEBLOCK* pblock = PC_GETBLOCK(i);
// stop before breakpoints // stop before breakpoints
if (isBreakpointNeeded(i) != 0 || isMemcheckNeeded(i) != 0) if (isBreakpointNeeded(i) != 0 || isMemcheckNeeded(i) != 0)
{ {

View File

@ -396,7 +396,7 @@ EERECOMPILE_CODE0(BNEL, XMMINFO_READS|XMMINFO_READT);
// xMOV(ptr32[(u32*)((int)&cpuRegs.code)], cpuRegs.code ); // xMOV(ptr32[(u32*)((int)&cpuRegs.code)], cpuRegs.code );
// xMOV(ptr32[(u32*)((int)&cpuRegs.pc)], pc ); // xMOV(ptr32[(u32*)((int)&cpuRegs.pc)], pc );
// iFlushCall(FLUSH_EVERYTHING); // iFlushCall(FLUSH_EVERYTHING);
// xCALL((void*)(int)BLTZAL ); // xFastCall((void*)(int)BLTZAL );
// branch = 2; // branch = 2;
//} //}

View File

@ -310,7 +310,7 @@ void vtlb_dynarec_init()
// jump to the indirect handler, which is a __fastcall C++ function. // jump to the indirect handler, which is a __fastcall C++ function.
// [ecx is address, edx is data] // [ecx is address, edx is data]
xCALL( ptr32[(eax*4) + vtlbdata.RWFT[bits][mode]] ); xFastCall(ptr32[(eax*4) + vtlbdata.RWFT[bits][mode]], ecx, edx);
if (!mode) if (!mode)
{ {
@ -406,8 +406,7 @@ void vtlb_DynGenRead64_Const( u32 bits, u32 addr_const )
} }
iFlushCall(FLUSH_FULLVTLB); iFlushCall(FLUSH_FULLVTLB);
xMOV( ecx, paddr ); xFastCall( vtlbdata.RWFT[szidx][0][handler], paddr );
xCALL( vtlbdata.RWFT[szidx][0][handler] );
} }
} }
@ -470,8 +469,7 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const )
else else
{ {
iFlushCall(FLUSH_FULLVTLB); iFlushCall(FLUSH_FULLVTLB);
xMOV( ecx, paddr ); xFastCall( vtlbdata.RWFT[szidx][0][handler], paddr );
xCALL( vtlbdata.RWFT[szidx][0][handler] );
// perform sign extension on the result: // perform sign extension on the result:
@ -561,8 +559,7 @@ void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const )
} }
iFlushCall(FLUSH_FULLVTLB); iFlushCall(FLUSH_FULLVTLB);
xMOV( ecx, paddr ); xFastCall( vtlbdata.RWFT[szidx][1][handler], paddr, edx );
xCALL( vtlbdata.RWFT[szidx][1][handler] );
} }
} }

View File

@ -57,8 +57,8 @@ void mVUDTendProgram(mV, microFlagCycles* mFC, int isEbit) {
mVU_XGKICK_DELAY(mVU); mVU_XGKICK_DELAY(mVU);
} }
if (doEarlyExit(mVU)) { if (doEarlyExit(mVU)) {
if (!isVU1) xCALL(mVU0clearlpStateJIT); if (!isVU1) xFastCall(mVU0clearlpStateJIT);
else xCALL(mVU1clearlpStateJIT); else xFastCall(mVU1clearlpStateJIT);
} }
} }
@ -117,9 +117,9 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
} }
if (doEarlyExit(mVU)) { if (doEarlyExit(mVU)) {
if (!isVU1) if (!isVU1)
xCALL(mVU0clearlpStateJIT); xFastCall(mVU0clearlpStateJIT);
else else
xCALL(mVU1clearlpStateJIT); xFastCall(mVU1clearlpStateJIT);
} }
} }
@ -192,8 +192,8 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump) {
xJMP(mVU.exitFunct); xJMP(mVU.exitFunct);
} }
if (!mVU.index) xCALL(mVUcompileJIT<0>); //(u32 startPC, uptr pState) if (!mVU.index) xFastCall(mVUcompileJIT<0>, gprT2, gprT3); //(u32 startPC, uptr pState)
else xCALL(mVUcompileJIT<1>); else xFastCall(mVUcompileJIT<1>, gprT2, gprT3);
mVUrestoreRegs(mVU); mVUrestoreRegs(mVU);
xJMP(gprT1); // Jump to rec-code address xJMP(gprT1); // Jump to rec-code address

View File

@ -194,10 +194,8 @@ __fi void handleBadOp(mV, int count) {
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if (mVUinfo.isBadOp) { if (mVUinfo.isBadOp) {
mVUbackupRegs(mVU, true); mVUbackupRegs(mVU, true);
xMOV(gprT2, mVU.prog.cur->idx); if (!isVU1) xFastCall(mVUbadOp0, mVU.prog.cur->idx, xPC);
xMOV(gprT3, xPC); else xFastCall(mVUbadOp1, mVU.prog.cur->idx, xPC);
if (!isVU1) xCALL(mVUbadOp0);
else xCALL(mVUbadOp1);
mVUrestoreRegs(mVU, true); mVUrestoreRegs(mVU, true);
} }
#endif #endif
@ -345,9 +343,8 @@ void mVUsetCycles(mV) {
void mVUdebugPrintBlocks(microVU& mVU, bool isEndPC) { void mVUdebugPrintBlocks(microVU& mVU, bool isEndPC) {
if (mVUdebugNow) { if (mVUdebugNow) {
mVUbackupRegs(mVU, true); mVUbackupRegs(mVU, true);
xMOV(gprT2, xPC); if (isEndPC) xFastCall(mVUprintPC2, xPC);
if (isEndPC) xCALL(mVUprintPC2); else xFastCall(mVUprintPC1, xPC);
else xCALL(mVUprintPC1);
mVUrestoreRegs(mVU, true); mVUrestoreRegs(mVU, true);
} }
} }
@ -375,9 +372,7 @@ void mVUtestCycles(microVU& mVU) {
// TEST32ItoM((uptr)&mVU.regs().flags, VUFLAG_MFLAGSET); // TEST32ItoM((uptr)&mVU.regs().flags, VUFLAG_MFLAGSET);
// xFowardJZ32 vu0jmp; // xFowardJZ32 vu0jmp;
// mVUbackupRegs(mVU, true); // mVUbackupRegs(mVU, true);
// xMOV(gprT2, mVU.prog.cur->idx); // xFastCall(mVUwarning0, mVU.prog.cur->idx, xPC); // VU0 is allowed early exit for COP2 Interlock Simulation
// xMOV(gprT3, xPC);
// xCALL(mVUwarning0); // VU0 is allowed early exit for COP2 Interlock Simulation
// mVUrestoreRegs(mVU, true); // mVUrestoreRegs(mVU, true);
mVUsavePipelineState(mVU); mVUsavePipelineState(mVU);
mVUendProgram(mVU, NULL, 0); mVUendProgram(mVU, NULL, 0);
@ -385,9 +380,7 @@ void mVUtestCycles(microVU& mVU) {
} }
else { else {
mVUbackupRegs(mVU, true); mVUbackupRegs(mVU, true);
xMOV(gprT2, mVU.prog.cur->idx); xFastCall(mVUwarning1, mVU.prog.cur->idx, xPC);
xMOV(gprT3, xPC);
xCALL(mVUwarning1);
mVUrestoreRegs(mVU, true); mVUrestoreRegs(mVU, true);
mVUsavePipelineState(mVU); mVUsavePipelineState(mVU);
mVUendProgram(mVU, NULL, 0); mVUendProgram(mVU, NULL, 0);

View File

@ -27,8 +27,8 @@ void mVUdispatcherAB(mV) {
xScopedStackFrame frame(false, true); xScopedStackFrame frame(false, true);
// __fastcall = The caller has already put the needed parameters in ecx/edx: // __fastcall = The caller has already put the needed parameters in ecx/edx:
if (!isVU1) { xCALL(mVUexecuteVU0); } if (!isVU1) { xFastCall(mVUexecuteVU0, ecx, edx); }
else { xCALL(mVUexecuteVU1); } else { xFastCall(mVUexecuteVU1, ecx, edx); }
// Load VU's MXCSR state // Load VU's MXCSR state
xLDMXCSR(g_sseVUMXCSR); xLDMXCSR(g_sseVUMXCSR);
@ -61,8 +61,8 @@ void mVUdispatcherAB(mV) {
// __fastcall = The first two DWORD or smaller arguments are passed in ECX and EDX registers; // __fastcall = The first two DWORD or smaller arguments are passed in ECX and EDX registers;
// all other arguments are passed right to left. // all other arguments are passed right to left.
if (!isVU1) { xCALL(mVUcleanUpVU0); } if (!isVU1) { xFastCall(mVUcleanUpVU0); }
else { xCALL(mVUcleanUpVU1); } else { xFastCall(mVUcleanUpVU1); }
} }
xRET(); xRET();

View File

@ -1219,8 +1219,7 @@ static __fi void mVU_XGKICK_DELAY(mV) {
xMOV (ptr32[&mVU.resumePtrXG], (uptr)xGetPtr() + 10 + 6); xMOV (ptr32[&mVU.resumePtrXG], (uptr)xGetPtr() + 10 + 6);
xJcc32(Jcc_NotZero, (uptr)mVU.exitFunctXG - ((uptr)xGetPtr()+6)); xJcc32(Jcc_NotZero, (uptr)mVU.exitFunctXG - ((uptr)xGetPtr()+6));
#endif #endif
xMOV(gprT2, ptr32[&mVU.VIxgkick]); xFastCall(mVU_XGKICK_, ptr32[&mVU.VIxgkick]);
xCALL(mVU_XGKICK_);
mVUrestoreRegs(mVU); mVUrestoreRegs(mVU);
} }

View File

@ -249,15 +249,15 @@ void recBC2TL() { _setupBranchTest(JZ32, true); }
void COP2_Interlock(bool mBitSync) { void COP2_Interlock(bool mBitSync) {
if (cpuRegs.code & 1) { if (cpuRegs.code & 1) {
iFlushCall(FLUSH_EVERYTHING | FLUSH_PC); iFlushCall(FLUSH_EVERYTHING | FLUSH_PC);
if (mBitSync) xCALL(_vu0WaitMicro); if (mBitSync) xFastCall(_vu0WaitMicro);
else xCALL(_vu0FinishMicro); else xFastCall(_vu0FinishMicro);
} }
} }
void TEST_FBRST_RESET(FnType_Void* resetFunct, int vuIndex) { void TEST_FBRST_RESET(FnType_Void* resetFunct, int vuIndex) {
xTEST(eax, (vuIndex) ? 0x200 : 0x002); xTEST(eax, (vuIndex) ? 0x200 : 0x002);
xForwardJZ8 skip; xForwardJZ8 skip;
xCALL(resetFunct); xFastCall(resetFunct);
xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]); xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
skip.SetTarget(); skip.SetTarget();
} }
@ -316,8 +316,8 @@ static void recCTC2() {
xMOV(ecx, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]); xMOV(ecx, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
} }
else xXOR(ecx, ecx); else xXOR(ecx, ecx);
xCALL(vu1ExecMicro); xFastCall(vu1ExecMicro, ecx);
xCALL(vif1VUFinish); xFastCall(vif1VUFinish);
break; break;
case REG_FBRST: case REG_FBRST:
if (!_Rt_) { if (!_Rt_) {
@ -336,8 +336,7 @@ static void recCTC2() {
// Executing vu0 block here fixes the intro of Ratchet and Clank // Executing vu0 block here fixes the intro of Ratchet and Clank
// sVU's COP2 has a comment that "Donald Duck" needs this too... // sVU's COP2 has a comment that "Donald Duck" needs this too...
if (_Rd_) _eeMoveGPRtoM((uptr)&vu0Regs.VI[_Rd_].UL, _Rt_); if (_Rd_) _eeMoveGPRtoM((uptr)&vu0Regs.VI[_Rd_].UL, _Rt_);
xMOV(ecx, (uptr)CpuVU0); xFastCall(BaseVUmicroCPU::ExecuteBlockJIT, (uptr)CpuVU0);
xCALL(BaseVUmicroCPU::ExecuteBlockJIT);
break; break;
} }
} }