mirror of https://github.com/PCSX2/pcsx2.git
major pcsx2 emitter change.
the emitter is now 'templified' so that you can run multiple instances such as: eMOVRtoR<0>(EAX, ESP); this uses emitter instance #0 to use another instance you can simply change the number in the brackets like: eMOVRtoR<1>(EAX, ESP); will use instance #1. all old-functions are mapped to instance #0 by macros. like: #define MOVRtoR eMOVRtoR<0> why do this to the emitter? so we can have thread safety, and eventually thread the recompilers using different emitter instances. note: this took me forever to get working (around 12 hours of non-stop coding). however for some reason debug build is being extra-picky and still giving compile errors. hopefully Jake or someone else can fix this, because i tried a few stuff, and just got more compile errors >< git-svn-id: http://pcsx2.googlecode.com/svn/trunk@647 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
9deff96c78
commit
e2d583c7fe
|
@ -2854,7 +2854,11 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_3dnow.cpp"
|
RelativePath="..\..\x86\ix86\ix86.inl"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\x86\ix86\ix86_3dnow.inl"
|
||||||
>
|
>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Devel vm|Win32"
|
Name="Devel vm|Win32"
|
||||||
|
@ -2886,7 +2890,7 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_fpu.cpp"
|
RelativePath="..\..\x86\ix86\ix86_fpu.inl"
|
||||||
>
|
>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug|Win32"
|
Name="Debug|Win32"
|
||||||
|
@ -2922,7 +2926,11 @@
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_mmx.cpp"
|
RelativePath="..\..\x86\ix86\ix86_macros.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\x86\ix86\ix86_mmx.inl"
|
||||||
>
|
>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug|Win32"
|
Name="Debug|Win32"
|
||||||
|
@ -2958,7 +2966,7 @@
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_sse.cpp"
|
RelativePath="..\..\x86\ix86\ix86_sse.inl"
|
||||||
>
|
>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug|Win32"
|
Name="Debug|Win32"
|
||||||
|
|
|
@ -1976,14 +1976,14 @@ CPU_SSE_XMMCACHE_END
|
||||||
// Both Macros are 16 bytes so we can use a shift instead of a Mul instruction
|
// Both Macros are 16 bytes so we can use a shift instead of a Mul instruction
|
||||||
#define QFSRVhelper0() { \
|
#define QFSRVhelper0() { \
|
||||||
ajmp[0] = JMP32(0); \
|
ajmp[0] = JMP32(0); \
|
||||||
x86Ptr += 11; \
|
x86Ptr[0] += 11; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define QFSRVhelper(shift1, shift2) { \
|
#define QFSRVhelper(shift1, shift2) { \
|
||||||
SSE2_PSRLDQ_I8_to_XMM(EEREC_D, shift1); \
|
SSE2_PSRLDQ_I8_to_XMM(EEREC_D, shift1); \
|
||||||
SSE2_PSLLDQ_I8_to_XMM(t0reg, shift2); \
|
SSE2_PSLLDQ_I8_to_XMM(t0reg, shift2); \
|
||||||
ajmp[shift1] = JMP32(0); \
|
ajmp[shift1] = JMP32(0); \
|
||||||
x86Ptr += 1; \
|
x86Ptr[0] += 1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
void recQFSRV()
|
void recQFSRV()
|
||||||
|
@ -2003,7 +2003,7 @@ void recQFSRV()
|
||||||
MOV32MtoR(EAX, (uptr)&cpuRegs.sa);
|
MOV32MtoR(EAX, (uptr)&cpuRegs.sa);
|
||||||
SHL32ItoR(EAX, 1); // Multiply SA bytes by 16 bytes (the amount of bytes in QFSRVhelper() macros)
|
SHL32ItoR(EAX, 1); // Multiply SA bytes by 16 bytes (the amount of bytes in QFSRVhelper() macros)
|
||||||
AND32I8toR(EAX, 0xf0); // This can possibly be removed but keeping it incase theres garbage in SA (cottonvibes)
|
AND32I8toR(EAX, 0xf0); // This can possibly be removed but keeping it incase theres garbage in SA (cottonvibes)
|
||||||
ADD32ItoEAX((uptr)x86Ptr + 7); // ADD32 = 5 bytes, JMPR = 2 bytes
|
ADD32ItoEAX((uptr)x86Ptr[0] + 7); // ADD32 = 5 bytes, JMPR = 2 bytes
|
||||||
JMPR(EAX); // Jumps to a QFSRVhelper() case below (a total of 16 different cases)
|
JMPR(EAX); // Jumps to a QFSRVhelper() case below (a total of 16 different cases)
|
||||||
|
|
||||||
// Case 0:
|
// Case 0:
|
||||||
|
|
|
@ -188,7 +188,7 @@ static void iIopDumpBlock( int startpc, u8 * ptr )
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
// dump the asm
|
// dump the asm
|
||||||
f = fopen( "mydump1", "wb" );
|
f = fopen( "mydump1", "wb" );
|
||||||
fwrite( ptr, 1, (uptr)x86Ptr - (uptr)ptr, f );
|
fwrite( ptr, 1, (uptr)x86Ptr[0] - (uptr)ptr, f );
|
||||||
fclose( f );
|
fclose( f );
|
||||||
sprintf( command, "objdump -D --target=binary --architecture=i386 -M intel mydump1 | cat %s - > tempdump", filename );
|
sprintf( command, "objdump -D --target=binary --architecture=i386 -M intel mydump1 | cat %s - > tempdump", filename );
|
||||||
system( command );
|
system( command );
|
||||||
|
@ -635,8 +635,6 @@ static void recShutdown()
|
||||||
safe_free(psxRecLUT);
|
safe_free(psxRecLUT);
|
||||||
safe_free( s_pInstCache );
|
safe_free( s_pInstCache );
|
||||||
s_nInstCacheSize = 0;
|
s_nInstCacheSize = 0;
|
||||||
|
|
||||||
x86Shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code
|
#pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code
|
||||||
|
@ -722,7 +720,7 @@ __declspec(naked) void psxDispatcher()
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
shl eax,4
|
shl eax,4
|
||||||
pop ecx // x86Ptr to mod
|
pop ecx // x86Ptr[0] to mod
|
||||||
mov edx, eax
|
mov edx, eax
|
||||||
sub edx, ecx
|
sub edx, ecx
|
||||||
sub edx, 4
|
sub edx, 4
|
||||||
|
@ -900,14 +898,14 @@ void psxRecClearMem(BASEBLOCK* p)
|
||||||
assert( p->GetFnptr() != 0 );
|
assert( p->GetFnptr() != 0 );
|
||||||
assert( p->startpc );
|
assert( p->startpc );
|
||||||
|
|
||||||
x86Ptr = (u8*)p->GetFnptr();
|
x86Ptr[0] = (u8*)p->GetFnptr();
|
||||||
|
|
||||||
// there is a small problem: mem can be ored with 0xa<<28 or 0x8<<28, and don't know which
|
// there is a small problem: mem can be ored with 0xa<<28 or 0x8<<28, and don't know which
|
||||||
MOV32ItoR(EDX, p->startpc);
|
MOV32ItoR(EDX, p->startpc);
|
||||||
assert( (uptr)x86Ptr <= 0xffffffff );
|
assert( (uptr)x86Ptr[0] <= 0xffffffff );
|
||||||
PUSH32I((uptr)x86Ptr);
|
PUSH32I((uptr)x86Ptr[0]);
|
||||||
JMP32((uptr)psxDispatcherClear - ( (uptr)x86Ptr + 5 ));
|
JMP32((uptr)psxDispatcherClear - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
assert( x86Ptr == (u8*)p->GetFnptr() + IOP_MIN_BLOCK_BYTES );
|
assert( x86Ptr[0] == (u8*)p->GetFnptr() + IOP_MIN_BLOCK_BYTES );
|
||||||
|
|
||||||
pstart = PSX_GETBLOCK(p->startpc);
|
pstart = PSX_GETBLOCK(p->startpc);
|
||||||
pexblock = PSX_GETBLOCKEX(pstart);
|
pexblock = PSX_GETBLOCKEX(pstart);
|
||||||
|
@ -954,7 +952,7 @@ void psxSetBranchReg(u32 reg)
|
||||||
_psxFlushCall(FLUSH_EVERYTHING);
|
_psxFlushCall(FLUSH_EVERYTHING);
|
||||||
iPsxBranchTest(0xffffffff, 1);
|
iPsxBranchTest(0xffffffff, 1);
|
||||||
|
|
||||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
}
|
}
|
||||||
|
|
||||||
void psxSetBranchImm( u32 imm )
|
void psxSetBranchImm( u32 imm )
|
||||||
|
@ -969,8 +967,8 @@ void psxSetBranchImm( u32 imm )
|
||||||
iPsxBranchTest(imm, imm <= psxpc);
|
iPsxBranchTest(imm, imm <= psxpc);
|
||||||
|
|
||||||
MOV32ItoR(EDX, 0);
|
MOV32ItoR(EDX, 0);
|
||||||
ptr = (u32*)(x86Ptr-4);
|
ptr = (u32*)(x86Ptr[0]-4);
|
||||||
*ptr = (uptr)JMP32((uptr)psxDispatcher - ( (uptr)x86Ptr + 5 ));
|
*ptr = (uptr)JMP32((uptr)psxDispatcher - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
}
|
}
|
||||||
|
|
||||||
//fixme : this is all a huge hack, we base the counter advancements on the average an opcode should take (wtf?)
|
//fixme : this is all a huge hack, we base the counter advancements on the average an opcode should take (wtf?)
|
||||||
|
@ -1011,7 +1009,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
|
||||||
if( newpc != 0xffffffff )
|
if( newpc != 0xffffffff )
|
||||||
{
|
{
|
||||||
CMP32ItoM((uptr)&psxRegs.pc, newpc);
|
CMP32ItoM((uptr)&psxRegs.pc, newpc);
|
||||||
JNE32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 6 ));
|
JNE32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 6 ));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip branch jump target here:
|
// Skip branch jump target here:
|
||||||
|
@ -1047,7 +1045,7 @@ void rpsxSYSCALL()
|
||||||
|
|
||||||
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
||||||
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
||||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
|
|
||||||
// jump target for skipping blockCycle updates
|
// jump target for skipping blockCycle updates
|
||||||
x86SetJ8(j8Ptr[0]);
|
x86SetJ8(j8Ptr[0]);
|
||||||
|
@ -1067,7 +1065,7 @@ void rpsxBREAK()
|
||||||
j8Ptr[0] = JE8(0);
|
j8Ptr[0] = JE8(0);
|
||||||
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
||||||
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
||||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
x86SetJ8(j8Ptr[0]);
|
x86SetJ8(j8Ptr[0]);
|
||||||
|
|
||||||
//if (!psxbranch) psxbranch = 2;
|
//if (!psxbranch) psxbranch = 2;
|
||||||
|
@ -1103,22 +1101,22 @@ void psxRecompileNextInstruction(int delayslot)
|
||||||
|
|
||||||
// if( pexblock->pOldFnptr ) {
|
// if( pexblock->pOldFnptr ) {
|
||||||
// // code already in place, so jump to it and exit recomp
|
// // code already in place, so jump to it and exit recomp
|
||||||
// JMP32((uptr)pexblock->pOldFnptr - ((uptr)x86Ptr + 5));
|
// JMP32((uptr)pexblock->pOldFnptr - ((uptr)x86Ptr[0] + 5));
|
||||||
// branch = 3;
|
// branch = 3;
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr + 5));
|
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr[0] + 5));
|
||||||
psxbranch = 3;
|
psxbranch = 3;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
if( !(delayslot && pblock->startpc == psxpc) ) {
|
if( !(delayslot && pblock->startpc == psxpc) ) {
|
||||||
u8* oldX86 = x86Ptr;
|
u8* oldX86 = x86Ptr[0];
|
||||||
//__Log("clear block %x\n", pblock->startpc);
|
//__Log("clear block %x\n", pblock->startpc);
|
||||||
psxRecClearMem(pblock);
|
psxRecClearMem(pblock);
|
||||||
x86Ptr = oldX86;
|
x86Ptr[0] = oldX86;
|
||||||
if( delayslot )
|
if( delayslot )
|
||||||
SysPrintf("delay slot %x\n", psxpc);
|
SysPrintf("delay slot %x\n", psxpc);
|
||||||
}
|
}
|
||||||
|
@ -1289,12 +1287,12 @@ void psxRecRecompile(u32 startpc)
|
||||||
|
|
||||||
x86SetPtr( recPtr );
|
x86SetPtr( recPtr );
|
||||||
x86Align(16);
|
x86Align(16);
|
||||||
recPtr = x86Ptr;
|
recPtr = x86Ptr[0];
|
||||||
|
|
||||||
psxbranch = 0;
|
psxbranch = 0;
|
||||||
|
|
||||||
s_pCurBlock->startpc = startpc;
|
s_pCurBlock->startpc = startpc;
|
||||||
s_pCurBlock->SetFnptr( (uptr)x86Ptr );
|
s_pCurBlock->SetFnptr( (uptr)x86Ptr[0] );
|
||||||
s_psxBlockCycles = 0;
|
s_psxBlockCycles = 0;
|
||||||
|
|
||||||
// reset recomp state variables
|
// reset recomp state variables
|
||||||
|
@ -1440,7 +1438,7 @@ StartRecomp:
|
||||||
|
|
||||||
iPsxBranchTest(0xffffffff, 1);
|
iPsxBranchTest(0xffffffff, 1);
|
||||||
|
|
||||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert( psxbranch != 3 );
|
assert( psxbranch != 3 );
|
||||||
|
@ -1456,7 +1454,7 @@ StartRecomp:
|
||||||
assert( psxpc == s_nEndBlock );
|
assert( psxpc == s_nEndBlock );
|
||||||
_psxFlushCall(FLUSH_EVERYTHING);
|
_psxFlushCall(FLUSH_EVERYTHING);
|
||||||
MOV32ItoM((uptr)&psxRegs.pc, psxpc);
|
MOV32ItoM((uptr)&psxRegs.pc, psxpc);
|
||||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr + 5));
|
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr[0] + 5));
|
||||||
psxbranch = 3;
|
psxbranch = 3;
|
||||||
}
|
}
|
||||||
else if( !psxbranch ) {
|
else if( !psxbranch ) {
|
||||||
|
@ -1466,14 +1464,14 @@ StartRecomp:
|
||||||
_psxFlushCall(FLUSH_EVERYTHING);
|
_psxFlushCall(FLUSH_EVERYTHING);
|
||||||
|
|
||||||
ptr = JMP32(0);
|
ptr = JMP32(0);
|
||||||
//JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
//JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( x86Ptr >= (u8*)s_pCurBlock->GetFnptr() + IOP_MIN_BLOCK_BYTES );
|
assert( x86Ptr[0] >= (u8*)s_pCurBlock->GetFnptr() + IOP_MIN_BLOCK_BYTES );
|
||||||
assert( x86Ptr < recMem+RECMEM_SIZE );
|
assert( x86Ptr[0] < recMem+RECMEM_SIZE );
|
||||||
|
|
||||||
recPtr = x86Ptr;
|
recPtr = x86Ptr[0];
|
||||||
|
|
||||||
assert( (g_psxHasConstReg&g_psxFlushedConstReg) == g_psxHasConstReg );
|
assert( (g_psxHasConstReg&g_psxFlushedConstReg) == g_psxHasConstReg );
|
||||||
|
|
||||||
|
|
|
@ -1259,7 +1259,7 @@ void rpsxJALR()
|
||||||
static void* s_pbranchjmp;
|
static void* s_pbranchjmp;
|
||||||
static u32 s_do32 = 0;
|
static u32 s_do32 = 0;
|
||||||
|
|
||||||
#define JUMPVALID(pjmp) (( x86Ptr - (u8*)pjmp ) <= 0x80)
|
#define JUMPVALID(pjmp) (( x86Ptr[0] - (u8*)pjmp ) <= 0x80)
|
||||||
|
|
||||||
void rpsxSetBranchEQ(int info, int process)
|
void rpsxSetBranchEQ(int info, int process)
|
||||||
{
|
{
|
||||||
|
@ -1306,7 +1306,7 @@ void rpsxBEQ_process(int info, int process)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_psxFlushAllUnused();
|
_psxFlushAllUnused();
|
||||||
u8* prevx86 = x86Ptr;
|
u8* prevx86 = x86Ptr[0];
|
||||||
s_do32 = 0;
|
s_do32 = 0;
|
||||||
psxSaveBranchState();
|
psxSaveBranchState();
|
||||||
|
|
||||||
|
@ -1319,7 +1319,7 @@ void rpsxBEQ_process(int info, int process)
|
||||||
x86SetJ8A( (u8*)s_pbranchjmp );
|
x86SetJ8A( (u8*)s_pbranchjmp );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x86Ptr = prevx86;
|
x86Ptr[0] = prevx86;
|
||||||
s_do32 = 1;
|
s_do32 = 1;
|
||||||
psxpc -= 4;
|
psxpc -= 4;
|
||||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||||
|
@ -1370,7 +1370,7 @@ void rpsxBNE_process(int info, int process)
|
||||||
}
|
}
|
||||||
|
|
||||||
_psxFlushAllUnused();
|
_psxFlushAllUnused();
|
||||||
u8* prevx86 = x86Ptr;
|
u8* prevx86 = x86Ptr[0];
|
||||||
s_do32 = 0;
|
s_do32 = 0;
|
||||||
rpsxSetBranchEQ(info, process);
|
rpsxSetBranchEQ(info, process);
|
||||||
|
|
||||||
|
@ -1382,7 +1382,7 @@ void rpsxBNE_process(int info, int process)
|
||||||
x86SetJ8A( (u8*)s_pbranchjmp );
|
x86SetJ8A( (u8*)s_pbranchjmp );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x86Ptr = prevx86;
|
x86Ptr[0] = prevx86;
|
||||||
s_do32 = 1;
|
s_do32 = 1;
|
||||||
psxpc -= 4;
|
psxpc -= 4;
|
||||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||||
|
@ -1424,7 +1424,7 @@ void rpsxBLTZ()
|
||||||
}
|
}
|
||||||
|
|
||||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||||
u8* prevx86 = x86Ptr;
|
u8* prevx86 = x86Ptr[0];
|
||||||
u8* pjmp = JL8(0);
|
u8* pjmp = JL8(0);
|
||||||
|
|
||||||
psxSaveBranchState();
|
psxSaveBranchState();
|
||||||
|
@ -1436,7 +1436,7 @@ void rpsxBLTZ()
|
||||||
x86SetJ8A( pjmp );
|
x86SetJ8A( pjmp );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x86Ptr = prevx86;
|
x86Ptr[0] = prevx86;
|
||||||
psxpc -= 4;
|
psxpc -= 4;
|
||||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||||
psxLoadBranchState();
|
psxLoadBranchState();
|
||||||
|
@ -1471,7 +1471,7 @@ void rpsxBGEZ()
|
||||||
}
|
}
|
||||||
|
|
||||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||||
u8* prevx86 = x86Ptr;
|
u8* prevx86 = x86Ptr[0];
|
||||||
u8* pjmp = JGE8(0);
|
u8* pjmp = JGE8(0);
|
||||||
|
|
||||||
psxSaveBranchState();
|
psxSaveBranchState();
|
||||||
|
@ -1483,7 +1483,7 @@ void rpsxBGEZ()
|
||||||
x86SetJ8A( pjmp );
|
x86SetJ8A( pjmp );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x86Ptr = prevx86;
|
x86Ptr[0] = prevx86;
|
||||||
psxpc -= 4;
|
psxpc -= 4;
|
||||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||||
psxLoadBranchState();
|
psxLoadBranchState();
|
||||||
|
@ -1525,7 +1525,7 @@ void rpsxBLTZAL()
|
||||||
}
|
}
|
||||||
|
|
||||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||||
u8* prevx86 = x86Ptr;
|
u8* prevx86 = x86Ptr[0];
|
||||||
u8* pjmp = JL8(0);
|
u8* pjmp = JL8(0);
|
||||||
|
|
||||||
psxSaveBranchState();
|
psxSaveBranchState();
|
||||||
|
@ -1539,7 +1539,7 @@ void rpsxBLTZAL()
|
||||||
x86SetJ8A( pjmp );
|
x86SetJ8A( pjmp );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x86Ptr = prevx86;
|
x86Ptr[0] = prevx86;
|
||||||
psxpc -= 4;
|
psxpc -= 4;
|
||||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||||
psxLoadBranchState();
|
psxLoadBranchState();
|
||||||
|
@ -1578,7 +1578,7 @@ void rpsxBGEZAL()
|
||||||
}
|
}
|
||||||
|
|
||||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||||
u8* prevx86 = x86Ptr;
|
u8* prevx86 = x86Ptr[0];
|
||||||
u8* pjmp = JGE8(0);
|
u8* pjmp = JGE8(0);
|
||||||
|
|
||||||
MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4);
|
MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4);
|
||||||
|
@ -1592,7 +1592,7 @@ void rpsxBGEZAL()
|
||||||
x86SetJ8A( pjmp );
|
x86SetJ8A( pjmp );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x86Ptr = prevx86;
|
x86Ptr[0] = prevx86;
|
||||||
psxpc -= 4;
|
psxpc -= 4;
|
||||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||||
psxLoadBranchState();
|
psxLoadBranchState();
|
||||||
|
@ -1632,7 +1632,7 @@ void rpsxBLEZ()
|
||||||
_clearNeededX86regs();
|
_clearNeededX86regs();
|
||||||
|
|
||||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||||
u8* prevx86 = x86Ptr;
|
u8* prevx86 = x86Ptr[0];
|
||||||
u8* pjmp = JLE8(0);
|
u8* pjmp = JLE8(0);
|
||||||
|
|
||||||
psxSaveBranchState();
|
psxSaveBranchState();
|
||||||
|
@ -1643,7 +1643,7 @@ void rpsxBLEZ()
|
||||||
x86SetJ8A( pjmp );
|
x86SetJ8A( pjmp );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x86Ptr = prevx86;
|
x86Ptr[0] = prevx86;
|
||||||
psxpc -= 4;
|
psxpc -= 4;
|
||||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||||
psxLoadBranchState();
|
psxLoadBranchState();
|
||||||
|
@ -1680,7 +1680,7 @@ void rpsxBGTZ()
|
||||||
_clearNeededX86regs();
|
_clearNeededX86regs();
|
||||||
|
|
||||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||||
u8* prevx86 = x86Ptr;
|
u8* prevx86 = x86Ptr[0];
|
||||||
u8* pjmp = JG8(0);
|
u8* pjmp = JG8(0);
|
||||||
|
|
||||||
psxSaveBranchState();
|
psxSaveBranchState();
|
||||||
|
@ -1691,7 +1691,7 @@ void rpsxBGTZ()
|
||||||
x86SetJ8A( pjmp );
|
x86SetJ8A( pjmp );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x86Ptr = prevx86;
|
x86Ptr[0] = prevx86;
|
||||||
psxpc -= 4;
|
psxpc -= 4;
|
||||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||||
psxLoadBranchState();
|
psxLoadBranchState();
|
||||||
|
|
|
@ -1569,7 +1569,7 @@ void recLQC2_co( void )
|
||||||
|
|
||||||
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
||||||
|
|
||||||
rawreadptr = x86Ptr;
|
rawreadptr = x86Ptr[0];
|
||||||
if( mmreg1 >= 0 ) SSEX_MOVDQARmtoROffset(mmreg1, ECX, PS2MEM_BASE_+s_nAddMemOffset);
|
if( mmreg1 >= 0 ) SSEX_MOVDQARmtoROffset(mmreg1, ECX, PS2MEM_BASE_+s_nAddMemOffset);
|
||||||
if( mmreg2 >= 0 ) SSEX_MOVDQARmtoROffset(mmreg2, ECX, PS2MEM_BASE_+s_nAddMemOffset+_Imm_co_-_Imm_);
|
if( mmreg2 >= 0 ) SSEX_MOVDQARmtoROffset(mmreg2, ECX, PS2MEM_BASE_+s_nAddMemOffset+_Imm_co_-_Imm_);
|
||||||
|
|
||||||
|
@ -1579,7 +1579,7 @@ void recLQC2_co( void )
|
||||||
|
|
||||||
// check if writing to VUs
|
// check if writing to VUs
|
||||||
CMP32ItoR(ECX, 0x11000000);
|
CMP32ItoR(ECX, 0x11000000);
|
||||||
JAE8(rawreadptr - (x86Ptr+2));
|
JAE8(rawreadptr - (x86Ptr[0]+2));
|
||||||
|
|
||||||
MOV32RtoM((u32)&s_tempaddr, ECX);
|
MOV32RtoM((u32)&s_tempaddr, ECX);
|
||||||
|
|
||||||
|
@ -1634,7 +1634,7 @@ void recSQC2_co( void )
|
||||||
|
|
||||||
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
||||||
|
|
||||||
rawreadptr = x86Ptr;
|
rawreadptr = x86Ptr[0];
|
||||||
|
|
||||||
if( mmreg1 >= 0 ) {
|
if( mmreg1 >= 0 ) {
|
||||||
SSEX_MOVDQARtoRmOffset(ECX, mmreg1, PS2MEM_BASE_+s_nAddMemOffset);
|
SSEX_MOVDQARtoRmOffset(ECX, mmreg1, PS2MEM_BASE_+s_nAddMemOffset);
|
||||||
|
@ -1705,7 +1705,7 @@ void recSQC2_co( void )
|
||||||
|
|
||||||
// check if writing to VUs
|
// check if writing to VUs
|
||||||
CMP32ItoR(ECX, 0x11000000);
|
CMP32ItoR(ECX, 0x11000000);
|
||||||
JAE8(rawreadptr - (x86Ptr+2));
|
JAE8(rawreadptr - (x86Ptr[0]+2));
|
||||||
|
|
||||||
// some type of hardware write
|
// some type of hardware write
|
||||||
if( mmreg1 >= 0) {
|
if( mmreg1 >= 0) {
|
||||||
|
|
|
@ -846,7 +846,7 @@ static VuFunctionHeader* SuperVURecompileProgram(u32 startpc, int vuindex)
|
||||||
|
|
||||||
SuperVURecompile();
|
SuperVURecompile();
|
||||||
|
|
||||||
s_recVUPtr = x86Ptr;
|
s_recVUPtr = x86Ptr[0];
|
||||||
|
|
||||||
// set the function's range
|
// set the function's range
|
||||||
VuFunctionHeader::RANGE r;
|
VuFunctionHeader::RANGE r;
|
||||||
|
@ -1883,7 +1883,7 @@ void VuBaseBlock::AssignVFRegs()
|
||||||
if( i == XMMREGS ) return; // nothing changed
|
if( i == XMMREGS ) return; // nothing changed
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* oldX86 = x86Ptr;
|
u8* oldX86 = x86Ptr[0];
|
||||||
|
|
||||||
FORIT(itinst, insts) {
|
FORIT(itinst, insts) {
|
||||||
|
|
||||||
|
@ -2072,7 +2072,7 @@ void VuBaseBlock::AssignVFRegs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( x86Ptr == oldX86 );
|
assert( x86Ptr[0] == oldX86 );
|
||||||
u32 analyzechildren = !(type&BLOCKTYPE_ANALYZED);
|
u32 analyzechildren = !(type&BLOCKTYPE_ANALYZED);
|
||||||
type |= BLOCKTYPE_ANALYZED;
|
type |= BLOCKTYPE_ANALYZED;
|
||||||
|
|
||||||
|
@ -2460,7 +2460,7 @@ static void SuperVURecompile()
|
||||||
AND32ItoM( (uptr)&VU->vifRegs->stat, ~0x4 );
|
AND32ItoM( (uptr)&VU->vifRegs->stat, ~0x4 );
|
||||||
|
|
||||||
MOV32ItoM((uptr)&VU->VI[REG_TPC], pchild->endpc);
|
MOV32ItoM((uptr)&VU->VI[REG_TPC], pchild->endpc);
|
||||||
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 5 ));
|
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
}
|
}
|
||||||
// only other case is when there are two branches
|
// only other case is when there are two branches
|
||||||
else assert( (*itblock)->insts.back().regs[0].pipe == VUPIPE_BRANCH );
|
else assert( (*itblock)->insts.back().regs[0].pipe == VUPIPE_BRANCH );
|
||||||
|
@ -2600,11 +2600,11 @@ void SuperVUTestVU0Condition(u32 incstack)
|
||||||
|
|
||||||
ADD32ItoR(ESP, incstack);
|
ADD32ItoR(ESP, incstack);
|
||||||
//CALLFunc((u32)timeout);
|
//CALLFunc((u32)timeout);
|
||||||
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 5 ));
|
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
|
|
||||||
x86SetJ8(ptr);
|
x86SetJ8(ptr);
|
||||||
}
|
}
|
||||||
else JAE32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 6 ) );
|
else JAE32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr[0] + 6 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void VuBaseBlock::Recompile()
|
void VuBaseBlock::Recompile()
|
||||||
|
@ -2612,7 +2612,7 @@ void VuBaseBlock::Recompile()
|
||||||
if( type & BLOCKTYPE_ANALYZED ) return;
|
if( type & BLOCKTYPE_ANALYZED ) return;
|
||||||
|
|
||||||
x86Align(16);
|
x86Align(16);
|
||||||
pcode = x86Ptr;
|
pcode = x86Ptr[0];
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
MOV32ItoM((uptr)&s_vufnheader, s_pFnHeader->startpc);
|
MOV32ItoM((uptr)&s_vufnheader, s_pFnHeader->startpc);
|
||||||
|
@ -2720,7 +2720,7 @@ void VuBaseBlock::Recompile()
|
||||||
AND32ItoM( (uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu?~0x100:~0x001 ); // E flag
|
AND32ItoM( (uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu?~0x100:~0x001 ); // E flag
|
||||||
AND32ItoM( (uptr)&VU->vifRegs->stat, ~0x4 );
|
AND32ItoM( (uptr)&VU->vifRegs->stat, ~0x4 );
|
||||||
if( !branch ) MOV32ItoM((uptr)&VU->VI[REG_TPC], endpc);
|
if( !branch ) MOV32ItoM((uptr)&VU->VI[REG_TPC], endpc);
|
||||||
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 5 ));
|
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
@ -2862,7 +2862,7 @@ void VuBaseBlock::Recompile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pendcode = x86Ptr;
|
pendcode = x86Ptr[0];
|
||||||
type |= BLOCKTYPE_ANALYZED;
|
type |= BLOCKTYPE_ANALYZED;
|
||||||
|
|
||||||
LISTBLOCKS::iterator itchild;
|
LISTBLOCKS::iterator itchild;
|
||||||
|
@ -3543,7 +3543,7 @@ void recVUMI_BranchHandle()
|
||||||
if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION)
|
if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION)
|
||||||
MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc);
|
MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc);
|
||||||
MOV32ItoR(s_JumpX86, 0);
|
MOV32ItoR(s_JumpX86, 0);
|
||||||
s_pCurBlock->pChildJumps[curjump] = (u32*)x86Ptr-1;
|
s_pCurBlock->pChildJumps[curjump] = (u32*)x86Ptr[0]-1;
|
||||||
|
|
||||||
if( !(s_pCurInst->type & INST_BRANCH_DELAY) ) {
|
if( !(s_pCurInst->type & INST_BRANCH_DELAY) ) {
|
||||||
j8Ptr[1] = JMP8(0);
|
j8Ptr[1] = JMP8(0);
|
||||||
|
@ -3552,7 +3552,7 @@ void recVUMI_BranchHandle()
|
||||||
if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION )
|
if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION )
|
||||||
MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), pc+8);
|
MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), pc+8);
|
||||||
MOV32ItoR(s_JumpX86, 0);
|
MOV32ItoR(s_JumpX86, 0);
|
||||||
s_pCurBlock->pChildJumps[curjump+1] = (u32*)x86Ptr-1;
|
s_pCurBlock->pChildJumps[curjump+1] = (u32*)x86Ptr[0]-1;
|
||||||
|
|
||||||
x86SetJ8( j8Ptr[ 1 ] );
|
x86SetJ8( j8Ptr[ 1 ] );
|
||||||
}
|
}
|
||||||
|
@ -3789,7 +3789,7 @@ void recVUMI_B( VURegs* vuu, s32 info )
|
||||||
if( s_pCurBlock->blocks.size() > 1 ) {
|
if( s_pCurBlock->blocks.size() > 1 ) {
|
||||||
s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE);
|
s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE);
|
||||||
MOV32ItoR(s_JumpX86, 0);
|
MOV32ItoR(s_JumpX86, 0);
|
||||||
s_pCurBlock->pChildJumps[(s_pCurInst->type & INST_BRANCH_DELAY)?1:0] = (u32*)x86Ptr-1;
|
s_pCurBlock->pChildJumps[(s_pCurInst->type & INST_BRANCH_DELAY)?1:0] = (u32*)x86Ptr[0]-1;
|
||||||
s_UnconditionalDelay = 1;
|
s_UnconditionalDelay = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3815,7 +3815,7 @@ void recVUMI_BAL( VURegs* vuu, s32 info )
|
||||||
if( s_pCurBlock->blocks.size() > 1 ) {
|
if( s_pCurBlock->blocks.size() > 1 ) {
|
||||||
s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE);
|
s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE);
|
||||||
MOV32ItoR(s_JumpX86, 0);
|
MOV32ItoR(s_JumpX86, 0);
|
||||||
s_pCurBlock->pChildJumps[(s_pCurInst->type & INST_BRANCH_DELAY)?1:0] = (u32*)x86Ptr-1;
|
s_pCurBlock->pChildJumps[(s_pCurInst->type & INST_BRANCH_DELAY)?1:0] = (u32*)x86Ptr[0]-1;
|
||||||
s_UnconditionalDelay = 1;
|
s_UnconditionalDelay = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ static void iDumpBlock( int startpc, u8 * ptr )
|
||||||
|
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
// f = fopen( "dump1", "wb" );
|
// f = fopen( "dump1", "wb" );
|
||||||
// fwrite( ptr, 1, (u32)x86Ptr - (u32)ptr, f );
|
// fwrite( ptr, 1, (u32)x86Ptr[0] - (u32)ptr, f );
|
||||||
// fclose( f );
|
// fclose( f );
|
||||||
//
|
//
|
||||||
// sprintf( command, "objdump -D --target=binary --architecture=i386 dump1 > %s", filename );
|
// sprintf( command, "objdump -D --target=binary --architecture=i386 dump1 > %s", filename );
|
||||||
|
@ -585,8 +585,8 @@ void recResetEE( void )
|
||||||
// so a fix will have to wait until later. -_- (air)
|
// so a fix will have to wait until later. -_- (air)
|
||||||
|
|
||||||
//x86SetPtr(recMem+REC_CACHEMEM);
|
//x86SetPtr(recMem+REC_CACHEMEM);
|
||||||
//dyna_block_discard_recmem=(u8*)x86Ptr;
|
//dyna_block_discard_recmem=(u8*)x86Ptr[0];
|
||||||
//JMP32( (uptr)&dyna_block_discard - ( (u32)x86Ptr + 5 ));
|
//JMP32( (uptr)&dyna_block_discard - ( (u32)x86Ptr[0] + 5 ));
|
||||||
|
|
||||||
x86SetPtr(recMem);
|
x86SetPtr(recMem);
|
||||||
|
|
||||||
|
@ -613,8 +613,6 @@ static void recShutdown( void )
|
||||||
|
|
||||||
safe_free( s_pInstCache );
|
safe_free( s_pInstCache );
|
||||||
s_nInstCacheSize = 0;
|
s_nInstCacheSize = 0;
|
||||||
|
|
||||||
x86Shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignored by Linux
|
// Ignored by Linux
|
||||||
|
@ -675,7 +673,7 @@ static __naked void Dispatcher()
|
||||||
// Modify the prev block's jump address, and jump to the new block:
|
// Modify the prev block's jump address, and jump to the new block:
|
||||||
__asm {
|
__asm {
|
||||||
shl eax, 4
|
shl eax, 4
|
||||||
pop ecx // x86Ptr to mod
|
pop ecx // x86Ptr[0] to mod
|
||||||
mov edx, eax
|
mov edx, eax
|
||||||
sub edx, ecx
|
sub edx, ecx
|
||||||
sub edx, 4
|
sub edx, 4
|
||||||
|
@ -686,7 +684,7 @@ static __naked void Dispatcher()
|
||||||
}
|
}
|
||||||
|
|
||||||
// edx - baseblock->startpc
|
// edx - baseblock->startpc
|
||||||
// stack - x86Ptr
|
// stack - x86Ptr[0]
|
||||||
static __naked void DispatcherClear()
|
static __naked void DispatcherClear()
|
||||||
{
|
{
|
||||||
// EDX contains the current pc
|
// EDX contains the current pc
|
||||||
|
@ -869,7 +867,7 @@ void recSYSCALL( void ) {
|
||||||
CMP32ItoM((uptr)&cpuRegs.pc, pc);
|
CMP32ItoM((uptr)&cpuRegs.pc, pc);
|
||||||
j8Ptr[0] = JE8(0);
|
j8Ptr[0] = JE8(0);
|
||||||
ADD32ItoM((uptr)&cpuRegs.cycle, eeScaleBlockCycles());
|
ADD32ItoM((uptr)&cpuRegs.cycle, eeScaleBlockCycles());
|
||||||
JMP32((uptr)DispatcherReg - ( (uptr)x86Ptr + 5 ));
|
JMP32((uptr)DispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||||
x86SetJ8(j8Ptr[0]);
|
x86SetJ8(j8Ptr[0]);
|
||||||
//branch = 2;
|
//branch = 2;
|
||||||
}
|
}
|
||||||
|
@ -933,13 +931,13 @@ void recClearMem(BASEBLOCK* p)
|
||||||
assert( p->GetFnptr() != 0 );
|
assert( p->GetFnptr() != 0 );
|
||||||
assert( p->startpc );
|
assert( p->startpc );
|
||||||
|
|
||||||
x86Ptr = (u8*)p->GetFnptr();
|
x86Ptr[0] = (u8*)p->GetFnptr();
|
||||||
|
|
||||||
// there is a small problem: mem can be ored with 0xa<<28 or 0x8<<28, and don't know which
|
// there is a small problem: mem can be ored with 0xa<<28 or 0x8<<28, and don't know which
|
||||||
MOV32ItoR(EDX, p->startpc);
|
MOV32ItoR(EDX, p->startpc);
|
||||||
PUSH32I((u32)x86Ptr); // will be replaced by JMP32
|
PUSH32I((u32)x86Ptr[0]); // will be replaced by JMP32
|
||||||
JMP32((u32)DispatcherClear - ( (u32)x86Ptr + 5 ));
|
JMP32((u32)DispatcherClear - ( (u32)x86Ptr[0] + 5 ));
|
||||||
assert( x86Ptr == (u8*)p->GetFnptr() + EE_MIN_BLOCK_BYTES );
|
assert( x86Ptr[0] == (u8*)p->GetFnptr() + EE_MIN_BLOCK_BYTES );
|
||||||
|
|
||||||
pstart = PC_GETBLOCK(p->startpc);
|
pstart = PC_GETBLOCK(p->startpc);
|
||||||
pexblock = PC_GETBLOCKEX(pstart);
|
pexblock = PC_GETBLOCKEX(pstart);
|
||||||
|
@ -1231,7 +1229,7 @@ static void iBranchTest(u32 newpc, bool noDispatch)
|
||||||
// to; creating a static link of blocks that doesn't require the overhead
|
// to; creating a static link of blocks that doesn't require the overhead
|
||||||
// of a dispatcher.
|
// of a dispatcher.
|
||||||
MOV32ItoR(EDX, 0);
|
MOV32ItoR(EDX, 0);
|
||||||
ptr = (u32*)(x86Ptr-4);
|
ptr = (u32*)(x86Ptr[0]-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the Event scheduler if our "cycle target" has been reached.
|
// Check the Event scheduler if our "cycle target" has been reached.
|
||||||
|
@ -1245,12 +1243,12 @@ static void iBranchTest(u32 newpc, bool noDispatch)
|
||||||
if( newpc != 0xffffffff )
|
if( newpc != 0xffffffff )
|
||||||
{
|
{
|
||||||
// This is the jump instruction which gets modified by Dispatcher.
|
// This is the jump instruction which gets modified by Dispatcher.
|
||||||
*ptr = (u32)JS32((u32)Dispatcher - ( (u32)x86Ptr + 6 ));
|
*ptr = (u32)JS32((u32)Dispatcher - ( (u32)x86Ptr[0] + 6 ));
|
||||||
}
|
}
|
||||||
else if( !noDispatch )
|
else if( !noDispatch )
|
||||||
{
|
{
|
||||||
// This instruction is a dynamic link, so it's never modified.
|
// This instruction is a dynamic link, so it's never modified.
|
||||||
JS32((uptr)DispatcherReg - ( (uptr)x86Ptr + 6 ));
|
JS32((uptr)DispatcherReg - ( (uptr)x86Ptr[0] + 6 ));
|
||||||
}
|
}
|
||||||
|
|
||||||
RET2();
|
RET2();
|
||||||
|
@ -1313,22 +1311,22 @@ void recompileNextInstruction(int delayslot)
|
||||||
|
|
||||||
// if( pexblock->pOldFnptr ) {
|
// if( pexblock->pOldFnptr ) {
|
||||||
// // code already in place, so jump to it and exit recomp
|
// // code already in place, so jump to it and exit recomp
|
||||||
// JMP32((u32)pexblock->pOldFnptr - ((u32)x86Ptr + 5));
|
// JMP32((u32)pexblock->pOldFnptr - ((u32)x86Ptr[0] + 5));
|
||||||
// branch = 3;
|
// branch = 3;
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr + 5));
|
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr[0] + 5));
|
||||||
branch = 3;
|
branch = 3;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
if( !(delayslot && pblock->startpc == pc) ) {
|
if( !(delayslot && pblock->startpc == pc) ) {
|
||||||
u8* oldX86 = x86Ptr;
|
u8* oldX86 = x86Ptr[0];
|
||||||
//__Log("clear block %x\n", pblock->startpc);
|
//__Log("clear block %x\n", pblock->startpc);
|
||||||
recClearMem(pblock);
|
recClearMem(pblock);
|
||||||
x86Ptr = oldX86;
|
x86Ptr[0] = oldX86;
|
||||||
if( delayslot )
|
if( delayslot )
|
||||||
Console::Notice("delay slot %x", params pc);
|
Console::Notice("delay slot %x", params pc);
|
||||||
}
|
}
|
||||||
|
@ -1576,8 +1574,8 @@ void recRecompile( const u32 startpc )
|
||||||
|
|
||||||
x86SetPtr( recPtr );
|
x86SetPtr( recPtr );
|
||||||
x86Align(16);
|
x86Align(16);
|
||||||
recPtr = x86Ptr;
|
recPtr = x86Ptr[0];
|
||||||
s_pCurBlock->SetFnptr( (uptr)x86Ptr );
|
s_pCurBlock->SetFnptr( (uptr)x86Ptr[0] );
|
||||||
s_pCurBlock->startpc = startpc;
|
s_pCurBlock->startpc = startpc;
|
||||||
|
|
||||||
branch = 0;
|
branch = 0;
|
||||||
|
@ -1906,7 +1904,7 @@ StartRecomp:
|
||||||
{
|
{
|
||||||
//MOV32ItoR(EAX,*pageVer);
|
//MOV32ItoR(EAX,*pageVer);
|
||||||
//CMP32MtoR(EAX,(uptr)pageVer);
|
//CMP32MtoR(EAX,(uptr)pageVer);
|
||||||
//JNE32(((u32)dyna_block_discard_recmem)- ( (u32)x86Ptr + 6 ));
|
//JNE32(((u32)dyna_block_discard_recmem)- ( (u32)x86Ptr[0] + 6 ));
|
||||||
|
|
||||||
mmap_MarkCountedRamPage(PSM(inpage_ptr),inpage_ptr&~0xFFF);
|
mmap_MarkCountedRamPage(PSM(inpage_ptr),inpage_ptr&~0xFFF);
|
||||||
}
|
}
|
||||||
|
@ -1918,7 +1916,7 @@ StartRecomp:
|
||||||
{
|
{
|
||||||
// was dyna_block_discard_recmem. See note in recResetEE for details.
|
// was dyna_block_discard_recmem. See note in recResetEE for details.
|
||||||
CMP32ItoM((uptr)PSM(lpc),*(u32*)PSM(lpc));
|
CMP32ItoM((uptr)PSM(lpc),*(u32*)PSM(lpc));
|
||||||
JNE32(((u32)&dyna_block_discard)- ( (u32)x86Ptr + 6 ));
|
JNE32(((u32)&dyna_block_discard)- ( (u32)x86Ptr[0] + 6 ));
|
||||||
|
|
||||||
stg-=4;
|
stg-=4;
|
||||||
lpc+=4;
|
lpc+=4;
|
||||||
|
@ -1997,7 +1995,7 @@ StartRecomp:
|
||||||
assert( pc == s_nEndBlock );
|
assert( pc == s_nEndBlock );
|
||||||
iFlushCall(FLUSH_EVERYTHING);
|
iFlushCall(FLUSH_EVERYTHING);
|
||||||
MOV32ItoM((uptr)&cpuRegs.pc, pc);
|
MOV32ItoM((uptr)&cpuRegs.pc, pc);
|
||||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr + 5));
|
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr[0] + 5));
|
||||||
branch = 3;
|
branch = 3;
|
||||||
}
|
}
|
||||||
else if( !branch ) {
|
else if( !branch ) {
|
||||||
|
@ -2010,12 +2008,12 @@ StartRecomp:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( x86Ptr >= (u8*)s_pCurBlock->GetFnptr() + EE_MIN_BLOCK_BYTES );
|
assert( x86Ptr[0] >= (u8*)s_pCurBlock->GetFnptr() + EE_MIN_BLOCK_BYTES );
|
||||||
assert( x86Ptr < recMem+REC_CACHEMEM );
|
assert( x86Ptr[0] < recMem+REC_CACHEMEM );
|
||||||
assert( recStackPtr < recStack+RECSTACK_SIZE );
|
assert( recStackPtr < recStack+RECSTACK_SIZE );
|
||||||
assert( x86FpuState == 0 );
|
assert( x86FpuState == 0 );
|
||||||
|
|
||||||
recPtr = x86Ptr;
|
recPtr = x86Ptr[0];
|
||||||
|
|
||||||
assert( (g_cpuHasConstReg&g_cpuFlushedConstReg) == g_cpuHasConstReg );
|
assert( (g_cpuHasConstReg&g_cpuFlushedConstReg) == g_cpuHasConstReg );
|
||||||
|
|
||||||
|
|
|
@ -1933,7 +1933,7 @@ void recLQC2( void )
|
||||||
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
||||||
|
|
||||||
if( _Ft_ ) {
|
if( _Ft_ ) {
|
||||||
u8* rawreadptr = x86Ptr;
|
u8* rawreadptr = x86Ptr[0];
|
||||||
|
|
||||||
if( mmreg >= 0 ) {
|
if( mmreg >= 0 ) {
|
||||||
SSEX_MOVDQARmtoROffset(mmreg, ECX, PS2MEM_BASE_+s_nAddMemOffset);
|
SSEX_MOVDQARmtoROffset(mmreg, ECX, PS2MEM_BASE_+s_nAddMemOffset);
|
||||||
|
@ -1948,7 +1948,7 @@ void recLQC2( void )
|
||||||
|
|
||||||
// check if writing to VUs
|
// check if writing to VUs
|
||||||
CMP32ItoR(ECX, 0x11000000);
|
CMP32ItoR(ECX, 0x11000000);
|
||||||
JAE8(rawreadptr - (x86Ptr+2));
|
JAE8(rawreadptr - (x86Ptr[0]+2));
|
||||||
|
|
||||||
PUSH32I( (int)&VU0.VF[_Ft_].UD[0] );
|
PUSH32I( (int)&VU0.VF[_Ft_].UD[0] );
|
||||||
CALLFunc( (int)recMemRead128 );
|
CALLFunc( (int)recMemRead128 );
|
||||||
|
@ -2002,7 +2002,7 @@ void recSQC2( void )
|
||||||
mmregs = _eePrepareReg(_Rs_);
|
mmregs = _eePrepareReg(_Rs_);
|
||||||
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
||||||
|
|
||||||
rawreadptr = x86Ptr;
|
rawreadptr = x86Ptr[0];
|
||||||
|
|
||||||
if( (mmreg = _checkXMMreg(XMMTYPE_VFREG, _Ft_, MODE_READ)) >= 0) {
|
if( (mmreg = _checkXMMreg(XMMTYPE_VFREG, _Ft_, MODE_READ)) >= 0) {
|
||||||
SSEX_MOVDQARtoRmOffset(ECX, mmreg, PS2MEM_BASE_+s_nAddMemOffset);
|
SSEX_MOVDQARtoRmOffset(ECX, mmreg, PS2MEM_BASE_+s_nAddMemOffset);
|
||||||
|
@ -2042,7 +2042,7 @@ void recSQC2( void )
|
||||||
|
|
||||||
// check if writing to VUs
|
// check if writing to VUs
|
||||||
CMP32ItoR(ECX, 0x11000000);
|
CMP32ItoR(ECX, 0x11000000);
|
||||||
JAE8(rawreadptr - (x86Ptr+2));
|
JAE8(rawreadptr - (x86Ptr[0]+2));
|
||||||
|
|
||||||
// some type of hardware write
|
// some type of hardware write
|
||||||
if( (mmreg = _checkXMMreg(XMMTYPE_VFREG, _Ft_, MODE_READ)) >= 0) {
|
if( (mmreg = _checkXMMreg(XMMTYPE_VFREG, _Ft_, MODE_READ)) >= 0) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,201 @@
|
||||||
|
/* Pcsx2 - Pc Ps2 Emulator
|
||||||
|
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// 3DNOW instructions
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* femms */
|
||||||
|
emitterT void eFEMMS( void )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0E0F );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFCMPEQMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0xB0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFCMPGTMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0xA0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFCMPGEMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0x90 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFADDMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0x9E );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFADDRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0x9E );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFSUBMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0x9A );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFSUBRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0x9A );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFMULMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0xB4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFMULRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0xB4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFRCPMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0x96 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFRCPRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0x96 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFRCPIT1RtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0xA6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFRCPIT2RtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0xB6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFRSQRTRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0x97 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFRSQIT1RtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0xA7 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePF2IDMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0x1D );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePF2IDRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0x1D );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePI2FDMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0x0D );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePI2FDRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0x0D );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFMAXMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0xA4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFMAXRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0xA4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFMINMtoR( x86IntRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( from );
|
||||||
|
write8<I>( 0x94 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePFMINRtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x0F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( 0x94 );
|
||||||
|
}
|
|
@ -0,0 +1,276 @@
|
||||||
|
/* Pcsx2 - Pc Ps2 Emulator
|
||||||
|
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
//#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// FPU instructions
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* fild m32 to fpu reg stack */
|
||||||
|
emitterT void eFILD32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDB );
|
||||||
|
ModRM<I>( 0, 0x0, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fistp m32 from fpu reg stack */
|
||||||
|
emitterT void eFISTP32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDB );
|
||||||
|
ModRM<I>( 0, 0x3, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fld m32 to fpu reg stack */
|
||||||
|
emitterT void eFLD32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD9 );
|
||||||
|
ModRM<I>( 0, 0x0, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fld st(i)
|
||||||
|
emitterT void eFLD(int st) { write16<I>(0xc0d9+(st<<8)); }
|
||||||
|
emitterT void eFLD1() { write16<I>(0xe8d9); }
|
||||||
|
emitterT void eFLDL2E() { write16<I>(0xead9); }
|
||||||
|
|
||||||
|
/* fst m32 from fpu reg stack */
|
||||||
|
emitterT void eFST32( u32 to )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD9 );
|
||||||
|
ModRM<I>( 0, 0x2, DISP32 );
|
||||||
|
write32<I>( MEMADDR(to, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fstp m32 from fpu reg stack */
|
||||||
|
emitterT void eFSTP32( u32 to )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD9 );
|
||||||
|
ModRM<I>( 0, 0x3, DISP32 );
|
||||||
|
write32<I>( MEMADDR(to, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fstp st(i)
|
||||||
|
emitterT void eFSTP(int st) { write16<I>(0xd8dd+(st<<8)); }
|
||||||
|
|
||||||
|
/* fldcw fpu control word from m16 */
|
||||||
|
emitterT void eFLDCW( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD9 );
|
||||||
|
ModRM<I>( 0, 0x5, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fnstcw fpu control word to m16 */
|
||||||
|
emitterT void eFNSTCW( u32 to )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD9 );
|
||||||
|
ModRM<I>( 0, 0x7, DISP32 );
|
||||||
|
write32<I>( MEMADDR(to, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eFNSTSWtoAX() { write16<I>(0xE0DF); }
|
||||||
|
emitterT void eFXAM() { write16<I>(0xe5d9); }
|
||||||
|
emitterT void eFDECSTP() { write16<I>(0xf6d9); }
|
||||||
|
emitterT void eFRNDINT() { write16<I>(0xfcd9); }
|
||||||
|
emitterT void eFXCH(int st) { write16<I>(0xc8d9+(st<<8)); }
|
||||||
|
emitterT void eF2XM1() { write16<I>(0xf0d9); }
|
||||||
|
emitterT void eFSCALE() { write16<I>(0xfdd9); }
|
||||||
|
emitterT void eFPATAN(void) { write16<I>(0xf3d9); }
|
||||||
|
emitterT void eFSIN(void) { write16<I>(0xfed9); }
|
||||||
|
|
||||||
|
/* fadd ST(src) to fpu reg stack ST(0) */
|
||||||
|
emitterT void eFADD32Rto0( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
write8<I>( 0xC0 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fadd ST(0) to fpu reg stack ST(src) */
|
||||||
|
emitterT void eFADD320toR( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDC );
|
||||||
|
write8<I>( 0xC0 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fsub ST(src) to fpu reg stack ST(0) */
|
||||||
|
emitterT void eFSUB32Rto0( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
write8<I>( 0xE0 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fsub ST(0) to fpu reg stack ST(src) */
|
||||||
|
emitterT void eFSUB320toR( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDC );
|
||||||
|
write8<I>( 0xE8 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fsubp -> substract ST(0) from ST(1), store in ST(1) and POP stack */
|
||||||
|
emitterT void eFSUBP( void )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDE );
|
||||||
|
write8<I>( 0xE9 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fmul ST(src) to fpu reg stack ST(0) */
|
||||||
|
emitterT void eFMUL32Rto0( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
write8<I>( 0xC8 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fmul ST(0) to fpu reg stack ST(src) */
|
||||||
|
emitterT void eFMUL320toR( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDC );
|
||||||
|
write8<I>( 0xC8 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fdiv ST(src) to fpu reg stack ST(0) */
|
||||||
|
emitterT void eFDIV32Rto0( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
write8<I>( 0xF0 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fdiv ST(0) to fpu reg stack ST(src) */
|
||||||
|
emitterT void eFDIV320toR( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDC );
|
||||||
|
write8<I>( 0xF8 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eFDIV320toRP( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDE );
|
||||||
|
write8<I>( 0xF8 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fadd m32 to fpu reg stack */
|
||||||
|
emitterT void eFADD32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
ModRM<I>( 0, 0x0, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fsub m32 to fpu reg stack */
|
||||||
|
emitterT void eFSUB32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
ModRM<I>( 0, 0x4, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fmul m32 to fpu reg stack */
|
||||||
|
emitterT void eFMUL32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
ModRM<I>( 0, 0x1, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fdiv m32 to fpu reg stack */
|
||||||
|
emitterT void eFDIV32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
ModRM<I>( 0, 0x6, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fabs fpu reg stack */
|
||||||
|
emitterT void eFABS( void )
|
||||||
|
{
|
||||||
|
write16<I>( 0xE1D9 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fsqrt fpu reg stack */
|
||||||
|
emitterT void eFSQRT( void )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFAD9 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fchs fpu reg stack */
|
||||||
|
emitterT void eFCHS( void )
|
||||||
|
{
|
||||||
|
write16<I>( 0xE0D9 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fcomi st, st(i) */
|
||||||
|
emitterT void eFCOMI( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDB );
|
||||||
|
write8<I>( 0xF0 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fcomip st, st(i) */
|
||||||
|
emitterT void eFCOMIP( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDF );
|
||||||
|
write8<I>( 0xF0 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fucomi st, st(i) */
|
||||||
|
emitterT void eFUCOMI( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDB );
|
||||||
|
write8<I>( 0xE8 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fucomip st, st(i) */
|
||||||
|
emitterT void eFUCOMIP( x86IntRegType src )
|
||||||
|
{
|
||||||
|
write8<I>( 0xDF );
|
||||||
|
write8<I>( 0xE8 + src );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fcom m32 to fpu reg stack */
|
||||||
|
emitterT void eFCOM32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
ModRM<I>( 0, 0x2, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fcomp m32 to fpu reg stack */
|
||||||
|
emitterT void eFCOMP32( u32 from )
|
||||||
|
{
|
||||||
|
write8<I>( 0xD8 );
|
||||||
|
ModRM<I>( 0, 0x3, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FCMOV32( low, high ) \
|
||||||
|
{ \
|
||||||
|
write8<I>( low ); \
|
||||||
|
write8<I>( high + from ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eFCMOVB32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC0 ); }
|
||||||
|
emitterT void eFCMOVE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC8 ); }
|
||||||
|
emitterT void eFCMOVBE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD0 ); }
|
||||||
|
emitterT void eFCMOVU32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD8 ); }
|
||||||
|
emitterT void eFCMOVNB32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC0 ); }
|
||||||
|
emitterT void eFCMOVNE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC8 ); }
|
||||||
|
emitterT void eFCMOVNBE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD0 ); }
|
||||||
|
emitterT void eFCMOVNU32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD8 ); }
|
|
@ -0,0 +1,648 @@
|
||||||
|
/* Pcsx2 - Pc Ps2 Emulator
|
||||||
|
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
//#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// MMX instructions
|
||||||
|
//
|
||||||
|
// note: r64 = mm
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* movq m64 to r64 */
|
||||||
|
emitterT void eMOVQMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6F0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* movq r64 to m64 */
|
||||||
|
emitterT void eMOVQRtoM( uptr to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x7F0F );
|
||||||
|
ModRM<I>( 0, from, DISP32 );
|
||||||
|
write32<I>(MEMADDR(to, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pand r64 to r64 */
|
||||||
|
emitterT void ePANDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xDB0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePANDNRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xDF0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* por r64 to r64 */
|
||||||
|
emitterT void ePORRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xEB0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pxor r64 to r64 */
|
||||||
|
emitterT void ePXORRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xEF0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* psllq r64 to r64 */
|
||||||
|
emitterT void ePSLLQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xF30F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* psllq m64 to r64 */
|
||||||
|
emitterT void ePSLLQMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xF30F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* psllq imm8 to r64 */
|
||||||
|
emitterT void ePSLLQItoR( x86MMXRegType to, u8 from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x730F );
|
||||||
|
ModRM<I>( 3, 6, to);
|
||||||
|
write8<I>( from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* psrlq r64 to r64 */
|
||||||
|
emitterT void ePSRLQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xD30F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* psrlq m64 to r64 */
|
||||||
|
emitterT void ePSRLQMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xD30F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* psrlq imm8 to r64 */
|
||||||
|
emitterT void ePSRLQItoR( x86MMXRegType to, u8 from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x730F );
|
||||||
|
ModRM<I>( 3, 2, to);
|
||||||
|
write8<I>( from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddusb r64 to r64 */
|
||||||
|
emitterT void ePADDUSBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xDC0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddusb m64 to r64 */
|
||||||
|
emitterT void ePADDUSBMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xDC0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddusw r64 to r64 */
|
||||||
|
emitterT void ePADDUSWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xDD0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddusw m64 to r64 */
|
||||||
|
emitterT void ePADDUSWMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xDD0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddb r64 to r64 */
|
||||||
|
emitterT void ePADDBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFC0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddb m64 to r64 */
|
||||||
|
emitterT void ePADDBMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFC0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddw r64 to r64 */
|
||||||
|
emitterT void ePADDWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFD0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddw m64 to r64 */
|
||||||
|
emitterT void ePADDWMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFD0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddd r64 to r64 */
|
||||||
|
emitterT void ePADDDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFE0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* paddd m64 to r64 */
|
||||||
|
emitterT void ePADDDMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFE0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* emms */
|
||||||
|
emitterT void eEMMS()
|
||||||
|
{
|
||||||
|
write16<I>( 0x770F );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePADDSBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xEC0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePADDSWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xED0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paddq m64 to r64 (sse2 only?)
|
||||||
|
emitterT void ePADDQMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xD40F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paddq r64 to r64 (sse2 only?)
|
||||||
|
emitterT void ePADDQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xD40F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSUBSBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xE80F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSUBSWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xE90F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
emitterT void ePSUBBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xF80F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSUBWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xF90F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSUBDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFA0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSUBDMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFA0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSUBUSBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xD80F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSUBUSWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xD90F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
// psubq m64 to r64 (sse2 only?)
|
||||||
|
emitterT void ePSUBQMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFB0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// psubq r64 to r64 (sse2 only?)
|
||||||
|
emitterT void ePSUBQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xFB0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pmuludq m64 to r64 (sse2 only?)
|
||||||
|
emitterT void ePMULUDQMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xF40F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pmuludq r64 to r64 (sse2 only?)
|
||||||
|
emitterT void ePMULUDQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xF40F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePCMPEQBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x740F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePCMPEQWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x750F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePCMPEQDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x760F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePCMPEQDMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x760F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePCMPGTBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x640F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePCMPGTWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x650F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePCMPGTDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x660F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePCMPGTDMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x660F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSRLWItoR( x86MMXRegType to, u8 from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x710F );
|
||||||
|
ModRM<I>( 3, 2 , to );
|
||||||
|
write8<I>( from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSRLDItoR( x86MMXRegType to, u8 from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x720F );
|
||||||
|
ModRM<I>( 3, 2 , to );
|
||||||
|
write8<I>( from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSRLDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xD20F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSLLWItoR( x86MMXRegType to, u8 from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x710F );
|
||||||
|
ModRM<I>( 3, 6 , to );
|
||||||
|
write8<I>( from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSLLDItoR( x86MMXRegType to, u8 from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x720F );
|
||||||
|
ModRM<I>( 3, 6 , to );
|
||||||
|
write8<I>( from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSLLDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xF20F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSRAWItoR( x86MMXRegType to, u8 from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x710F );
|
||||||
|
ModRM<I>( 3, 4 , to );
|
||||||
|
write8<I>( from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSRADItoR( x86MMXRegType to, u8 from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x720F );
|
||||||
|
ModRM<I>( 3, 4 , to );
|
||||||
|
write8<I>( from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSRADRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xE20F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* por m64 to r64 */
|
||||||
|
emitterT void ePORMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xEB0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pxor m64 to r64 */
|
||||||
|
emitterT void ePXORMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xEF0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pand m64 to r64 */
|
||||||
|
emitterT void ePANDMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
//u64 rip = (u64)x86Ptr[0] + 7;
|
||||||
|
write16<I>( 0xDB0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePANDNMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0xDF0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePUNPCKHDQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6A0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePUNPCKHDQMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6A0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePUNPCKLDQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x620F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePUNPCKLDQMtoR( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x620F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVQ64ItoR( x86MMXRegType reg, u64 i )
|
||||||
|
{
|
||||||
|
eMOVQMtoR<I>( reg, ( uptr )(x86Ptr[0]) + 2 + 7 );
|
||||||
|
eJMP8<I>( 8 );
|
||||||
|
write64<I>( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6F0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVQRmtoROffset( x86MMXRegType to, x86IntRegType from, u32 offset )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6F0F );
|
||||||
|
|
||||||
|
if( offset < 128 ) {
|
||||||
|
ModRM<I>( 1, to, from );
|
||||||
|
write8<I>(offset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ModRM<I>( 2, to, from );
|
||||||
|
write32<I>(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVQRtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
|
||||||
|
{
|
||||||
|
write16<I>( 0x7F0F );
|
||||||
|
|
||||||
|
if( offset < 128 ) {
|
||||||
|
ModRM<I>( 1, from , to );
|
||||||
|
write8<I>(offset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ModRM<I>( 2, from, to );
|
||||||
|
write32<I>(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* movd m32 to r64 */
|
||||||
|
emitterT void eMOVDMtoMMX( x86MMXRegType to, uptr from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6E0F );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* movd r64 to m32 */
|
||||||
|
emitterT void eMOVDMMXtoM( uptr to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x7E0F );
|
||||||
|
ModRM<I>( 0, from, DISP32 );
|
||||||
|
write32<I>( MEMADDR(to, 4) );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVD32RtoMMX( x86MMXRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6E0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6E0F );
|
||||||
|
ModRM<I>( 0, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVD32RmOffsettoMMX( x86MMXRegType to, x86IntRegType from, u32 offset )
|
||||||
|
{
|
||||||
|
write16<I>( 0x6E0F );
|
||||||
|
|
||||||
|
if( offset < 128 ) {
|
||||||
|
ModRM<I>( 1, to, from );
|
||||||
|
write8<I>(offset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ModRM<I>( 2, to, from );
|
||||||
|
write32<I>(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVD32MMXtoR( x86IntRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x7E0F );
|
||||||
|
ModRM<I>( 3, from, to );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from )
|
||||||
|
{
|
||||||
|
write16<I>( 0x7E0F );
|
||||||
|
ModRM<I>( 0, from, to );
|
||||||
|
if( to >= 4 ) {
|
||||||
|
// no idea why
|
||||||
|
assert( to == ESP );
|
||||||
|
write8<I>(0x24);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMOVD32MMXtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
|
||||||
|
{
|
||||||
|
write16<I>( 0x7E0F );
|
||||||
|
|
||||||
|
if( offset < 128 ) {
|
||||||
|
ModRM<I>( 1, from, to );
|
||||||
|
write8<I>(offset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ModRM<I>( 2, from, to );
|
||||||
|
write32<I>(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///* movd r32 to r64 */
|
||||||
|
//emitterT void eMOVD32MMXtoMMX( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
//{
|
||||||
|
// write16<I>( 0x6E0F );
|
||||||
|
// ModRM<I>( 3, to, from );
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
///* movq r64 to r32 */
|
||||||
|
//emitterT void eMOVD64MMXtoMMX( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
//{
|
||||||
|
// write16<I>( 0x7E0F );
|
||||||
|
// ModRM<I>( 3, from, to );
|
||||||
|
//}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
emitterT void ePACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
|
||||||
|
{
|
||||||
|
write16<I>( 0x630F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
|
||||||
|
{
|
||||||
|
write16<I>( 0x6B0F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from)
|
||||||
|
{
|
||||||
|
write16<I>( 0xD70F );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 )
|
||||||
|
{
|
||||||
|
if (to > 7 || from > 7) Rex(1, to >> 3, 0, from >> 3);
|
||||||
|
write16<I>( 0xc40f );
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>( imm8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8)
|
||||||
|
{
|
||||||
|
write16<I>(0x700f);
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
write8<I>(imm8);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void ePSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8)
|
||||||
|
{
|
||||||
|
write16<I>( 0x700f );
|
||||||
|
ModRM<I>( 0, to, DISP32 );
|
||||||
|
write32<I>( MEMADDR(from, 4) );
|
||||||
|
write8<I>(imm8);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void eMASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from)
|
||||||
|
{
|
||||||
|
write16<I>(0xf70f);
|
||||||
|
ModRM<I>( 3, to, from );
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -15,10 +15,11 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "microVU.h"
|
|
||||||
#ifdef PCSX2_MICROVU
|
#ifdef PCSX2_MICROVU
|
||||||
|
#include "microVU.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Micro VU Micromode Lower instructions
|
// Micro VU Micromode Lower instructions
|
||||||
|
|
Loading…
Reference in New Issue