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
|
||||
RelativePath="..\..\x86\ix86\ix86_3dnow.cpp"
|
||||
RelativePath="..\..\x86\ix86\ix86.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\ix86\ix86_3dnow.inl"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Devel vm|Win32"
|
||||
|
@ -2886,7 +2890,7 @@
|
|||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\ix86\ix86_fpu.cpp"
|
||||
RelativePath="..\..\x86\ix86\ix86_fpu.inl"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
|
@ -2922,7 +2926,11 @@
|
|||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\ix86\ix86_mmx.cpp"
|
||||
RelativePath="..\..\x86\ix86\ix86_macros.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\ix86\ix86_mmx.inl"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
|
@ -2958,7 +2966,7 @@
|
|||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\ix86\ix86_sse.cpp"
|
||||
RelativePath="..\..\x86\ix86\ix86_sse.inl"
|
||||
>
|
||||
<FileConfiguration
|
||||
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
|
||||
#define QFSRVhelper0() { \
|
||||
ajmp[0] = JMP32(0); \
|
||||
x86Ptr += 11; \
|
||||
x86Ptr[0] += 11; \
|
||||
}
|
||||
|
||||
#define QFSRVhelper(shift1, shift2) { \
|
||||
SSE2_PSRLDQ_I8_to_XMM(EEREC_D, shift1); \
|
||||
SSE2_PSLLDQ_I8_to_XMM(t0reg, shift2); \
|
||||
ajmp[shift1] = JMP32(0); \
|
||||
x86Ptr += 1; \
|
||||
x86Ptr[0] += 1; \
|
||||
}
|
||||
|
||||
void recQFSRV()
|
||||
|
@ -2003,7 +2003,7 @@ void recQFSRV()
|
|||
MOV32MtoR(EAX, (uptr)&cpuRegs.sa);
|
||||
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)
|
||||
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)
|
||||
|
||||
// Case 0:
|
||||
|
|
|
@ -188,7 +188,7 @@ static void iIopDumpBlock( int startpc, u8 * ptr )
|
|||
#ifdef __LINUX__
|
||||
// dump the asm
|
||||
f = fopen( "mydump1", "wb" );
|
||||
fwrite( ptr, 1, (uptr)x86Ptr - (uptr)ptr, f );
|
||||
fwrite( ptr, 1, (uptr)x86Ptr[0] - (uptr)ptr, f );
|
||||
fclose( f );
|
||||
sprintf( command, "objdump -D --target=binary --architecture=i386 -M intel mydump1 | cat %s - > tempdump", filename );
|
||||
system( command );
|
||||
|
@ -635,8 +635,6 @@ static void recShutdown()
|
|||
safe_free(psxRecLUT);
|
||||
safe_free( s_pInstCache );
|
||||
s_nInstCacheSize = 0;
|
||||
|
||||
x86Shutdown();
|
||||
}
|
||||
|
||||
#pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code
|
||||
|
@ -722,7 +720,7 @@ __declspec(naked) void psxDispatcher()
|
|||
__asm
|
||||
{
|
||||
shl eax,4
|
||||
pop ecx // x86Ptr to mod
|
||||
pop ecx // x86Ptr[0] to mod
|
||||
mov edx, eax
|
||||
sub edx, ecx
|
||||
sub edx, 4
|
||||
|
@ -900,14 +898,14 @@ void psxRecClearMem(BASEBLOCK* p)
|
|||
assert( p->GetFnptr() != 0 );
|
||||
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
|
||||
MOV32ItoR(EDX, p->startpc);
|
||||
assert( (uptr)x86Ptr <= 0xffffffff );
|
||||
PUSH32I((uptr)x86Ptr);
|
||||
JMP32((uptr)psxDispatcherClear - ( (uptr)x86Ptr + 5 ));
|
||||
assert( x86Ptr == (u8*)p->GetFnptr() + IOP_MIN_BLOCK_BYTES );
|
||||
assert( (uptr)x86Ptr[0] <= 0xffffffff );
|
||||
PUSH32I((uptr)x86Ptr[0]);
|
||||
JMP32((uptr)psxDispatcherClear - ( (uptr)x86Ptr[0] + 5 ));
|
||||
assert( x86Ptr[0] == (u8*)p->GetFnptr() + IOP_MIN_BLOCK_BYTES );
|
||||
|
||||
pstart = PSX_GETBLOCK(p->startpc);
|
||||
pexblock = PSX_GETBLOCKEX(pstart);
|
||||
|
@ -954,7 +952,7 @@ void psxSetBranchReg(u32 reg)
|
|||
_psxFlushCall(FLUSH_EVERYTHING);
|
||||
iPsxBranchTest(0xffffffff, 1);
|
||||
|
||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||
}
|
||||
|
||||
void psxSetBranchImm( u32 imm )
|
||||
|
@ -969,8 +967,8 @@ void psxSetBranchImm( u32 imm )
|
|||
iPsxBranchTest(imm, imm <= psxpc);
|
||||
|
||||
MOV32ItoR(EDX, 0);
|
||||
ptr = (u32*)(x86Ptr-4);
|
||||
*ptr = (uptr)JMP32((uptr)psxDispatcher - ( (uptr)x86Ptr + 5 ));
|
||||
ptr = (u32*)(x86Ptr[0]-4);
|
||||
*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?)
|
||||
|
@ -1011,7 +1009,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
|
|||
if( newpc != 0xffffffff )
|
||||
{
|
||||
CMP32ItoM((uptr)&psxRegs.pc, newpc);
|
||||
JNE32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 6 ));
|
||||
JNE32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 6 ));
|
||||
}
|
||||
|
||||
// Skip branch jump target here:
|
||||
|
@ -1047,7 +1045,7 @@ void rpsxSYSCALL()
|
|||
|
||||
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
||||
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||
|
||||
// jump target for skipping blockCycle updates
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
|
@ -1067,7 +1065,7 @@ void rpsxBREAK()
|
|||
j8Ptr[0] = JE8(0);
|
||||
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
||||
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
|
||||
//if (!psxbranch) psxbranch = 2;
|
||||
|
@ -1103,22 +1101,22 @@ void psxRecompileNextInstruction(int delayslot)
|
|||
|
||||
// if( pexblock->pOldFnptr ) {
|
||||
// // 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;
|
||||
// return;
|
||||
// }
|
||||
|
||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr + 5));
|
||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr[0] + 5));
|
||||
psxbranch = 3;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
if( !(delayslot && pblock->startpc == psxpc) ) {
|
||||
u8* oldX86 = x86Ptr;
|
||||
u8* oldX86 = x86Ptr[0];
|
||||
//__Log("clear block %x\n", pblock->startpc);
|
||||
psxRecClearMem(pblock);
|
||||
x86Ptr = oldX86;
|
||||
x86Ptr[0] = oldX86;
|
||||
if( delayslot )
|
||||
SysPrintf("delay slot %x\n", psxpc);
|
||||
}
|
||||
|
@ -1289,12 +1287,12 @@ void psxRecRecompile(u32 startpc)
|
|||
|
||||
x86SetPtr( recPtr );
|
||||
x86Align(16);
|
||||
recPtr = x86Ptr;
|
||||
recPtr = x86Ptr[0];
|
||||
|
||||
psxbranch = 0;
|
||||
|
||||
s_pCurBlock->startpc = startpc;
|
||||
s_pCurBlock->SetFnptr( (uptr)x86Ptr );
|
||||
s_pCurBlock->SetFnptr( (uptr)x86Ptr[0] );
|
||||
s_psxBlockCycles = 0;
|
||||
|
||||
// reset recomp state variables
|
||||
|
@ -1440,7 +1438,7 @@ StartRecomp:
|
|||
|
||||
iPsxBranchTest(0xffffffff, 1);
|
||||
|
||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
||||
JMP32((uptr)psxDispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||
}
|
||||
else {
|
||||
assert( psxbranch != 3 );
|
||||
|
@ -1456,7 +1454,7 @@ StartRecomp:
|
|||
assert( psxpc == s_nEndBlock );
|
||||
_psxFlushCall(FLUSH_EVERYTHING);
|
||||
MOV32ItoM((uptr)&psxRegs.pc, psxpc);
|
||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr + 5));
|
||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr[0] + 5));
|
||||
psxbranch = 3;
|
||||
}
|
||||
else if( !psxbranch ) {
|
||||
|
@ -1466,14 +1464,14 @@ StartRecomp:
|
|||
_psxFlushCall(FLUSH_EVERYTHING);
|
||||
|
||||
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 < recMem+RECMEM_SIZE );
|
||||
assert( x86Ptr[0] >= (u8*)s_pCurBlock->GetFnptr() + IOP_MIN_BLOCK_BYTES );
|
||||
assert( x86Ptr[0] < recMem+RECMEM_SIZE );
|
||||
|
||||
recPtr = x86Ptr;
|
||||
recPtr = x86Ptr[0];
|
||||
|
||||
assert( (g_psxHasConstReg&g_psxFlushedConstReg) == g_psxHasConstReg );
|
||||
|
||||
|
|
|
@ -1259,7 +1259,7 @@ void rpsxJALR()
|
|||
static void* s_pbranchjmp;
|
||||
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)
|
||||
{
|
||||
|
@ -1306,7 +1306,7 @@ void rpsxBEQ_process(int info, int process)
|
|||
else
|
||||
{
|
||||
_psxFlushAllUnused();
|
||||
u8* prevx86 = x86Ptr;
|
||||
u8* prevx86 = x86Ptr[0];
|
||||
s_do32 = 0;
|
||||
psxSaveBranchState();
|
||||
|
||||
|
@ -1319,7 +1319,7 @@ void rpsxBEQ_process(int info, int process)
|
|||
x86SetJ8A( (u8*)s_pbranchjmp );
|
||||
}
|
||||
else {
|
||||
x86Ptr = prevx86;
|
||||
x86Ptr[0] = prevx86;
|
||||
s_do32 = 1;
|
||||
psxpc -= 4;
|
||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||
|
@ -1370,7 +1370,7 @@ void rpsxBNE_process(int info, int process)
|
|||
}
|
||||
|
||||
_psxFlushAllUnused();
|
||||
u8* prevx86 = x86Ptr;
|
||||
u8* prevx86 = x86Ptr[0];
|
||||
s_do32 = 0;
|
||||
rpsxSetBranchEQ(info, process);
|
||||
|
||||
|
@ -1382,7 +1382,7 @@ void rpsxBNE_process(int info, int process)
|
|||
x86SetJ8A( (u8*)s_pbranchjmp );
|
||||
}
|
||||
else {
|
||||
x86Ptr = prevx86;
|
||||
x86Ptr[0] = prevx86;
|
||||
s_do32 = 1;
|
||||
psxpc -= 4;
|
||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||
|
@ -1424,7 +1424,7 @@ void rpsxBLTZ()
|
|||
}
|
||||
|
||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||
u8* prevx86 = x86Ptr;
|
||||
u8* prevx86 = x86Ptr[0];
|
||||
u8* pjmp = JL8(0);
|
||||
|
||||
psxSaveBranchState();
|
||||
|
@ -1436,7 +1436,7 @@ void rpsxBLTZ()
|
|||
x86SetJ8A( pjmp );
|
||||
}
|
||||
else {
|
||||
x86Ptr = prevx86;
|
||||
x86Ptr[0] = prevx86;
|
||||
psxpc -= 4;
|
||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||
psxLoadBranchState();
|
||||
|
@ -1471,7 +1471,7 @@ void rpsxBGEZ()
|
|||
}
|
||||
|
||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||
u8* prevx86 = x86Ptr;
|
||||
u8* prevx86 = x86Ptr[0];
|
||||
u8* pjmp = JGE8(0);
|
||||
|
||||
psxSaveBranchState();
|
||||
|
@ -1483,7 +1483,7 @@ void rpsxBGEZ()
|
|||
x86SetJ8A( pjmp );
|
||||
}
|
||||
else {
|
||||
x86Ptr = prevx86;
|
||||
x86Ptr[0] = prevx86;
|
||||
psxpc -= 4;
|
||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||
psxLoadBranchState();
|
||||
|
@ -1525,7 +1525,7 @@ void rpsxBLTZAL()
|
|||
}
|
||||
|
||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||
u8* prevx86 = x86Ptr;
|
||||
u8* prevx86 = x86Ptr[0];
|
||||
u8* pjmp = JL8(0);
|
||||
|
||||
psxSaveBranchState();
|
||||
|
@ -1539,7 +1539,7 @@ void rpsxBLTZAL()
|
|||
x86SetJ8A( pjmp );
|
||||
}
|
||||
else {
|
||||
x86Ptr = prevx86;
|
||||
x86Ptr[0] = prevx86;
|
||||
psxpc -= 4;
|
||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||
psxLoadBranchState();
|
||||
|
@ -1578,7 +1578,7 @@ void rpsxBGEZAL()
|
|||
}
|
||||
|
||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||
u8* prevx86 = x86Ptr;
|
||||
u8* prevx86 = x86Ptr[0];
|
||||
u8* pjmp = JGE8(0);
|
||||
|
||||
MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4);
|
||||
|
@ -1592,7 +1592,7 @@ void rpsxBGEZAL()
|
|||
x86SetJ8A( pjmp );
|
||||
}
|
||||
else {
|
||||
x86Ptr = prevx86;
|
||||
x86Ptr[0] = prevx86;
|
||||
psxpc -= 4;
|
||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||
psxLoadBranchState();
|
||||
|
@ -1632,7 +1632,7 @@ void rpsxBLEZ()
|
|||
_clearNeededX86regs();
|
||||
|
||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||
u8* prevx86 = x86Ptr;
|
||||
u8* prevx86 = x86Ptr[0];
|
||||
u8* pjmp = JLE8(0);
|
||||
|
||||
psxSaveBranchState();
|
||||
|
@ -1643,7 +1643,7 @@ void rpsxBLEZ()
|
|||
x86SetJ8A( pjmp );
|
||||
}
|
||||
else {
|
||||
x86Ptr = prevx86;
|
||||
x86Ptr[0] = prevx86;
|
||||
psxpc -= 4;
|
||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||
psxLoadBranchState();
|
||||
|
@ -1680,7 +1680,7 @@ void rpsxBGTZ()
|
|||
_clearNeededX86regs();
|
||||
|
||||
CMP32ItoM((uptr)&psxRegs.GPR.r[_Rs_], 0);
|
||||
u8* prevx86 = x86Ptr;
|
||||
u8* prevx86 = x86Ptr[0];
|
||||
u8* pjmp = JG8(0);
|
||||
|
||||
psxSaveBranchState();
|
||||
|
@ -1691,7 +1691,7 @@ void rpsxBGTZ()
|
|||
x86SetJ8A( pjmp );
|
||||
}
|
||||
else {
|
||||
x86Ptr = prevx86;
|
||||
x86Ptr[0] = prevx86;
|
||||
psxpc -= 4;
|
||||
psxRegs.code = iopMemRead32( psxpc - 4 );
|
||||
psxLoadBranchState();
|
||||
|
|
|
@ -1569,7 +1569,7 @@ void recLQC2_co( void )
|
|||
|
||||
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
||||
|
||||
rawreadptr = x86Ptr;
|
||||
rawreadptr = x86Ptr[0];
|
||||
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_);
|
||||
|
||||
|
@ -1579,7 +1579,7 @@ void recLQC2_co( void )
|
|||
|
||||
// check if writing to VUs
|
||||
CMP32ItoR(ECX, 0x11000000);
|
||||
JAE8(rawreadptr - (x86Ptr+2));
|
||||
JAE8(rawreadptr - (x86Ptr[0]+2));
|
||||
|
||||
MOV32RtoM((u32)&s_tempaddr, ECX);
|
||||
|
||||
|
@ -1634,7 +1634,7 @@ void recSQC2_co( void )
|
|||
|
||||
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
||||
|
||||
rawreadptr = x86Ptr;
|
||||
rawreadptr = x86Ptr[0];
|
||||
|
||||
if( mmreg1 >= 0 ) {
|
||||
SSEX_MOVDQARtoRmOffset(ECX, mmreg1, PS2MEM_BASE_+s_nAddMemOffset);
|
||||
|
@ -1705,7 +1705,7 @@ void recSQC2_co( void )
|
|||
|
||||
// check if writing to VUs
|
||||
CMP32ItoR(ECX, 0x11000000);
|
||||
JAE8(rawreadptr - (x86Ptr+2));
|
||||
JAE8(rawreadptr - (x86Ptr[0]+2));
|
||||
|
||||
// some type of hardware write
|
||||
if( mmreg1 >= 0) {
|
||||
|
|
|
@ -846,7 +846,7 @@ static VuFunctionHeader* SuperVURecompileProgram(u32 startpc, int vuindex)
|
|||
|
||||
SuperVURecompile();
|
||||
|
||||
s_recVUPtr = x86Ptr;
|
||||
s_recVUPtr = x86Ptr[0];
|
||||
|
||||
// set the function's range
|
||||
VuFunctionHeader::RANGE r;
|
||||
|
@ -1883,7 +1883,7 @@ void VuBaseBlock::AssignVFRegs()
|
|||
if( i == XMMREGS ) return; // nothing changed
|
||||
}
|
||||
|
||||
u8* oldX86 = x86Ptr;
|
||||
u8* oldX86 = x86Ptr[0];
|
||||
|
||||
FORIT(itinst, insts) {
|
||||
|
||||
|
@ -2072,7 +2072,7 @@ void VuBaseBlock::AssignVFRegs()
|
|||
}
|
||||
}
|
||||
|
||||
assert( x86Ptr == oldX86 );
|
||||
assert( x86Ptr[0] == oldX86 );
|
||||
u32 analyzechildren = !(type&BLOCKTYPE_ANALYZED);
|
||||
type |= BLOCKTYPE_ANALYZED;
|
||||
|
||||
|
@ -2460,7 +2460,7 @@ static void SuperVURecompile()
|
|||
AND32ItoM( (uptr)&VU->vifRegs->stat, ~0x4 );
|
||||
|
||||
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
|
||||
else assert( (*itblock)->insts.back().regs[0].pipe == VUPIPE_BRANCH );
|
||||
|
@ -2600,11 +2600,11 @@ void SuperVUTestVU0Condition(u32 incstack)
|
|||
|
||||
ADD32ItoR(ESP, incstack);
|
||||
//CALLFunc((u32)timeout);
|
||||
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 5 ));
|
||||
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr[0] + 5 ));
|
||||
|
||||
x86SetJ8(ptr);
|
||||
}
|
||||
else JAE32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 6 ) );
|
||||
else JAE32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr[0] + 6 ) );
|
||||
}
|
||||
|
||||
void VuBaseBlock::Recompile()
|
||||
|
@ -2612,7 +2612,7 @@ void VuBaseBlock::Recompile()
|
|||
if( type & BLOCKTYPE_ANALYZED ) return;
|
||||
|
||||
x86Align(16);
|
||||
pcode = x86Ptr;
|
||||
pcode = x86Ptr[0];
|
||||
|
||||
#ifdef _DEBUG
|
||||
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)&VU->vifRegs->stat, ~0x4 );
|
||||
if( !branch ) MOV32ItoM((uptr)&VU->VI[REG_TPC], endpc);
|
||||
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr + 5 ));
|
||||
JMP32( (uptr)SuperVUEndProgram - ( (uptr)x86Ptr[0] + 5 ));
|
||||
}
|
||||
else {
|
||||
|
||||
|
@ -2862,7 +2862,7 @@ void VuBaseBlock::Recompile()
|
|||
}
|
||||
}
|
||||
|
||||
pendcode = x86Ptr;
|
||||
pendcode = x86Ptr[0];
|
||||
type |= BLOCKTYPE_ANALYZED;
|
||||
|
||||
LISTBLOCKS::iterator itchild;
|
||||
|
@ -3543,7 +3543,7 @@ void recVUMI_BranchHandle()
|
|||
if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION)
|
||||
MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), bpc);
|
||||
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) ) {
|
||||
j8Ptr[1] = JMP8(0);
|
||||
|
@ -3552,7 +3552,7 @@ void recVUMI_BranchHandle()
|
|||
if( (s_pCurBlock->type & BLOCKTYPE_HASEOP) || s_vu == 0 || SUPERVU_CHECKCONDITION )
|
||||
MOV32ItoM(SuperVUGetVIAddr(REG_TPC, 0), pc+8);
|
||||
MOV32ItoR(s_JumpX86, 0);
|
||||
s_pCurBlock->pChildJumps[curjump+1] = (u32*)x86Ptr-1;
|
||||
s_pCurBlock->pChildJumps[curjump+1] = (u32*)x86Ptr[0]-1;
|
||||
|
||||
x86SetJ8( j8Ptr[ 1 ] );
|
||||
}
|
||||
|
@ -3789,7 +3789,7 @@ void recVUMI_B( VURegs* vuu, s32 info )
|
|||
if( s_pCurBlock->blocks.size() > 1 ) {
|
||||
s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3815,7 +3815,7 @@ void recVUMI_BAL( VURegs* vuu, s32 info )
|
|||
if( s_pCurBlock->blocks.size() > 1 ) {
|
||||
s_JumpX86 = _allocX86reg(-1, X86TYPE_VUJUMP, 0, MODE_WRITE);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ static void iDumpBlock( int startpc, u8 * ptr )
|
|||
|
||||
fflush( stdout );
|
||||
// f = fopen( "dump1", "wb" );
|
||||
// fwrite( ptr, 1, (u32)x86Ptr - (u32)ptr, f );
|
||||
// fwrite( ptr, 1, (u32)x86Ptr[0] - (u32)ptr, f );
|
||||
// fclose( f );
|
||||
//
|
||||
// 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)
|
||||
|
||||
//x86SetPtr(recMem+REC_CACHEMEM);
|
||||
//dyna_block_discard_recmem=(u8*)x86Ptr;
|
||||
//JMP32( (uptr)&dyna_block_discard - ( (u32)x86Ptr + 5 ));
|
||||
//dyna_block_discard_recmem=(u8*)x86Ptr[0];
|
||||
//JMP32( (uptr)&dyna_block_discard - ( (u32)x86Ptr[0] + 5 ));
|
||||
|
||||
x86SetPtr(recMem);
|
||||
|
||||
|
@ -613,8 +613,6 @@ static void recShutdown( void )
|
|||
|
||||
safe_free( s_pInstCache );
|
||||
s_nInstCacheSize = 0;
|
||||
|
||||
x86Shutdown();
|
||||
}
|
||||
|
||||
// Ignored by Linux
|
||||
|
@ -675,7 +673,7 @@ static __naked void Dispatcher()
|
|||
// Modify the prev block's jump address, and jump to the new block:
|
||||
__asm {
|
||||
shl eax, 4
|
||||
pop ecx // x86Ptr to mod
|
||||
pop ecx // x86Ptr[0] to mod
|
||||
mov edx, eax
|
||||
sub edx, ecx
|
||||
sub edx, 4
|
||||
|
@ -686,7 +684,7 @@ static __naked void Dispatcher()
|
|||
}
|
||||
|
||||
// edx - baseblock->startpc
|
||||
// stack - x86Ptr
|
||||
// stack - x86Ptr[0]
|
||||
static __naked void DispatcherClear()
|
||||
{
|
||||
// EDX contains the current pc
|
||||
|
@ -869,7 +867,7 @@ void recSYSCALL( void ) {
|
|||
CMP32ItoM((uptr)&cpuRegs.pc, pc);
|
||||
j8Ptr[0] = JE8(0);
|
||||
ADD32ItoM((uptr)&cpuRegs.cycle, eeScaleBlockCycles());
|
||||
JMP32((uptr)DispatcherReg - ( (uptr)x86Ptr + 5 ));
|
||||
JMP32((uptr)DispatcherReg - ( (uptr)x86Ptr[0] + 5 ));
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
//branch = 2;
|
||||
}
|
||||
|
@ -933,13 +931,13 @@ void recClearMem(BASEBLOCK* p)
|
|||
assert( p->GetFnptr() != 0 );
|
||||
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
|
||||
MOV32ItoR(EDX, p->startpc);
|
||||
PUSH32I((u32)x86Ptr); // will be replaced by JMP32
|
||||
JMP32((u32)DispatcherClear - ( (u32)x86Ptr + 5 ));
|
||||
assert( x86Ptr == (u8*)p->GetFnptr() + EE_MIN_BLOCK_BYTES );
|
||||
PUSH32I((u32)x86Ptr[0]); // will be replaced by JMP32
|
||||
JMP32((u32)DispatcherClear - ( (u32)x86Ptr[0] + 5 ));
|
||||
assert( x86Ptr[0] == (u8*)p->GetFnptr() + EE_MIN_BLOCK_BYTES );
|
||||
|
||||
pstart = PC_GETBLOCK(p->startpc);
|
||||
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
|
||||
// of a dispatcher.
|
||||
MOV32ItoR(EDX, 0);
|
||||
ptr = (u32*)(x86Ptr-4);
|
||||
ptr = (u32*)(x86Ptr[0]-4);
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
// 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 )
|
||||
{
|
||||
// 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();
|
||||
|
@ -1313,22 +1311,22 @@ void recompileNextInstruction(int delayslot)
|
|||
|
||||
// if( pexblock->pOldFnptr ) {
|
||||
// // 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;
|
||||
// return;
|
||||
// }
|
||||
|
||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr + 5));
|
||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr[0] + 5));
|
||||
branch = 3;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
if( !(delayslot && pblock->startpc == pc) ) {
|
||||
u8* oldX86 = x86Ptr;
|
||||
u8* oldX86 = x86Ptr[0];
|
||||
//__Log("clear block %x\n", pblock->startpc);
|
||||
recClearMem(pblock);
|
||||
x86Ptr = oldX86;
|
||||
x86Ptr[0] = oldX86;
|
||||
if( delayslot )
|
||||
Console::Notice("delay slot %x", params pc);
|
||||
}
|
||||
|
@ -1576,8 +1574,8 @@ void recRecompile( const u32 startpc )
|
|||
|
||||
x86SetPtr( recPtr );
|
||||
x86Align(16);
|
||||
recPtr = x86Ptr;
|
||||
s_pCurBlock->SetFnptr( (uptr)x86Ptr );
|
||||
recPtr = x86Ptr[0];
|
||||
s_pCurBlock->SetFnptr( (uptr)x86Ptr[0] );
|
||||
s_pCurBlock->startpc = startpc;
|
||||
|
||||
branch = 0;
|
||||
|
@ -1906,7 +1904,7 @@ StartRecomp:
|
|||
{
|
||||
//MOV32ItoR(EAX,*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);
|
||||
}
|
||||
|
@ -1918,7 +1916,7 @@ StartRecomp:
|
|||
{
|
||||
// was dyna_block_discard_recmem. See note in recResetEE for details.
|
||||
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;
|
||||
lpc+=4;
|
||||
|
@ -1997,7 +1995,7 @@ StartRecomp:
|
|||
assert( pc == s_nEndBlock );
|
||||
iFlushCall(FLUSH_EVERYTHING);
|
||||
MOV32ItoM((uptr)&cpuRegs.pc, pc);
|
||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr + 5));
|
||||
JMP32((uptr)pblock->GetFnptr() - ((uptr)x86Ptr[0] + 5));
|
||||
branch = 3;
|
||||
}
|
||||
else if( !branch ) {
|
||||
|
@ -2010,12 +2008,12 @@ StartRecomp:
|
|||
}
|
||||
}
|
||||
|
||||
assert( x86Ptr >= (u8*)s_pCurBlock->GetFnptr() + EE_MIN_BLOCK_BYTES );
|
||||
assert( x86Ptr < recMem+REC_CACHEMEM );
|
||||
assert( x86Ptr[0] >= (u8*)s_pCurBlock->GetFnptr() + EE_MIN_BLOCK_BYTES );
|
||||
assert( x86Ptr[0] < recMem+REC_CACHEMEM );
|
||||
assert( recStackPtr < recStack+RECSTACK_SIZE );
|
||||
assert( x86FpuState == 0 );
|
||||
|
||||
recPtr = x86Ptr;
|
||||
recPtr = x86Ptr[0];
|
||||
|
||||
assert( (g_cpuHasConstReg&g_cpuFlushedConstReg) == g_cpuHasConstReg );
|
||||
|
||||
|
|
|
@ -1933,7 +1933,7 @@ void recLQC2( void )
|
|||
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
||||
|
||||
if( _Ft_ ) {
|
||||
u8* rawreadptr = x86Ptr;
|
||||
u8* rawreadptr = x86Ptr[0];
|
||||
|
||||
if( mmreg >= 0 ) {
|
||||
SSEX_MOVDQARmtoROffset(mmreg, ECX, PS2MEM_BASE_+s_nAddMemOffset);
|
||||
|
@ -1948,7 +1948,7 @@ void recLQC2( void )
|
|||
|
||||
// check if writing to VUs
|
||||
CMP32ItoR(ECX, 0x11000000);
|
||||
JAE8(rawreadptr - (x86Ptr+2));
|
||||
JAE8(rawreadptr - (x86Ptr[0]+2));
|
||||
|
||||
PUSH32I( (int)&VU0.VF[_Ft_].UD[0] );
|
||||
CALLFunc( (int)recMemRead128 );
|
||||
|
@ -2002,7 +2002,7 @@ void recSQC2( void )
|
|||
mmregs = _eePrepareReg(_Rs_);
|
||||
dohw = recSetMemLocation(_Rs_, _Imm_, mmregs, 2, 0);
|
||||
|
||||
rawreadptr = x86Ptr;
|
||||
rawreadptr = x86Ptr[0];
|
||||
|
||||
if( (mmreg = _checkXMMreg(XMMTYPE_VFREG, _Ft_, MODE_READ)) >= 0) {
|
||||
SSEX_MOVDQARtoRmOffset(ECX, mmreg, PS2MEM_BASE_+s_nAddMemOffset);
|
||||
|
@ -2042,7 +2042,7 @@ void recSQC2( void )
|
|||
|
||||
// check if writing to VUs
|
||||
CMP32ItoR(ECX, 0x11000000);
|
||||
JAE8(rawreadptr - (x86Ptr+2));
|
||||
JAE8(rawreadptr - (x86Ptr[0]+2));
|
||||
|
||||
// some type of hardware write
|
||||
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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "microVU.h"
|
||||
#ifdef PCSX2_MICROVU
|
||||
#include "microVU.h"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Micro VU Micromode Lower instructions
|
||||
|
|
Loading…
Reference in New Issue