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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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