mirror of https://github.com/PCSX2/pcsx2.git
pcsx2: manually cast function pointer to void*
Templace is nicer but give a hard time to compiler. New version compile in both gcc&clang without hack v2: add an uptr cast too for VS2013 sigh... v3: use an ugly function pointer cast to please VS2013
This commit is contained in:
parent
15db7eeb81
commit
cc68776069
common/include/x86emitter/implement
pcsx2/x86
|
@ -19,23 +19,6 @@
|
||||||
|
|
||||||
namespace x86Emitter {
|
namespace x86Emitter {
|
||||||
|
|
||||||
#ifdef __GNUG__
|
|
||||||
// GCC has a bug that causes the templated function handler for Jmp/Call emitters to generate
|
|
||||||
// bad asm code. (error is something like "7#*_uber_379s_mangled_$&02_name is already defined!")
|
|
||||||
// Using GCC's always_inline attribute fixes it. This differs from __fi in that it
|
|
||||||
// inlines *even in debug builds* which is (usually) undesirable.
|
|
||||||
// ... except when it avoids compiler bugs.
|
|
||||||
|
|
||||||
// Note: I try with -fabi-version=6 without success
|
|
||||||
// {standard input}: Assembler messages:
|
|
||||||
// {standard input}:30773: Error: symbol `_ZNK10x86Emitter13xImpl_JmpCallclIFvvEEEvPT_' is already defined
|
|
||||||
// pcsx2/CMakeFiles/PCSX2.dir/build.make:4550: recipe for target 'pcsx2/CMakeFiles/PCSX2.dir/x86/ix86-32/iR5900-32.cpp.o' failed
|
|
||||||
|
|
||||||
# define __always_inline_tmpl_fail __attribute__((always_inline))
|
|
||||||
#else
|
|
||||||
# define __always_inline_tmpl_fail
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward );
|
extern void xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward );
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -48,8 +31,7 @@ struct xImpl_JmpCall
|
||||||
|
|
||||||
// Special form for calling functions. This form automatically resolves the
|
// Special form for calling functions. This form automatically resolves the
|
||||||
// correct displacement based on the size of the instruction being generated.
|
// correct displacement based on the size of the instruction being generated.
|
||||||
template< typename T > __fi __always_inline_tmpl_fail
|
void operator()( void* func ) const
|
||||||
void operator()( T* func ) const
|
|
||||||
{
|
{
|
||||||
if( isJmp )
|
if( isJmp )
|
||||||
xJccKnownTarget( Jcc_Unconditional, (void*)(uptr)func, false ); // double cast to/from (uptr) needed to appease GCC
|
xJccKnownTarget( Jcc_Unconditional, (void*)(uptr)func, false ); // double cast to/from (uptr) needed to appease GCC
|
||||||
|
@ -79,35 +61,34 @@ struct xImpl_FastCall
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
|
||||||
#define XFASTCALL \
|
#define XFASTCALL \
|
||||||
xCALL(func);
|
xCALL(f);
|
||||||
|
|
||||||
#define XFASTCALL1 \
|
#define XFASTCALL1 \
|
||||||
xMOV(rdi, a1); \
|
xMOV(rdi, a1); \
|
||||||
xCALL(func);
|
xCALL(f);
|
||||||
|
|
||||||
#define XFASTCALL2 \
|
#define XFASTCALL2 \
|
||||||
xMOV(rdi, a1); \
|
xMOV(rdi, a1); \
|
||||||
xMOV(rsi, a2); \
|
xMOV(rsi, a2); \
|
||||||
xCALL(func);
|
xCALL(f);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define XFASTCALL \
|
#define XFASTCALL \
|
||||||
xCALL(func);
|
xCALL(f);
|
||||||
|
|
||||||
#define XFASTCALL1 \
|
#define XFASTCALL1 \
|
||||||
xMOV(ecx, a1); \
|
xMOV(ecx, a1); \
|
||||||
xCALL(func);
|
xCALL(f);
|
||||||
|
|
||||||
#define XFASTCALL2 \
|
#define XFASTCALL2 \
|
||||||
xMOV(ecx, a1); \
|
xMOV(ecx, a1); \
|
||||||
xMOV(edx, a2); \
|
xMOV(edx, a2); \
|
||||||
xCALL(func);
|
xCALL(f);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template< typename T > __fi __always_inline_tmpl_fail
|
void operator()( void* f, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const
|
||||||
void operator()( T* func, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const
|
|
||||||
{
|
{
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
if (a1.IsEmpty()) {
|
if (a1.IsEmpty()) {
|
||||||
|
@ -128,9 +109,11 @@ struct xImpl_FastCall
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T > __fi __always_inline_tmpl_fail
|
template< typename T > __fi
|
||||||
void operator()( T* func, u32 a1, const xRegisterLong& a2) const
|
void operator()( T* func, u32 a1, const xRegisterLong& a2) const
|
||||||
{
|
{
|
||||||
|
void* f = (void*)func;
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
XFASTCALL2;
|
XFASTCALL2;
|
||||||
#else
|
#else
|
||||||
|
@ -138,9 +121,11 @@ struct xImpl_FastCall
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T > __fi __always_inline_tmpl_fail
|
template< typename T > __fi
|
||||||
void operator()( T* func, const xIndirectVoid& a1) const
|
void operator()( T* func, const xIndirectVoid& a1) const
|
||||||
{
|
{
|
||||||
|
void* f = (void*)func;
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
XFASTCALL1;
|
XFASTCALL1;
|
||||||
#else
|
#else
|
||||||
|
@ -148,9 +133,11 @@ struct xImpl_FastCall
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T > __fi __always_inline_tmpl_fail
|
template< typename T > __fi
|
||||||
void operator()( T* func, u32 a1, u32 a2) const
|
void operator()( T* func, u32 a1, u32 a2) const
|
||||||
{
|
{
|
||||||
|
void* f = (void*)func;
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
XFASTCALL2;
|
XFASTCALL2;
|
||||||
#else
|
#else
|
||||||
|
@ -158,9 +145,11 @@ struct xImpl_FastCall
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T > __fi __always_inline_tmpl_fail
|
template< typename T > __fi
|
||||||
void operator()( T* func, u32 a1) const
|
void operator()( T* func, u32 a1) const
|
||||||
{
|
{
|
||||||
|
void* f = (void*)func;
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
XFASTCALL1;
|
XFASTCALL1;
|
||||||
#else
|
#else
|
||||||
|
@ -168,7 +157,7 @@ struct xImpl_FastCall
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const xIndirect32& func, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const
|
void operator()(const xIndirect32& f, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const
|
||||||
{
|
{
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
if (a1.IsEmpty()) {
|
if (a1.IsEmpty()) {
|
||||||
|
|
|
@ -169,13 +169,13 @@ void recMFC0()
|
||||||
else if (0 == (_Imm_ & 2)) // MFPC 0, only LSB of register matters
|
else if (0 == (_Imm_ & 2)) // MFPC 0, only LSB of register matters
|
||||||
{
|
{
|
||||||
iFlushCall(FLUSH_INTERPRETER);
|
iFlushCall(FLUSH_INTERPRETER);
|
||||||
xFastCall(COP0_UpdatePCCR);
|
xFastCall((void*)COP0_UpdatePCCR);
|
||||||
xMOV(eax, ptr[&cpuRegs.PERF.n.pcr0]);
|
xMOV(eax, ptr[&cpuRegs.PERF.n.pcr0]);
|
||||||
}
|
}
|
||||||
else // MFPC 1
|
else // MFPC 1
|
||||||
{
|
{
|
||||||
iFlushCall(FLUSH_INTERPRETER);
|
iFlushCall(FLUSH_INTERPRETER);
|
||||||
xFastCall(COP0_UpdatePCCR);
|
xFastCall((void*)COP0_UpdatePCCR);
|
||||||
xMOV(eax, ptr[&cpuRegs.PERF.n.pcr1]);
|
xMOV(eax, ptr[&cpuRegs.PERF.n.pcr1]);
|
||||||
}
|
}
|
||||||
_deleteEEreg(_Rt_, 0);
|
_deleteEEreg(_Rt_, 0);
|
||||||
|
@ -206,7 +206,7 @@ void recMTC0()
|
||||||
{
|
{
|
||||||
case 12:
|
case 12:
|
||||||
iFlushCall(FLUSH_INTERPRETER);
|
iFlushCall(FLUSH_INTERPRETER);
|
||||||
xFastCall(WriteCP0Status, g_cpuConstRegs[_Rt_].UL[0] );
|
xFastCall((void*)WriteCP0Status, g_cpuConstRegs[_Rt_].UL[0] );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
|
@ -222,9 +222,9 @@ void recMTC0()
|
||||||
break;
|
break;
|
||||||
// Updates PCRs and sets the PCCR.
|
// Updates PCRs and sets the PCCR.
|
||||||
iFlushCall(FLUSH_INTERPRETER);
|
iFlushCall(FLUSH_INTERPRETER);
|
||||||
xFastCall(COP0_UpdatePCCR);
|
xFastCall((void*)COP0_UpdatePCCR);
|
||||||
xMOV(ptr32[&cpuRegs.PERF.n.pccr], g_cpuConstRegs[_Rt_].UL[0]);
|
xMOV(ptr32[&cpuRegs.PERF.n.pccr], g_cpuConstRegs[_Rt_].UL[0]);
|
||||||
xFastCall(COP0_DiagnosticPCCR);
|
xFastCall((void*)COP0_DiagnosticPCCR);
|
||||||
}
|
}
|
||||||
else if (0 == (_Imm_ & 2)) // MTPC 0, only LSB of register matters
|
else if (0 == (_Imm_ & 2)) // MTPC 0, only LSB of register matters
|
||||||
{
|
{
|
||||||
|
@ -256,7 +256,7 @@ void recMTC0()
|
||||||
case 12:
|
case 12:
|
||||||
iFlushCall(FLUSH_INTERPRETER);
|
iFlushCall(FLUSH_INTERPRETER);
|
||||||
_eeMoveGPRtoR(ecx, _Rt_);
|
_eeMoveGPRtoR(ecx, _Rt_);
|
||||||
xFastCall(WriteCP0Status, ecx );
|
xFastCall((void*)WriteCP0Status, ecx );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
|
@ -271,9 +271,9 @@ void recMTC0()
|
||||||
if (0 != (_Imm_ & 0x3E)) // only effective when the register is 0
|
if (0 != (_Imm_ & 0x3E)) // only effective when the register is 0
|
||||||
break;
|
break;
|
||||||
iFlushCall(FLUSH_INTERPRETER);
|
iFlushCall(FLUSH_INTERPRETER);
|
||||||
xFastCall(COP0_UpdatePCCR);
|
xFastCall((void*)COP0_UpdatePCCR);
|
||||||
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_);
|
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_);
|
||||||
xFastCall(COP0_DiagnosticPCCR);
|
xFastCall((void*)COP0_DiagnosticPCCR);
|
||||||
}
|
}
|
||||||
else if (0 == (_Imm_ & 2)) // MTPC 0, only LSB of register matters
|
else if (0 == (_Imm_ & 2)) // MTPC 0, only LSB of register matters
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,7 +128,7 @@ static DynGenFunc* _DynGen_JITCompile()
|
||||||
|
|
||||||
u8* retval = xGetPtr();
|
u8* retval = xGetPtr();
|
||||||
|
|
||||||
xFastCall(iopRecRecompile, ptr[&psxRegs.pc] );
|
xFastCall((void*)iopRecRecompile, ptr[&psxRegs.pc] );
|
||||||
|
|
||||||
xMOV( eax, ptr[&psxRegs.pc] );
|
xMOV( eax, ptr[&psxRegs.pc] );
|
||||||
xMOV( ebx, eax );
|
xMOV( ebx, eax );
|
||||||
|
@ -142,7 +142,7 @@ static DynGenFunc* _DynGen_JITCompile()
|
||||||
static DynGenFunc* _DynGen_JITCompileInBlock()
|
static DynGenFunc* _DynGen_JITCompileInBlock()
|
||||||
{
|
{
|
||||||
u8* retval = xGetPtr();
|
u8* retval = xGetPtr();
|
||||||
xJMP( iopJITCompile );
|
xJMP( (void*)iopJITCompile );
|
||||||
return (DynGenFunc*)retval;
|
return (DynGenFunc*)retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
{ // Properly scope the frame prologue/epilogue
|
{ // Properly scope the frame prologue/epilogue
|
||||||
xScopedStackFrame frame(IsDevBuild);
|
xScopedStackFrame frame(IsDevBuild);
|
||||||
|
|
||||||
xJMP(iopDispatcherReg);
|
xJMP((void*)iopDispatcherReg);
|
||||||
|
|
||||||
// Save an exit point
|
// Save an exit point
|
||||||
iopExitRecompiledCode = (DynGenFunc*)xGetPtr();
|
iopExitRecompiledCode = (DynGenFunc*)xGetPtr();
|
||||||
|
@ -198,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();
|
||||||
xFastCall(recEventTest );
|
xFastCall((void*)recEventTest );
|
||||||
iopDispatcherReg = _DynGen_DispatcherReg();
|
iopDispatcherReg = _DynGen_DispatcherReg();
|
||||||
|
|
||||||
iopJITCompile = _DynGen_JITCompile();
|
iopJITCompile = _DynGen_JITCompile();
|
||||||
|
@ -520,15 +520,15 @@ void psxRecompileCodeConst1(R3000AFNPTR constcode, R3000AFNPTR_INFO noconstcode)
|
||||||
xMOV(ecx, (uptr)libname);
|
xMOV(ecx, (uptr)libname);
|
||||||
xMOV(edx, index);
|
xMOV(edx, index);
|
||||||
xPUSH((uptr)funcname);
|
xPUSH((uptr)funcname);
|
||||||
xCALL(irxImportLog);
|
xCALL((void*)irxImportLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
xFastCall(debug);
|
xFastCall((void*)debug);
|
||||||
#endif
|
#endif
|
||||||
irxHLE hle = irxImportHLE(libname, index);
|
irxHLE hle = irxImportHLE(libname, index);
|
||||||
if (hle) {
|
if (hle) {
|
||||||
xFastCall(hle);
|
xFastCall((void*)hle);
|
||||||
xCMP(eax, 0);
|
xCMP(eax, 0);
|
||||||
xJNE(iopDispatcherReg);
|
xJNE(iopDispatcherReg);
|
||||||
}
|
}
|
||||||
|
@ -908,7 +908,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
|
||||||
xSUB(ptr32[&iopCycleEE], eax);
|
xSUB(ptr32[&iopCycleEE], eax);
|
||||||
xJLE(iopExitRecompiledCode);
|
xJLE(iopExitRecompiledCode);
|
||||||
|
|
||||||
xFastCall(iopEventTest);
|
xFastCall((void*)iopEventTest);
|
||||||
|
|
||||||
if( newpc != 0xffffffff )
|
if( newpc != 0xffffffff )
|
||||||
{
|
{
|
||||||
|
@ -930,7 +930,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
|
||||||
xSUB(eax, ptr32[&g_iopNextEventCycle]);
|
xSUB(eax, ptr32[&g_iopNextEventCycle]);
|
||||||
xForwardJS<u8> nointerruptpending;
|
xForwardJS<u8> nointerruptpending;
|
||||||
|
|
||||||
xFastCall(iopEventTest);
|
xFastCall((void*)iopEventTest);
|
||||||
|
|
||||||
if( newpc != 0xffffffff ) {
|
if( newpc != 0xffffffff ) {
|
||||||
xCMP(ptr32[&psxRegs.pc], newpc);
|
xCMP(ptr32[&psxRegs.pc], newpc);
|
||||||
|
@ -967,7 +967,7 @@ void rpsxSYSCALL()
|
||||||
|
|
||||||
//xMOV( ecx, 0x20 ); // exception code
|
//xMOV( ecx, 0x20 ); // exception code
|
||||||
//xMOV( edx, psxbranch==1 ); // branch delay slot?
|
//xMOV( edx, psxbranch==1 ); // branch delay slot?
|
||||||
xFastCall(psxException, 0x20, psxbranch == 1 );
|
xFastCall((void*)psxException, 0x20, psxbranch == 1 );
|
||||||
|
|
||||||
xCMP(ptr32[&psxRegs.pc], psxpc-4);
|
xCMP(ptr32[&psxRegs.pc], psxpc-4);
|
||||||
j8Ptr[0] = JE8(0);
|
j8Ptr[0] = JE8(0);
|
||||||
|
@ -990,7 +990,7 @@ void rpsxBREAK()
|
||||||
|
|
||||||
//xMOV( ecx, 0x24 ); // exception code
|
//xMOV( ecx, 0x24 ); // exception code
|
||||||
//xMOV( edx, psxbranch==1 ); // branch delay slot?
|
//xMOV( edx, psxbranch==1 ); // branch delay slot?
|
||||||
xFastCall(psxException, 0x24, psxbranch == 1 );
|
xFastCall((void*)psxException, 0x24, psxbranch == 1 );
|
||||||
|
|
||||||
xCMP(ptr32[&psxRegs.pc], psxpc-4);
|
xCMP(ptr32[&psxRegs.pc], psxpc-4);
|
||||||
j8Ptr[0] = JE8(0);
|
j8Ptr[0] = JE8(0);
|
||||||
|
@ -1113,7 +1113,7 @@ static void __fastcall iopRecRecompile( const u32 startpc )
|
||||||
|
|
||||||
if( IsDebugBuild )
|
if( IsDebugBuild )
|
||||||
{
|
{
|
||||||
xFastCall(PreBlockCheck, psxpc);
|
xFastCall((void*)PreBlockCheck, psxpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// go until the next branch
|
// go until the next branch
|
||||||
|
|
|
@ -631,7 +631,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_);
|
||||||
xFastCall(iopMemRead8, ecx ); // returns value in EAX
|
xFastCall((void*)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);
|
||||||
|
@ -647,7 +647,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_);
|
||||||
xFastCall(iopMemRead8, ecx ); // returns value in EAX
|
xFastCall((void*)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);
|
||||||
|
@ -663,7 +663,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_);
|
||||||
xFastCall(iopMemRead16, ecx ); // returns value in EAX
|
xFastCall((void*)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);
|
||||||
|
@ -679,7 +679,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_);
|
||||||
xFastCall(iopMemRead16, ecx ); // returns value in EAX
|
xFastCall((void*)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);
|
||||||
|
@ -700,7 +700,7 @@ static void rpsxLW()
|
||||||
xTEST(ecx, 0x10000000);
|
xTEST(ecx, 0x10000000);
|
||||||
j8Ptr[0] = JZ8(0);
|
j8Ptr[0] = JZ8(0);
|
||||||
|
|
||||||
xFastCall(iopMemRead32, ecx ); // returns value in EAX
|
xFastCall((void*)iopMemRead32, ecx ); // returns value in EAX
|
||||||
if (_Rt_) {
|
if (_Rt_) {
|
||||||
xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax);
|
xMOV(ptr[&psxRegs.GPR.r[_Rt_]], eax);
|
||||||
}
|
}
|
||||||
|
@ -728,7 +728,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_]] );
|
||||||
xFastCall(iopMemWrite8, ecx, edx );
|
xFastCall((void*)iopMemWrite8, ecx, edx );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpsxSH()
|
static void rpsxSH()
|
||||||
|
@ -739,7 +739,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_]] );
|
||||||
xFastCall(iopMemWrite16, ecx, edx );
|
xFastCall((void*)iopMemWrite16, ecx, edx );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpsxSW()
|
static void rpsxSW()
|
||||||
|
@ -750,7 +750,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_]] );
|
||||||
xFastCall(iopMemWrite32, ecx, edx );
|
xFastCall((void*)iopMemWrite32, ecx, edx );
|
||||||
}
|
}
|
||||||
|
|
||||||
//// SLL
|
//// SLL
|
||||||
|
|
|
@ -307,7 +307,7 @@ void recBranchCall( void (*func)() )
|
||||||
void recCall( void (*func)() )
|
void recCall( void (*func)() )
|
||||||
{
|
{
|
||||||
iFlushCall(FLUSH_INTERPRETER);
|
iFlushCall(FLUSH_INTERPRETER);
|
||||||
xFastCall(func);
|
xFastCall((void*)func);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =====================================================================================================
|
// =====================================================================================================
|
||||||
|
@ -347,7 +347,7 @@ static DynGenFunc* _DynGen_JITCompile()
|
||||||
|
|
||||||
u8* retval = xGetAlignedCallTarget();
|
u8* retval = xGetAlignedCallTarget();
|
||||||
|
|
||||||
xFastCall(recRecompile, ptr[&cpuRegs.pc] );
|
xFastCall((void*)recRecompile, ptr[&cpuRegs.pc] );
|
||||||
|
|
||||||
xMOV( eax, ptr[&cpuRegs.pc] );
|
xMOV( eax, ptr[&cpuRegs.pc] );
|
||||||
xMOV( ebx, eax );
|
xMOV( ebx, eax );
|
||||||
|
@ -361,7 +361,7 @@ static DynGenFunc* _DynGen_JITCompile()
|
||||||
static DynGenFunc* _DynGen_JITCompileInBlock()
|
static DynGenFunc* _DynGen_JITCompileInBlock()
|
||||||
{
|
{
|
||||||
u8* retval = xGetAlignedCallTarget();
|
u8* retval = xGetAlignedCallTarget();
|
||||||
xJMP( JITCompile );
|
xJMP( (void*)JITCompile );
|
||||||
return (DynGenFunc*)retval;
|
return (DynGenFunc*)retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ static DynGenFunc* _DynGen_DispatcherEvent()
|
||||||
{
|
{
|
||||||
u8* retval = xGetPtr();
|
u8* retval = xGetPtr();
|
||||||
|
|
||||||
xFastCall(recEventTest );
|
xFastCall((void*)recEventTest );
|
||||||
|
|
||||||
return (DynGenFunc*)retval;
|
return (DynGenFunc*)retval;
|
||||||
}
|
}
|
||||||
|
@ -397,7 +397,7 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
{ // Properly scope the frame prologue/epilogue
|
{ // Properly scope the frame prologue/epilogue
|
||||||
xScopedStackFrame frame(IsDevBuild);
|
xScopedStackFrame frame(IsDevBuild);
|
||||||
|
|
||||||
xJMP(DispatcherReg);
|
xJMP((void*)DispatcherReg);
|
||||||
|
|
||||||
// Save an exit point
|
// Save an exit point
|
||||||
ExitRecompiledCode = (DynGenFunc*)xGetPtr();
|
ExitRecompiledCode = (DynGenFunc*)xGetPtr();
|
||||||
|
@ -411,16 +411,16 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
static DynGenFunc* _DynGen_DispatchBlockDiscard()
|
static DynGenFunc* _DynGen_DispatchBlockDiscard()
|
||||||
{
|
{
|
||||||
u8* retval = xGetPtr();
|
u8* retval = xGetPtr();
|
||||||
xFastCall(dyna_block_discard);
|
xFastCall((void*)dyna_block_discard);
|
||||||
xJMP(ExitRecompiledCode);
|
xJMP((void*)ExitRecompiledCode);
|
||||||
return (DynGenFunc*)retval;
|
return (DynGenFunc*)retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DynGenFunc* _DynGen_DispatchPageReset()
|
static DynGenFunc* _DynGen_DispatchPageReset()
|
||||||
{
|
{
|
||||||
u8* retval = xGetPtr();
|
u8* retval = xGetPtr();
|
||||||
xFastCall(dyna_page_reset);
|
xFastCall((void*)dyna_page_reset);
|
||||||
xJMP(ExitRecompiledCode);
|
xJMP((void*)ExitRecompiledCode);
|
||||||
return (DynGenFunc*)retval;
|
return (DynGenFunc*)retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,7 +742,7 @@ void R5900::Dynarec::OpcodeImpl::recSYSCALL()
|
||||||
xADD(ptr32[&cpuRegs.cycle], scaleblockcycles());
|
xADD(ptr32[&cpuRegs.cycle], scaleblockcycles());
|
||||||
// Note: technically the address is 0x8000_0180 (or 0x180)
|
// Note: technically the address is 0x8000_0180 (or 0x180)
|
||||||
// (if CPU is booted)
|
// (if CPU is booted)
|
||||||
xJMP( DispatcherReg );
|
xJMP( (void*)DispatcherReg );
|
||||||
x86SetJ8(j8Ptr[0]);
|
x86SetJ8(j8Ptr[0]);
|
||||||
//g_branch = 2;
|
//g_branch = 2;
|
||||||
}
|
}
|
||||||
|
@ -757,7 +757,7 @@ void R5900::Dynarec::OpcodeImpl::recBREAK()
|
||||||
xCMP(ptr32[&cpuRegs.pc], pc);
|
xCMP(ptr32[&cpuRegs.pc], pc);
|
||||||
j8Ptr[0] = JE8(0);
|
j8Ptr[0] = JE8(0);
|
||||||
xADD(ptr32[&cpuRegs.cycle], scaleblockcycles());
|
xADD(ptr32[&cpuRegs.cycle], scaleblockcycles());
|
||||||
xJMP( DispatcherEvent );
|
xJMP( (void*)DispatcherEvent );
|
||||||
x86SetJ8(j8Ptr[0]);
|
x86SetJ8(j8Ptr[0]);
|
||||||
//g_branch = 2;
|
//g_branch = 2;
|
||||||
}
|
}
|
||||||
|
@ -1034,7 +1034,7 @@ static void iBranchTest(u32 newpc)
|
||||||
xCMOVS(eax, ptr32[&cpuRegs.cycle]);
|
xCMOVS(eax, ptr32[&cpuRegs.cycle]);
|
||||||
xMOV(ptr32[&cpuRegs.cycle], eax);
|
xMOV(ptr32[&cpuRegs.cycle], eax);
|
||||||
|
|
||||||
xJMP( DispatcherEvent );
|
xJMP( (void*)DispatcherEvent );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1048,7 +1048,7 @@ static void iBranchTest(u32 newpc)
|
||||||
else
|
else
|
||||||
recBlocks.Link(HWADDR(newpc), xJcc32(Jcc_Signed));
|
recBlocks.Link(HWADDR(newpc), xJcc32(Jcc_Signed));
|
||||||
|
|
||||||
xJMP( DispatcherEvent );
|
xJMP( (void*)DispatcherEvent );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1179,7 +1179,7 @@ void recMemcheck(u32 op, u32 bits, bool store)
|
||||||
if (bits == 128)
|
if (bits == 128)
|
||||||
xAND(ecx, ~0x0F);
|
xAND(ecx, ~0x0F);
|
||||||
|
|
||||||
xFastCall(standardizeBreakpointAddress, ecx);
|
xFastCall((void*)standardizeBreakpointAddress, ecx);
|
||||||
xMOV(ecx,eax);
|
xMOV(ecx,eax);
|
||||||
xMOV(edx,eax);
|
xMOV(edx,eax);
|
||||||
xADD(edx,bits/8);
|
xADD(edx,bits/8);
|
||||||
|
@ -1210,10 +1210,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);
|
||||||
xFastCall(dynarecMemLogcheck, ecx, edx);
|
xFastCall((void*)dynarecMemLogcheck, ecx, edx);
|
||||||
}
|
}
|
||||||
if (checks[i].result & MEMCHECK_BREAK) {
|
if (checks[i].result & MEMCHECK_BREAK) {
|
||||||
xFastCall(dynarecMemcheck);
|
xFastCall((void*)dynarecMemcheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
next1.SetTarget();
|
next1.SetTarget();
|
||||||
|
@ -1226,7 +1226,7 @@ void encodeBreakpoint()
|
||||||
if (isBreakpointNeeded(pc) != 0)
|
if (isBreakpointNeeded(pc) != 0)
|
||||||
{
|
{
|
||||||
iFlushCall(FLUSH_EVERYTHING|FLUSH_PC);
|
iFlushCall(FLUSH_EVERYTHING|FLUSH_PC);
|
||||||
xFastCall(dynarecCheckBreakpoint);
|
xFastCall((void*)dynarecCheckBreakpoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1657,7 +1657,7 @@ static void __fastcall recRecompile( const u32 startpc )
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eeloadMain && HWADDR(startpc) == HWADDR(eeloadMain)) {
|
if (eeloadMain && HWADDR(startpc) == HWADDR(eeloadMain)) {
|
||||||
xFastCall(eeloadHook);
|
xFastCall((void*)eeloadHook);
|
||||||
|
|
||||||
// On fast/full boot this will have a crc of 0x0. But when the game/elf itself is
|
// On fast/full boot this will have a crc of 0x0. But when the game/elf itself is
|
||||||
// recompiled (below - ElfEntry && g_GameLoading), then the crc would be from the elf.
|
// recompiled (below - ElfEntry && g_GameLoading), then the crc would be from the elf.
|
||||||
|
@ -1671,7 +1671,7 @@ static void __fastcall recRecompile( const u32 startpc )
|
||||||
// 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 (g_GameLoading && HWADDR(startpc) == ElfEntry) {
|
if (g_GameLoading && HWADDR(startpc) == ElfEntry) {
|
||||||
Console.WriteLn(L"Elf entry point @ 0x%08x about to get recompiled. Load patches first.", startpc);
|
Console.WriteLn(L"Elf entry point @ 0x%08x about to get recompiled. Load patches first.", startpc);
|
||||||
xFastCall(eeGameStarting);
|
xFastCall((void*)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.
|
||||||
|
@ -1695,18 +1695,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.
|
||||||
|
|
||||||
xFastCall(PreBlockCheck, pc);
|
xFastCall((void*)PreBlockCheck, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
xFastCall(GoemonPreloadTlb);
|
xFastCall((void*)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.
|
||||||
eeRecNeedsReset = true;
|
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
|
||||||
xFastCall(GoemonUnloadTlb, ptr[&cpuRegs.GPR.n.a0.UL[0]]);
|
xFastCall((void*)GoemonUnloadTlb, ptr[&cpuRegs.GPR.n.a0.UL[0]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) xFastCall(mVU0clearlpStateJIT);
|
if (!isVU1) xFastCall((void*)mVU0clearlpStateJIT);
|
||||||
else xFastCall(mVU1clearlpStateJIT);
|
else xFastCall((void*)mVU1clearlpStateJIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +117,9 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
|
||||||
}
|
}
|
||||||
if (doEarlyExit(mVU)) {
|
if (doEarlyExit(mVU)) {
|
||||||
if (!isVU1)
|
if (!isVU1)
|
||||||
xFastCall(mVU0clearlpStateJIT);
|
xFastCall((void*)mVU0clearlpStateJIT);
|
||||||
else
|
else
|
||||||
xFastCall(mVU1clearlpStateJIT);
|
xFastCall((void*)mVU1clearlpStateJIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,8 +192,8 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump) {
|
||||||
xJMP(mVU.exitFunct);
|
xJMP(mVU.exitFunct);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mVU.index) xFastCall(mVUcompileJIT<0>, gprT2, gprT3); //(u32 startPC, uptr pState)
|
if (!mVU.index) xFastCall((void*)(void(*)())mVUcompileJIT<0>, gprT2, gprT3); //(u32 startPC, uptr pState)
|
||||||
else xFastCall(mVUcompileJIT<1>, gprT2, gprT3);
|
else xFastCall((void*)(void(*)())mVUcompileJIT<1>, gprT2, gprT3);
|
||||||
|
|
||||||
mVUrestoreRegs(mVU);
|
mVUrestoreRegs(mVU);
|
||||||
xJMP(gprT1); // Jump to rec-code address
|
xJMP(gprT1); // Jump to rec-code address
|
||||||
|
|
|
@ -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) { xFastCall(mVUexecuteVU0, ecx, edx); }
|
if (!isVU1) { xFastCall((void*)mVUexecuteVU0, ecx, edx); }
|
||||||
else { xFastCall(mVUexecuteVU1, ecx, edx); }
|
else { xFastCall((void*)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) { xFastCall(mVUcleanUpVU0); }
|
if (!isVU1) { xFastCall((void*)mVUcleanUpVU0); }
|
||||||
else { xFastCall(mVUcleanUpVU1); }
|
else { xFastCall((void*)mVUcleanUpVU1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
xRET();
|
xRET();
|
||||||
|
|
|
@ -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) xFastCall(_vu0WaitMicro);
|
if (mBitSync) xFastCall((void*)_vu0WaitMicro);
|
||||||
else xFastCall(_vu0FinishMicro);
|
else xFastCall((void*)_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;
|
||||||
xFastCall(resetFunct);
|
xFastCall((void*)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);
|
||||||
xFastCall(vu1ExecMicro, ecx);
|
xFastCall((void*)vu1ExecMicro, ecx);
|
||||||
xFastCall(vif1VUFinish);
|
xFastCall((void*)vif1VUFinish);
|
||||||
break;
|
break;
|
||||||
case REG_FBRST:
|
case REG_FBRST:
|
||||||
if (!_Rt_) {
|
if (!_Rt_) {
|
||||||
|
@ -336,7 +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_);
|
||||||
xFastCall(BaseVUmicroCPU::ExecuteBlockJIT, (uptr)CpuVU0);
|
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, (uptr)CpuVU0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,9 +298,9 @@ __fi void mVUaddrFix(mV, const x32& gprReg)
|
||||||
if (IsDevBuild && !isCOP2) { // Lets see which games do this!
|
if (IsDevBuild && !isCOP2) { // Lets see which games do this!
|
||||||
xMOV(gprT2, mVU.prog.cur->idx); // Note: Kernel does it via COP2 to initialize VU1!
|
xMOV(gprT2, mVU.prog.cur->idx); // Note: Kernel does it via COP2 to initialize VU1!
|
||||||
xMOV(gprT3, xPC); // So we don't spam console, we'll only check micro-mode...
|
xMOV(gprT3, xPC); // So we don't spam console, we'll only check micro-mode...
|
||||||
xCALL(mVUwarningRegAccess);
|
xCALL((void*)mVUwarningRegAccess);
|
||||||
}
|
}
|
||||||
xCALL(mVUwaitMTVU);
|
xCALL((void*)mVUwaitMTVU);
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
xADD(esp, 4);
|
xADD(esp, 4);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2890,7 +2890,7 @@ void VuBaseBlock::Recompile()
|
||||||
if (itparent == parents.end()) xMOV(ptr32[&skipparent], -1);
|
if (itparent == parents.end()) xMOV(ptr32[&skipparent], -1);
|
||||||
|
|
||||||
xMOV( ecx, s_vu );
|
xMOV( ecx, s_vu );
|
||||||
xCALL( svudispfn );
|
xCALL( (void*)svudispfn );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s_pCurBlock = this;
|
s_pCurBlock = this;
|
||||||
|
@ -3599,7 +3599,7 @@ void VuInstruction::Recompile(std::list<VuInstruction>::iterator& itinst, u32 vu
|
||||||
u8* jptr = JZ8(0);
|
u8* jptr = JZ8(0);
|
||||||
xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], s_vu ? 0x200 : 0x002);
|
xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], s_vu ? 0x200 : 0x002);
|
||||||
xMOV( ecx, s_vu ? INTC_VU1 : INTC_VU0 );
|
xMOV( ecx, s_vu ? INTC_VU1 : INTC_VU0 );
|
||||||
xCALL( hwIntcIrq );
|
xCALL( (void*)hwIntcIrq );
|
||||||
x86SetJ8(jptr);
|
x86SetJ8(jptr);
|
||||||
}
|
}
|
||||||
if (code_ptr[1] & 0x08000000) // T flag
|
if (code_ptr[1] & 0x08000000) // T flag
|
||||||
|
@ -3608,7 +3608,7 @@ void VuInstruction::Recompile(std::list<VuInstruction>::iterator& itinst, u32 vu
|
||||||
u8* jptr = JZ8(0);
|
u8* jptr = JZ8(0);
|
||||||
xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], s_vu ? 0x400 : 0x004);
|
xOR(ptr32[&VU0.VI[REG_VPU_STAT].UL], s_vu ? 0x400 : 0x004);
|
||||||
xMOV( ecx, s_vu ? INTC_VU1 : INTC_VU0 );
|
xMOV( ecx, s_vu ? INTC_VU1 : INTC_VU0 );
|
||||||
xCALL( hwIntcIrq );
|
xCALL( (void*)hwIntcIrq );
|
||||||
x86SetJ8(jptr);
|
x86SetJ8(jptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4311,7 +4311,7 @@ void recVUMI_XGKICK_(VURegs *VU)
|
||||||
_freeXMMregs();
|
_freeXMMregs();
|
||||||
|
|
||||||
xMOV(ecx, xRegister32(s_XGKICKReg));
|
xMOV(ecx, xRegister32(s_XGKICKReg));
|
||||||
xCALL(VU1XGKICK_MTGSTransfer);
|
xCALL((void*)VU1XGKICK_MTGSTransfer);
|
||||||
|
|
||||||
s_ScheduleXGKICK = 0;
|
s_ScheduleXGKICK = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue