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:
cottonvibes 2009-03-01 14:42:31 +00:00
parent 9deff96c78
commit e2d583c7fe
16 changed files with 6066 additions and 5016 deletions

View File

@ -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"

View File

@ -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:

View File

@ -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 );

View File

@ -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();

View File

@ -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) {

View File

@ -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;
} }

View File

@ -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 );

View File

@ -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

3336
pcsx2/x86/ix86/ix86.inl Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 );
}

276
pcsx2/x86/ix86/ix86_fpu.inl Normal file
View File

@ -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 ); }

648
pcsx2/x86/ix86/ix86_mmx.inl Normal file
View File

@ -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 );
}

1407
pcsx2/x86/ix86/ix86_sse.inl Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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