From e2d583c7fec805565edae4b0788acfb24017ea7f Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Sun, 1 Mar 2009 14:42:31 +0000 Subject: [PATCH] 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 --- pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 16 +- pcsx2/x86/iMMI.cpp | 6 +- pcsx2/x86/iR3000A.cpp | 52 +- pcsx2/x86/iR3000Atables.cpp | 34 +- pcsx2/x86/iR5900CoissuedLoadStore.cpp | 8 +- pcsx2/x86/iVUzerorec.cpp | 26 +- pcsx2/x86/ix86-32/iR5900-32.cpp | 52 +- pcsx2/x86/ix86-32/iR5900LoadStore.cpp | 8 +- pcsx2/x86/ix86/ix86.cpp | 3343 +------------------- pcsx2/x86/ix86/ix86.h | 1666 +--------- pcsx2/x86/ix86/ix86.inl | 3336 +++++++++++++++++++ pcsx2/x86/ix86/ix86_3dnow.inl | 201 ++ pcsx2/x86/ix86/ix86_fpu.inl | 276 ++ pcsx2/x86/ix86/ix86_mmx.inl | 648 ++++ pcsx2/x86/ix86/ix86_sse.inl | 1407 ++++++++ pcsx2/x86/microVU_Lower.cpp | 3 +- 16 files changed, 6066 insertions(+), 5016 deletions(-) create mode 100644 pcsx2/x86/ix86/ix86.inl create mode 100644 pcsx2/x86/ix86/ix86_3dnow.inl create mode 100644 pcsx2/x86/ix86/ix86_fpu.inl create mode 100644 pcsx2/x86/ix86/ix86_mmx.inl create mode 100644 pcsx2/x86/ix86/ix86_sse.inl diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index a595c1e275..012af69d3d 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -2854,7 +2854,11 @@ > + + + + 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 ); diff --git a/pcsx2/x86/iR3000Atables.cpp b/pcsx2/x86/iR3000Atables.cpp index d971bffe6a..fb859660bc 100644 --- a/pcsx2/x86/iR3000Atables.cpp +++ b/pcsx2/x86/iR3000Atables.cpp @@ -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(); diff --git a/pcsx2/x86/iR5900CoissuedLoadStore.cpp b/pcsx2/x86/iR5900CoissuedLoadStore.cpp index 84caeb20c2..13ffe2e86a 100644 --- a/pcsx2/x86/iR5900CoissuedLoadStore.cpp +++ b/pcsx2/x86/iR5900CoissuedLoadStore.cpp @@ -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) { diff --git a/pcsx2/x86/iVUzerorec.cpp b/pcsx2/x86/iVUzerorec.cpp index 179dca1db8..87fc5d260f 100644 --- a/pcsx2/x86/iVUzerorec.cpp +++ b/pcsx2/x86/iVUzerorec.cpp @@ -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; } diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index 94d0a64eca..e8d81f1e73 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -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 ); diff --git a/pcsx2/x86/ix86-32/iR5900LoadStore.cpp b/pcsx2/x86/ix86-32/iR5900LoadStore.cpp index 9ee0ea9fd4..49a85cd32e 100644 --- a/pcsx2/x86/ix86-32/iR5900LoadStore.cpp +++ b/pcsx2/x86/ix86-32/iR5900LoadStore.cpp @@ -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) { diff --git a/pcsx2/x86/ix86/ix86.cpp b/pcsx2/x86/ix86/ix86.cpp index 66930d5bab..1b586e2976 100644 --- a/pcsx2/x86/ix86/ix86.cpp +++ b/pcsx2/x86/ix86/ix86.cpp @@ -17,3344 +17,25 @@ */ /* * ix86 core v0.6.2 - * Authors: linuzappz - * alexey silinov - * goldfinger - * zerofrog(@gmail.com) + * Authors: linuzappz + * alexey silinov + * goldfinger + * zerofrog(@gmail.com) + * cottonvibes(@gmail.com) */ +#pragma once #include "PrecompiledHeader.h" #include "System.h" - #include "ix86.h" -#define SWAP(x, y) { *(u32*)&y ^= *(u32*)&x; *(u32*)&x ^= *(u32*)&y; *(u32*)&y ^= *(u32*)&x; } - -u8 *x86Ptr; +u8 *x86Ptr[3]; // 3 rec instances (can be increased if needed) + // <0> = Main Instance, <1> = VU0 Instance, <2> = VU1 Instance u8 *j8Ptr[32]; u32 *j32Ptr[32]; -extern void SysPrintf(const char *fmt, ...); +PCSX2_ALIGNED16(unsigned int p[4]); +PCSX2_ALIGNED16(unsigned int p2[4]); +PCSX2_ALIGNED16(float f[4]); -__forceinline void WriteRmOffset(x86IntRegType to, s32 offset) -{ - if( (to&7) == ESP ) { - if( offset == 0 ) { - ModRM( 0, 0, 4 ); - SibSB( 0, ESP, 4 ); - } - else if( offset < 128 && offset >= -128 ) { - ModRM( 1, 0, 4 ); - SibSB( 0, ESP, 4 ); - write8(offset); - } - else { - ModRM( 2, 0, 4 ); - SibSB( 0, ESP, 4 ); - write32(offset); - } - } - else { - if( offset == 0 ) { - ModRM( 0, 0, to ); - } - else if( offset < 128 && offset >= -128 ) { - ModRM( 1, 0, to ); - write8(offset); - } - else { - ModRM( 2, 0, to ); - write32(offset); - } - } -} - -__forceinline void WriteRmOffsetFrom(x86IntRegType to, x86IntRegType from, int offset) -{ - if ((from&7) == ESP) { - if( offset == 0 ) { - ModRM( 0, to, 0x4 ); - SibSB( 0, 0x4, 0x4 ); - } - else if( offset < 128 && offset >= -128 ) { - ModRM( 1, to, 0x4 ); - SibSB( 0, 0x4, 0x4 ); - write8(offset); - } - else { - ModRM( 2, to, 0x4 ); - SibSB( 0, 0x4, 0x4 ); - write32(offset); - } - } - else { - if( offset == 0 ) { - ModRM( 0, to, from ); - } - else if( offset < 128 && offset >= -128 ) { - ModRM( 1, to, from ); - write8(offset); - } - else { - ModRM( 2, to, from ); - write32(offset); - } - } -} - -// This function is just for rec debugging purposes -__forceinline void CheckX86Ptr( void ) -{ -} - -__forceinline void write64( u64 val ) -{ -#ifdef _DEBUG - CheckX86Ptr( ); -#endif - - *(u64*)x86Ptr = val; - x86Ptr += 8; -} - -__forceinline void ModRM( s32 mod, s32 reg, s32 rm ) -{ - write8( ( mod << 6 ) | ( (reg & 7) << 3 ) | ( rm & 7 ) ); -} - -__forceinline void SibSB( s32 ss, s32 index, s32 base ) -{ - write8( ( ss << 6 ) | ( (index & 7) << 3 ) | ( base & 7 ) ); -} - -__forceinline void SET8R( int cc, int to ) -{ - RexB(0, to); - write8( 0x0F ); - write8( cc ); - write8( 0xC0 | ( to ) ); -} - -__forceinline u8* J8Rel( int cc, int to ) -{ - write8( cc ); - write8( to ); - return (u8*)(x86Ptr - 1); -} - -__forceinline u16* J16Rel( int cc, u32 to ) -{ - write16( 0x0F66 ); - write8( cc ); - write16( to ); - return (u16*)( x86Ptr - 2 ); -} - -__forceinline u32* J32Rel( int cc, u32 to ) -{ - write8( 0x0F ); - write8( cc ); - write32( to ); - return (u32*)( x86Ptr - 4 ); -} - -__forceinline void CMOV32RtoR( int cc, int to, int from ) -{ - RexRB(0,to, from); - write8( 0x0F ); - write8( cc ); - ModRM( 3, to, from ); -} - -__forceinline void CMOV32MtoR( int cc, int to, uptr from ) -{ - RexR(0, to); - write8( 0x0F ); - write8( cc ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -//////////////////////////////////////////////////// -__forceinline void x86SetPtr( u8* ptr ) -{ - x86Ptr = ptr; -} - -//////////////////////////////////////////////////// -__forceinline void x86Shutdown( void ) -{ -} - -//////////////////////////////////////////////////// -__forceinline void x86SetJ8( u8* j8 ) -{ - u32 jump = ( x86Ptr - j8 ) - 1; - - if ( jump > 0x7f ) { - Console::Error( "j8 greater than 0x7f!!" ); - assert(0); - } - *j8 = (u8)jump; -} - -__forceinline void x86SetJ8A( u8* j8 ) -{ - u32 jump = ( x86Ptr - j8 ) - 1; - - if ( jump > 0x7f ) { - Console::Error( "j8 greater than 0x7f!!" ); - assert(0); - } - - if( ((uptr)x86Ptr&0xf) > 4 ) { - - uptr newjump = jump + 16-((uptr)x86Ptr&0xf); - - if( newjump <= 0x7f ) { - jump = newjump; - while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90; - } - } - *j8 = (u8)jump; -} - -__forceinline void x86SetJ16( u16 *j16 ) -{ - // doesn't work - u32 jump = ( x86Ptr - (u8*)j16 ) - 2; - - if ( jump > 0x7fff ) { - Console::Error( "j16 greater than 0x7fff!!" ); - assert(0); - } - *j16 = (u16)jump; -} - -__forceinline void x86SetJ16A( u16 *j16 ) -{ - if( ((uptr)x86Ptr&0xf) > 4 ) { - while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90; - } - x86SetJ16(j16); -} - -//////////////////////////////////////////////////// -__forceinline void x86SetJ32( u32* j32 ) -{ - *j32 = ( x86Ptr - (u8*)j32 ) - 4; -} - -__forceinline void x86SetJ32A( u32* j32 ) -{ - while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90; - x86SetJ32(j32); -} - -//////////////////////////////////////////////////// -__forceinline void x86Align( int bytes ) -{ - // fordward align - x86Ptr = (u8*)( ( (uptr)x86Ptr + bytes - 1) & ~( bytes - 1 ) ); -} - -//////////////////////////////////////////////////// -// Generates executable code to align to the given alignment (could be useful for the second leg -// of if/else conditionals, which usually fall through a jump target label). -void x86AlignExecutable( int align ) -{ - uptr newx86 = ( (uptr)x86Ptr + align - 1) & ~( align - 1 ); - uptr bytes = ( newx86 - (uptr)x86Ptr ); - - switch( bytes ) - { - case 0: break; - - case 1: NOP(); break; - case 2: MOV32RtoR( ESI, ESI ); break; - case 3: write8(0x08D); write8(0x024); write8(0x024); break; - case 5: NOP(); // falls through to 4... - case 4: write8(0x08D); write8(0x064); write8(0x024); write8(0); break; - case 6: write8(0x08D); write8(0x0B6); write32(0); break; - case 8: NOP(); // falls through to 7... - case 7: write8(0x08D); write8(0x034); write8(0x035); write32(0); break; - - default: - { - // for larger alignments, just use a JMP... - u8* aligned_target = JMP8(0); - x86Ptr = (u8*)newx86; - x86SetJ8( aligned_target ); - } - } - - jASSUME( x86Ptr == (u8*)newx86 ); -} - -/********************/ -/* IX86 intructions */ -/********************/ - -__forceinline void STC( void ) -{ - write8( 0xF9 ); -} - -__forceinline void CLC( void ) -{ - write8( 0xF8 ); -} - -// NOP 1-byte -__forceinline void NOP( void ) -{ - write8(0x90); -} - - -//////////////////////////////////// -// mov instructions / -//////////////////////////////////// - -/* mov r64 to r64 */ -__forceinline void MOV64RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(1, from, to); - write8( 0x89 ); - ModRM( 3, from, to ); -} - -/* mov r64 to m64 */ -__forceinline void MOV64RtoM( uptr to, x86IntRegType from ) -{ - RexR(1, from); - write8( 0x89 ); - ModRM( 0, from, DISP32 ); - write32( (u32)MEMADDR(to, 4) ); -} - -/* mov m64 to r64 */ -__forceinline void MOV64MtoR( x86IntRegType to, uptr from ) -{ - RexR(1, to); - write8( 0x8B ); - ModRM( 0, to, DISP32 ); - write32( (u32)MEMADDR(from, 4) ); -} - -/* mov imm32 to m64 */ -__forceinline void MOV64I32toM(uptr to, u32 from ) -{ - Rex(1, 0, 0, 0); - write8( 0xC7 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -// mov imm64 to r64 -__forceinline void MOV64ItoR( x86IntRegType to, u64 from) -{ - RexB(1, to); - write8( 0xB8 | (to & 0x7) ); - write64( from ); -} - -/* mov imm32 to r64 */ -__forceinline void MOV64I32toR( x86IntRegType to, s32 from ) -{ - RexB(1, to); - write8( 0xC7 ); - ModRM( 0, 0, to ); - write32( from ); -} - -// mov imm64 to [r64+off] -__forceinline void MOV64ItoRmOffset( x86IntRegType to, u32 from, int offset) -{ - RexB(1,to); - write8( 0xC7 ); - WriteRmOffset(to, offset); - write32(from); -} - -// mov [r64+offset] to r64 -__forceinline void MOV64RmOffsettoR( x86IntRegType to, x86IntRegType from, int offset ) -{ - RexRB(1, to, from); - write8( 0x8B ); - WriteRmOffsetFrom(to, from, offset); -} - -/* mov [r64][r64*scale] to r64 */ -__forceinline void MOV64RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) { - RexRXB(1, to, from2, from); - write8( 0x8B ); - ModRM( 0, to, 0x4 ); - SibSB(scale, from2, from ); -} - -/* mov r64 to [r64+offset] */ -__forceinline void MOV64RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset ) -{ - RexRB(1,from,to); - write8( 0x89 ); - WriteRmOffsetFrom(from, to, offset); -} - -/* mov r64 to [r64][r64*scale] */ -__forceinline void MOV64RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) { - RexRXB(1, to, from2, from); - write8( 0x89 ); - ModRM( 0, to, 0x4 ); - SibSB(scale, from2, from ); -} - - -/* mov r32 to r32 */ -__forceinline void MOV32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0, from, to); - write8( 0x89 ); - ModRM( 3, from, to ); -} - -/* mov r32 to m32 */ -void MOV32RtoM( uptr to, x86IntRegType from ) -{ - RexR(0, from); - write8( 0x89 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* mov m32 to r32 */ -__forceinline void MOV32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0, to); - write8( 0x8B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* mov [r32] to r32 */ -__forceinline void MOV32RmtoR( x86IntRegType to, x86IntRegType from ) { - RexRB(0, to, from); - write8(0x8B); - WriteRmOffsetFrom(to, from, 0); -} - -__forceinline void MOV32RmtoROffset( x86IntRegType to, x86IntRegType from, int offset ) { - RexRB(0, to, from); - write8( 0x8B ); - WriteRmOffsetFrom(to, from, offset); -} - -/* mov [r32+r32*scale] to r32 */ -__forceinline void MOV32RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) { - RexRXB(0,to,from2,from); - write8( 0x8B ); - ModRM( 0, to, 0x4 ); - SibSB(scale, from2, from ); -} - -// mov r32 to [r32<> 3); - if ( to == EAX) { - write8( 0x05 ); - } else { - write8( 0x81 ); - ModRM( 3, 0, to ); - } - write32( from ); -} - -/* add m64 to r64 */ -__forceinline void ADD64MtoR( x86IntRegType to, uptr from ) -{ - Rex(1, to >> 3, 0, 0); - write8( 0x03 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* add r64 to r64 */ -__forceinline void ADD64RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(1, from, to); - write8( 0x01 ); - ModRM( 3, from, to ); -} - -/* add imm32 to EAX */ -void ADD32ItoEAX( u32 from ) -{ - write8( 0x05 ); - write32( from ); -} - -/* add imm32 to r32 */ -__forceinline void ADD32ItoR( x86IntRegType to, u32 from ) -{ - RexB(0, to); - if(from < 0x80) - { - write8( 0x83 ); - ModRM( 3, 0, to ); - write8( from ); - } - else - { - if ( to == EAX ) { - ADD32ItoEAX(from); - } - else { - write8( 0x81 ); - ModRM( 3, 0, to ); - write32( from ); - } - } -} - -/* add imm32 to m32 */ -__forceinline void ADD32ItoM( uptr to, u32 from ) -{ - /*if(from < 0x80) // crashes games in 64bit build; TODO: figure out why. - { - write8( 0x83 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 8) ); - write8( from ); - } - else*/ - { - write8( 0x81 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); - } -} - -// add imm32 to [r32+off] -__forceinline void ADD32ItoRmOffset( x86IntRegType to, u32 from, s32 offset) -{ - RexB(0,to); - if(from < 0x80) - { - write8( 0x83 ); - WriteRmOffset(to,offset); - write8(from); - } - else - { - write8( 0x81 ); - WriteRmOffset(to,offset); - write32(from); - } -} - -/* add r32 to r32 */ -__forceinline void ADD32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0, from, to); - write8( 0x01 ); - ModRM( 3, from, to ); -} - -/* add r32 to m32 */ -__forceinline void ADD32RtoM(uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x01 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* add m32 to r32 */ -__forceinline void ADD32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x03 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// add r16 to r16 -__forceinline void ADD16RtoR( x86IntRegType to , x86IntRegType from ) -{ - write8(0x66); - RexRB(0,to,from); - write8( 0x03 ); - ModRM( 3, to, from ); -} - -/* add imm16 to r16 */ -__forceinline void ADD16ItoR( x86IntRegType to, u16 from ) -{ - write8( 0x66 ); - RexB(0,to); - - if ( to == EAX) - { - write8( 0x05 ); - write16( from ); - } - else if(from < 0x80) - { - write8( 0x83 ); - ModRM( 3, 0, to ); - write8((u8)from ); - } - else - { - write8( 0x81 ); - ModRM( 3, 0, to ); - write16( from ); - } -} - -/* add imm16 to m16 */ -__forceinline void ADD16ItoM( uptr to, u16 from ) -{ - write8( 0x66 ); - if(from < 0x80) - { - write8( 0x83 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 6) ); - write8((u8)from ); - } - else - { - write8( 0x81 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); - } -} - -/* add r16 to m16 */ -__forceinline void ADD16RtoM(uptr to, x86IntRegType from ) -{ - write8( 0x66 ); - RexR(0,from); - write8( 0x01 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* add m16 to r16 */ -__forceinline void ADD16MtoR( x86IntRegType to, uptr from ) -{ - write8( 0x66 ); - RexR(0,to); - write8( 0x03 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// add m8 to r8 -__forceinline void ADD8MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x02 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* adc imm32 to r32 */ -__forceinline void ADC32ItoR( x86IntRegType to, u32 from ) -{ - RexB(0,to); - if ( to == EAX ) { - write8( 0x15 ); - } - else { - write8( 0x81 ); - ModRM( 3, 2, to ); - } - write32( from ); -} - -/* adc imm32 to m32 */ -__forceinline void ADC32ItoM( uptr to, u32 from ) -{ - write8( 0x81 ); - ModRM( 0, 2, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -/* adc r32 to r32 */ -__forceinline void ADC32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,from,to); - write8( 0x11 ); - ModRM( 3, from, to ); -} - -/* adc m32 to r32 */ -__forceinline void ADC32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x13 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// adc r32 to m32 -__forceinline void ADC32RtoM( uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x11 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* inc r32 */ -__forceinline void INC32R( x86IntRegType to ) -{ - write8( 0x40 + to ); -} - -/* inc m32 */ -__forceinline void INC32M( u32 to ) -{ - write8( 0xFF ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* inc r16 */ -__forceinline void INC16R( x86IntRegType to ) -{ - write8( 0x66 ); - write8( 0x40 + to ); -} - -/* inc m16 */ -__forceinline void INC16M( u32 to ) -{ - write8( 0x66 ); - write8( 0xFF ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 4) ); -} - - -/* sub imm32 to r64 */ -__forceinline void SUB64ItoR( x86IntRegType to, u32 from ) -{ - RexB(1, to); - if ( to == EAX ) { - write8( 0x2D ); - } - else { - write8( 0x81 ); - ModRM( 3, 5, to ); - } - write32( from ); -} - -/* sub r64 to r64 */ -__forceinline void SUB64RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(1, from, to); - write8( 0x29 ); - ModRM( 3, from, to ); -} - -/* sub m64 to r64 */ -__forceinline void SUB64MtoR( x86IntRegType to, uptr from ) -{ - RexR(1, to); - write8( 0x2B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* sub imm32 to r32 */ -__forceinline void SUB32ItoR( x86IntRegType to, u32 from ) -{ - RexB(0,to); - if ( to == EAX ) { - write8( 0x2D ); - } - else { - write8( 0x81 ); - ModRM( 3, 5, to ); - } - write32( from ); -} - -/* sub imm32 to m32 */ -__forceinline void SUB32ItoM( uptr to, u32 from ) -{ - write8( 0x81 ); - ModRM( 0, 5, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -/* sub r32 to r32 */ -__forceinline void SUB32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0, from, to); - write8( 0x29 ); - ModRM( 3, from, to ); -} - -/* sub m32 to r32 */ -__forceinline void SUB32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x2B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// sub r32 to m32 -__forceinline void SUB32RtoM( uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x29 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -// sub r16 to r16 -__forceinline void SUB16RtoR( x86IntRegType to, u16 from ) -{ - write8(0x66); - RexRB(0,to,from); - write8( 0x2b ); - ModRM( 3, to, from ); -} - -/* sub imm16 to r16 */ -__forceinline void SUB16ItoR( x86IntRegType to, u16 from ) { - write8( 0x66 ); - RexB(0,to); - if ( to == EAX ) { - write8( 0x2D ); - } else { - write8( 0x81 ); - ModRM( 3, 5, to ); - } - write16( from ); -} - -/* sub imm16 to m16 */ -__forceinline void SUB16ItoM( uptr to, u16 from ) { - write8( 0x66 ); - write8( 0x81 ); - ModRM( 0, 5, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); -} - -/* sub m16 to r16 */ -__forceinline void SUB16MtoR( x86IntRegType to, uptr from ) { - write8( 0x66 ); - RexR(0,to); - write8( 0x2B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* sbb r64 to r64 */ -__forceinline void SBB64RtoR( x86IntRegType to, x86IntRegType from ) { - RexRB(1, from,to); - write8( 0x19 ); - ModRM( 3, from, to ); -} - -/* sbb imm32 to r32 */ -__forceinline void SBB32ItoR( x86IntRegType to, u32 from ) { - RexB(0,to); - if ( to == EAX ) { - write8( 0x1D ); - } - else { - write8( 0x81 ); - ModRM( 3, 3, to ); - } - write32( from ); -} - -/* sbb imm32 to m32 */ -__forceinline void SBB32ItoM( uptr to, u32 from ) { - write8( 0x81 ); - ModRM( 0, 3, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -/* sbb r32 to r32 */ -__forceinline void SBB32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,from,to); - write8( 0x19 ); - ModRM( 3, from, to ); -} - -/* sbb m32 to r32 */ -__forceinline void SBB32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x1B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* sbb r32 to m32 */ -__forceinline void SBB32RtoM( uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x19 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* dec r32 */ -__forceinline void DEC32R( x86IntRegType to ) -{ - write8( 0x48 + to ); -} - -/* dec m32 */ -__forceinline void DEC32M( u32 to ) -{ - write8( 0xFF ); - ModRM( 0, 1, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* dec r16 */ -__forceinline void DEC16R( x86IntRegType to ) -{ - write8( 0x66 ); - write8( 0x48 + to ); -} - -/* dec m16 */ -__forceinline void DEC16M( u32 to ) -{ - write8( 0x66 ); - write8( 0xFF ); - ModRM( 0, 1, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* mul eax by r32 to edx:eax */ -__forceinline void MUL32R( x86IntRegType from ) -{ - RexB(0,from); - write8( 0xF7 ); - ModRM( 3, 4, from ); -} - -/* imul eax by r32 to edx:eax */ -__forceinline void IMUL32R( x86IntRegType from ) -{ - RexB(0,from); - write8( 0xF7 ); - ModRM( 3, 5, from ); -} - -/* mul eax by m32 to edx:eax */ -__forceinline void MUL32M( u32 from ) -{ - write8( 0xF7 ); - ModRM( 0, 4, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* imul eax by m32 to edx:eax */ -__forceinline void IMUL32M( u32 from ) -{ - write8( 0xF7 ); - ModRM( 0, 5, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* imul r32 by r32 to r32 */ -__forceinline void IMUL32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,to,from); - write16( 0xAF0F ); - ModRM( 3, to, from ); -} - -/* div eax by r32 to edx:eax */ -__forceinline void DIV32R( x86IntRegType from ) -{ - RexB(0,from); - write8( 0xF7 ); - ModRM( 3, 6, from ); -} - -/* idiv eax by r32 to edx:eax */ -__forceinline void IDIV32R( x86IntRegType from ) -{ - RexB(0,from); - write8( 0xF7 ); - ModRM( 3, 7, from ); -} - -/* div eax by m32 to edx:eax */ -__forceinline void DIV32M( u32 from ) -{ - write8( 0xF7 ); - ModRM( 0, 6, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* idiv eax by m32 to edx:eax */ -__forceinline void IDIV32M( u32 from ) -{ - write8( 0xF7 ); - ModRM( 0, 7, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -//////////////////////////////////// -// shifting instructions / -//////////////////////////////////// - -/* shl imm8 to r64 */ -__forceinline void SHL64ItoR( x86IntRegType to, u8 from ) -{ - RexB(1, to); - if ( from == 1 ) - { - write8( 0xD1 ); - ModRM( 3, 4, to ); - return; - } - write8( 0xC1 ); - ModRM( 3, 4, to ); - write8( from ); -} - -/* shl cl to r64 */ -__forceinline void SHL64CLtoR( x86IntRegType to ) -{ - RexB(1, to); - write8( 0xD3 ); - ModRM( 3, 4, to ); -} - -/* shr imm8 to r64 */ -__forceinline void SHR64ItoR( x86IntRegType to, u8 from ) -{ - RexB(1,to); - if ( from == 1 ) { - write8( 0xD1 ); - ModRM( 3, 5, to ); - return; - } - write8( 0xC1 ); - ModRM( 3, 5, to ); - write8( from ); -} - -/* shr cl to r64 */ -__forceinline void SHR64CLtoR( x86IntRegType to ) -{ - RexB(1, to); - write8( 0xD3 ); - ModRM( 3, 5, to ); -} - -/* shl imm8 to r32 */ -__forceinline void SHL32ItoR( x86IntRegType to, u8 from ) -{ - RexB(0, to); - if ( from == 1 ) - { - write8( 0xD1 ); - write8( 0xE0 | (to & 0x7) ); - return; - } - write8( 0xC1 ); - ModRM( 3, 4, to ); - write8( from ); -} - -/* shl imm8 to m32 */ -__forceinline void SHL32ItoM( uptr to, u8 from ) -{ - if ( from == 1 ) - { - write8( 0xD1 ); - ModRM( 0, 4, DISP32 ); - write32( MEMADDR(to, 4) ); - } - else - { - write8( 0xC1 ); - ModRM( 0, 4, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); - } -} - -/* shl cl to r32 */ -__forceinline void SHL32CLtoR( x86IntRegType to ) -{ - RexB(0,to); - write8( 0xD3 ); - ModRM( 3, 4, to ); -} - -// shl imm8 to r16 -__forceinline void SHL16ItoR( x86IntRegType to, u8 from ) -{ - write8(0x66); - RexB(0,to); - if ( from == 1 ) - { - write8( 0xD1 ); - write8( 0xE0 | (to & 0x7) ); - return; - } - write8( 0xC1 ); - ModRM( 3, 4, to ); - write8( from ); -} - -// shl imm8 to r8 -__forceinline void SHL8ItoR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - if ( from == 1 ) - { - write8( 0xD0 ); - write8( 0xE0 | (to & 0x7) ); - return; - } - write8( 0xC0 ); - ModRM( 3, 4, to ); - write8( from ); -} - -/* shr imm8 to r32 */ -__forceinline void SHR32ItoR( x86IntRegType to, u8 from ) { - RexB(0,to); - if ( from == 1 ) - { - write8( 0xD1 ); - write8( 0xE8 | (to & 0x7) ); - } - else - { - write8( 0xC1 ); - ModRM( 3, 5, to ); - write8( from ); - } -} - -/* shr imm8 to m32 */ -__forceinline void SHR32ItoM( uptr to, u8 from ) -{ - if ( from == 1 ) - { - write8( 0xD1 ); - ModRM( 0, 5, DISP32 ); - write32( MEMADDR(to, 4) ); - } - else - { - write8( 0xC1 ); - ModRM( 0, 5, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); - } -} - -/* shr cl to r32 */ -__forceinline void SHR32CLtoR( x86IntRegType to ) -{ - RexB(0,to); - write8( 0xD3 ); - ModRM( 3, 5, to ); -} - -// shr imm8 to r16 -__forceinline void SHR16ItoR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - if ( from == 1 ) - { - write8( 0xD1 ); - ModRM( 3, 5, to ); - } - else - { - write8( 0xC1 ); - ModRM( 3, 5, to ); - write8( from ); - } -} - -// shr imm8 to r8 -__forceinline void SHR8ItoR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - if ( from == 1 ) - { - write8( 0xD0 ); - write8( 0xE8 | (to & 0x7) ); - } - else - { - write8( 0xC0 ); - ModRM( 3, 5, to ); - write8( from ); - } -} - -/* sar imm8 to r64 */ -__forceinline void SAR64ItoR( x86IntRegType to, u8 from ) -{ - RexB(1,to); - if ( from == 1 ) - { - write8( 0xD1 ); - ModRM( 3, 7, to ); - return; - } - write8( 0xC1 ); - ModRM( 3, 7, to ); - write8( from ); -} - -/* sar cl to r64 */ -__forceinline void SAR64CLtoR( x86IntRegType to ) -{ - RexB(1, to); - write8( 0xD3 ); - ModRM( 3, 7, to ); -} - -/* sar imm8 to r32 */ -__forceinline void SAR32ItoR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - if ( from == 1 ) - { - write8( 0xD1 ); - ModRM( 3, 7, to ); - return; - } - write8( 0xC1 ); - ModRM( 3, 7, to ); - write8( from ); -} - -/* sar imm8 to m32 */ -__forceinline void SAR32ItoM( uptr to, u8 from ) -{ - write8( 0xC1 ); - ModRM( 0, 7, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); -} - -/* sar cl to r32 */ -__forceinline void SAR32CLtoR( x86IntRegType to ) -{ - RexB(0,to); - write8( 0xD3 ); - ModRM( 3, 7, to ); -} - -// sar imm8 to r16 -__forceinline void SAR16ItoR( x86IntRegType to, u8 from ) -{ - write8(0x66); - RexB(0,to); - if ( from == 1 ) - { - write8( 0xD1 ); - ModRM( 3, 7, to ); - return; - } - write8( 0xC1 ); - ModRM( 3, 7, to ); - write8( from ); -} - -__forceinline void ROR32ItoR( x86IntRegType to,u8 from ) -{ - RexB(0,to); - if ( from == 1 ) { - write8( 0xd1 ); - write8( 0xc8 | to ); - } - else - { - write8( 0xc1 ); - write8( 0xc8 | to ); - write8( from ); - } -} - -__forceinline void RCR32ItoR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - if ( from == 1 ) { - write8( 0xd1 ); - ModRM(3, 3, to); - } - else - { - write8( 0xc1 ); - ModRM(3, 3, to); - write8( from ); - } -} - -__forceinline void RCR32ItoM( uptr to, u8 from ) -{ - RexB(0,to); - if ( from == 1 ) { - write8( 0xd1 ); - ModRM( 0, 3, DISP32 ); - write32( MEMADDR(to, 8) ); - } - else - { - write8( 0xc1 ); - ModRM( 0, 3, DISP32 ); - write32( MEMADDR(to, 8) ); - write8( from ); - } -} - -// shld imm8 to r32 -__forceinline void SHLD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) -{ - RexRB(0,from,to); - write8( 0x0F ); - write8( 0xA4 ); - ModRM( 3, from, to ); - write8( shift ); -} - -// shrd imm8 to r32 -__forceinline void SHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) -{ - RexRB(0,from,to); - write8( 0x0F ); - write8( 0xAC ); - ModRM( 3, from, to ); - write8( shift ); -} - -//////////////////////////////////// -// logical instructions / -//////////////////////////////////// - -/* or imm32 to r32 */ -__forceinline void OR64ItoR( x86IntRegType to, u32 from ) -{ - RexB(1, to); - if ( to == EAX ) { - write8( 0x0D ); - } else { - write8( 0x81 ); - ModRM( 3, 1, to ); - } - write32( from ); -} - -/* or m64 to r64 */ -__forceinline void OR64MtoR( x86IntRegType to, uptr from ) -{ - RexR(1, to); - write8( 0x0B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* or r64 to r64 */ -__forceinline void OR64RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(1, from, to); - write8( 0x09 ); - ModRM( 3, from, to ); -} - -// or r32 to m64 -__forceinline void OR64RtoM(uptr to, x86IntRegType from ) -{ - RexR(1,from); - write8( 0x09 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* or imm32 to r32 */ -__forceinline void OR32ItoR( x86IntRegType to, u32 from ) -{ - RexB(0,to); - if ( to == EAX ) { - write8( 0x0D ); - } - else { - write8( 0x81 ); - ModRM( 3, 1, to ); - } - write32( from ); -} - -/* or imm32 to m32 */ -__forceinline void OR32ItoM(uptr to, u32 from ) -{ - write8( 0x81 ); - ModRM( 0, 1, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -/* or r32 to r32 */ -__forceinline void OR32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,from,to); - write8( 0x09 ); - ModRM( 3, from, to ); -} - -/* or r32 to m32 */ -__forceinline void OR32RtoM(uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x09 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* or m32 to r32 */ -__forceinline void OR32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x0B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// or r16 to r16 -__forceinline void OR16RtoR( x86IntRegType to, x86IntRegType from ) -{ - write8(0x66); - RexRB(0,from,to); - write8( 0x09 ); - ModRM( 3, from, to ); -} - -// or imm16 to r16 -__forceinline void OR16ItoR( x86IntRegType to, u16 from ) -{ - write8(0x66); - RexB(0,to); - if ( to == EAX ) { - write8( 0x0D ); - } - else { - write8( 0x81 ); - ModRM( 3, 1, to ); - } - write16( from ); -} - -// or imm16 to m316 -__forceinline void OR16ItoM( uptr to, u16 from ) -{ - write8(0x66); - write8( 0x81 ); - ModRM( 0, 1, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); -} - -/* or m16 to r16 */ -__forceinline void OR16MtoR( x86IntRegType to, uptr from ) -{ - write8(0x66); - RexR(0,to); - write8( 0x0B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// or r16 to m16 -__forceinline void OR16RtoM( uptr to, x86IntRegType from ) -{ - write8(0x66); - RexR(0,from); - write8( 0x09 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -// or r8 to r8 -__forceinline void OR8RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,from,to); - write8( 0x08 ); - ModRM( 3, from, to ); -} - -// or r8 to m8 -__forceinline void OR8RtoM( uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x08 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -// or imm8 to m8 -__forceinline void OR8ItoM( uptr to, u8 from ) -{ - write8( 0x80 ); - ModRM( 0, 1, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); -} - -// or m8 to r8 -__forceinline void OR8MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x0A ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* xor imm32 to r64 */ -__forceinline void XOR64ItoR( x86IntRegType to, u32 from ) -{ - RexB(1,to); - if ( to == EAX ) { - write8( 0x35 ); - } else { - write8( 0x81 ); - ModRM( 3, 6, to ); - } - write32( from ); -} - -/* xor r64 to r64 */ -__forceinline void XOR64RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(1, from, to); - write8( 0x31 ); - ModRM( 3, from, to ); -} - -/* xor m64 to r64 */ -__forceinline void XOR64MtoR( x86IntRegType to, uptr from ) -{ - RexR(1, to); - write8( 0x33 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* xor r64 to m64 */ -__forceinline void XOR64RtoM( uptr to, x86IntRegType from ) -{ - RexR(1,from); - write8( 0x31 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* xor imm32 to r32 */ -__forceinline void XOR32ItoR( x86IntRegType to, u32 from ) -{ - RexB(0,to); - if ( to == EAX ) { - write8( 0x35 ); - } - else { - write8( 0x81 ); - ModRM( 3, 6, to ); - } - write32( from ); -} - -/* xor imm32 to m32 */ -__forceinline void XOR32ItoM( uptr to, u32 from ) -{ - write8( 0x81 ); - ModRM( 0, 6, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -/* xor r32 to r32 */ -__forceinline void XOR32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,from,to); - write8( 0x31 ); - ModRM( 3, from, to ); -} - -/* xor r16 to r16 */ -__forceinline void XOR16RtoR( x86IntRegType to, x86IntRegType from ) -{ - write8( 0x66 ); - RexRB(0,from,to); - write8( 0x31 ); - ModRM( 3, from, to ); -} - -/* xor r32 to m32 */ -__forceinline void XOR32RtoM( uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x31 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* xor m32 to r32 */ -__forceinline void XOR32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x33 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// xor imm16 to r16 -__forceinline void XOR16ItoR( x86IntRegType to, u16 from ) -{ - write8(0x66); - RexB(0,to); - if ( to == EAX ) { - write8( 0x35 ); - } - else { - write8( 0x81 ); - ModRM( 3, 6, to ); - } - write16( from ); -} - -// xor r16 to m16 -__forceinline void XOR16RtoM( uptr to, x86IntRegType from ) -{ - write8(0x66); - RexR(0,from); - write8( 0x31 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* and imm32 to r64 */ -__forceinline void AND64I32toR( x86IntRegType to, u32 from ) -{ - RexB(1, to); - if ( to == EAX ) { - write8( 0x25 ); - } else { - write8( 0x81 ); - ModRM( 3, 0x4, to ); - } - write32( from ); -} - -/* and m64 to r64 */ -__forceinline void AND64MtoR( x86IntRegType to, uptr from ) -{ - RexR(1, to); - write8( 0x23 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* and r64 to m64 */ -__forceinline void AND64RtoM( uptr to, x86IntRegType from ) -{ - RexR(1, from); - write8( 0x21 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* and r64 to r64 */ -__forceinline void AND64RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(1, from, to); - write8( 0x21 ); - ModRM( 3, from, to ); -} - -/* and imm32 to m64 */ -__forceinline void AND64I32toM( uptr to, u32 from ) -{ - Rex(1,0,0,0); - write8( 0x81 ); - ModRM( 0, 0x4, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -/* and imm32 to r32 */ -__forceinline void AND32ItoR( x86IntRegType to, u32 from ) -{ - RexB(0,to); - if(from < 0x80) - { - AND32I8toR(to, (u8)from); - } - else - { - if ( to == EAX ) { - write8( 0x25 ); - } else { - write8( 0x81 ); - ModRM( 3, 0x4, to ); - } - write32( from ); - } -} - -/* and sign ext imm8 to r32 */ -__forceinline void AND32I8toR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - write8( 0x83 ); - ModRM( 3, 0x4, to ); - write8( from ); -} - -/* and imm32 to m32 */ -__forceinline void AND32ItoM( uptr to, u32 from ) -{ - if(from < 0x80) - { - AND32I8toM(to, (u8)from); - } - else - { - write8( 0x81 ); - ModRM( 0, 0x4, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); - } -} - - -/* and sign ext imm8 to m32 */ -__forceinline void AND32I8toM( uptr to, u8 from ) -{ - write8( 0x83 ); - ModRM( 0, 0x4, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); -} - -/* and r32 to r32 */ -__forceinline void AND32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,from,to); - write8( 0x21 ); - ModRM( 3, from, to ); -} - -/* and r32 to m32 */ -__forceinline void AND32RtoM( uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x21 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* and m32 to r32 */ -__forceinline void AND32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x23 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// and r16 to r16 -__forceinline void AND16RtoR( x86IntRegType to, x86IntRegType from ) -{ - write8(0x66); - RexRB(0,to,from); - write8( 0x23 ); - ModRM( 3, to, from ); -} - -/* and imm16 to r16 */ -__forceinline void AND16ItoR( x86IntRegType to, u16 from ) -{ - write8(0x66); - RexB(0,to); - - if ( to == EAX ) { - write8( 0x25 ); - write16( from ); - } - else if ( from < 0x80 ) { - write8( 0x83 ); - ModRM( 3, 0x4, to ); - write8((u8)from ); - } - else { - write8( 0x81 ); - ModRM( 3, 0x4, to ); - write16( from ); - } -} - -/* and imm16 to m16 */ -__forceinline void AND16ItoM( uptr to, u16 from ) -{ - write8(0x66); - if ( from < 0x80 ) { - write8( 0x83 ); - ModRM( 0, 0x4, DISP32 ); - write32( MEMADDR(to, 6) ); - write8((u8)from ); - } - else - { - write8( 0x81 ); - ModRM( 0, 0x4, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); - - } -} - -/* and r16 to m16 */ -__forceinline void AND16RtoM( uptr to, x86IntRegType from ) -{ - write8( 0x66 ); - RexR(0,from); - write8( 0x21 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* and m16 to r16 */ -__forceinline void AND16MtoR( x86IntRegType to, uptr from ) -{ - write8( 0x66 ); - RexR(0,to); - write8( 0x23 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4)); -} - -/* and imm8 to r8 */ -__forceinline void AND8ItoR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - if ( to == EAX ) { - write8( 0x24 ); - } else { - write8( 0x80 ); - ModRM( 3, 0x4, to ); - } - write8( from ); -} - -/* and imm8 to m8 */ -__forceinline void AND8ItoM( uptr to, u8 from ) -{ - write8( 0x80 ); - ModRM( 0, 0x4, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); -} - -// and r8 to r8 -__forceinline void AND8RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,to,from); - write8( 0x22 ); - ModRM( 3, to, from ); -} - -/* and r8 to m8 */ -__forceinline void AND8RtoM( uptr to, x86IntRegType from ) -{ - RexR(0,from); - write8( 0x20 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* and m8 to r8 */ -__forceinline void AND8MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x22 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4)); -} - -/* not r64 */ -__forceinline void NOT64R( x86IntRegType from ) -{ - RexB(1, from); - write8( 0xF7 ); - ModRM( 3, 2, from ); -} - -/* not r32 */ -__forceinline void NOT32R( x86IntRegType from ) -{ - RexB(0,from); - write8( 0xF7 ); - ModRM( 3, 2, from ); -} - -// not m32 -__forceinline void NOT32M( u32 from ) -{ - write8( 0xF7 ); - ModRM( 0, 2, DISP32 ); - write32( MEMADDR(from, 4)); -} - -/* neg r64 */ -__forceinline void NEG64R( x86IntRegType from ) -{ - RexB(1, from); - write8( 0xF7 ); - ModRM( 3, 3, from ); -} - -/* neg r32 */ -__forceinline void NEG32R( x86IntRegType from ) -{ - RexB(0,from); - write8( 0xF7 ); - ModRM( 3, 3, from ); -} - -__forceinline void NEG32M( u32 from ) -{ - write8( 0xF7 ); - ModRM( 0, 3, DISP32 ); - write32( MEMADDR(from, 4)); -} - -/* neg r16 */ -__forceinline void NEG16R( x86IntRegType from ) -{ - write8( 0x66 ); - RexB(0,from); - write8( 0xF7 ); - ModRM( 3, 3, from ); -} - -//////////////////////////////////// -// jump instructions / -//////////////////////////////////// - -__forceinline u8* JMP( uptr to ) { - uptr jump = ( x86Ptr - (u8*)to ) - 1; - - if ( jump > 0x7f ) { - assert( to <= 0xffffffff ); - return (u8*)JMP32( to ); - } - else { - return (u8*)JMP8( to ); - } -} - -/* jmp rel8 */ -__forceinline u8* JMP8( u8 to ) -{ - write8( 0xEB ); - write8( to ); - return x86Ptr - 1; -} - -/* jmp rel32 */ -__forceinline u32* JMP32( uptr to ) -{ - assert( (sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff ); - write8( 0xE9 ); - write32( to ); - return (u32*)(x86Ptr - 4 ); -} - -/* jmp r32/r64 */ -__forceinline void JMPR( x86IntRegType to ) -{ - RexB(0, to); - write8( 0xFF ); - ModRM( 3, 4, to ); -} - -// jmp m32 -__forceinline void JMP32M( uptr to ) -{ - write8( 0xFF ); - ModRM( 0, 4, DISP32 ); - write32( MEMADDR(to, 4)); -} - -/* jp rel8 */ -__forceinline u8* JP8( u8 to ) { - return J8Rel( 0x7A, to ); -} - -/* jnp rel8 */ -__forceinline u8* JNP8( u8 to ) { - return J8Rel( 0x7B, to ); -} - -/* je rel8 */ -__forceinline u8* JE8( u8 to ) { - return J8Rel( 0x74, to ); -} - -/* jz rel8 */ -__forceinline u8* JZ8( u8 to ) -{ - return J8Rel( 0x74, to ); -} - -/* js rel8 */ -__forceinline u8* JS8( u8 to ) -{ - return J8Rel( 0x78, to ); -} - -/* jns rel8 */ -__forceinline u8* JNS8( u8 to ) -{ - return J8Rel( 0x79, to ); -} - -/* jg rel8 */ -__forceinline u8* JG8( u8 to ) -{ - return J8Rel( 0x7F, to ); -} - -/* jge rel8 */ -__forceinline u8* JGE8( u8 to ) -{ - return J8Rel( 0x7D, to ); -} - -/* jl rel8 */ -__forceinline u8* JL8( u8 to ) -{ - return J8Rel( 0x7C, to ); -} - -/* ja rel8 */ -__forceinline u8* JA8( u8 to ) -{ - return J8Rel( 0x77, to ); -} - -__forceinline u8* JAE8( u8 to ) -{ - return J8Rel( 0x73, to ); -} - -/* jb rel8 */ -__forceinline u8* JB8( u8 to ) -{ - return J8Rel( 0x72, to ); -} - -/* jbe rel8 */ -__forceinline u8* JBE8( u8 to ) -{ - return J8Rel( 0x76, to ); -} - -/* jle rel8 */ -__forceinline u8* JLE8( u8 to ) -{ - return J8Rel( 0x7E, to ); -} - -/* jne rel8 */ -__forceinline u8* JNE8( u8 to ) -{ - return J8Rel( 0x75, to ); -} - -/* jnz rel8 */ -__forceinline u8* JNZ8( u8 to ) -{ - return J8Rel( 0x75, to ); -} - -/* jng rel8 */ -__forceinline u8* JNG8( u8 to ) -{ - return J8Rel( 0x7E, to ); -} - -/* jnge rel8 */ -__forceinline u8* JNGE8( u8 to ) -{ - return J8Rel( 0x7C, to ); -} - -/* jnl rel8 */ -__forceinline u8* JNL8( u8 to ) -{ - return J8Rel( 0x7D, to ); -} - -/* jnle rel8 */ -__forceinline u8* JNLE8( u8 to ) -{ - return J8Rel( 0x7F, to ); -} - -/* jo rel8 */ -__forceinline u8* JO8( u8 to ) -{ - return J8Rel( 0x70, to ); -} - -/* jno rel8 */ -__forceinline u8* JNO8( u8 to ) -{ - return J8Rel( 0x71, to ); -} -/* Untested and slower, use 32bit versions instead -// ja rel16 -__forceinline u16* JA16( u16 to ) -{ - return J16Rel( 0x87, to ); -} - -// jb rel16 -__forceinline u16* JB16( u16 to ) -{ - return J16Rel( 0x82, to ); -} - -// je rel16 -__forceinline u16* JE16( u16 to ) -{ - return J16Rel( 0x84, to ); -} - -// jz rel16 -__forceinline u16* JZ16( u16 to ) -{ - return J16Rel( 0x84, to ); -} -*/ -// jb rel32 -__forceinline u32* JB32( u32 to ) -{ - return J32Rel( 0x82, to ); -} - -/* je rel32 */ -__forceinline u32* JE32( u32 to ) -{ - return J32Rel( 0x84, to ); -} - -/* jz rel32 */ -__forceinline u32* JZ32( u32 to ) -{ - return J32Rel( 0x84, to ); -} - -/* js rel32 */ -__forceinline u32* JS32( u32 to ) -{ - return J32Rel( 0x88, to ); -} - -/* jns rel32 */ -__forceinline u32* JNS32( u32 to ) -{ - return J32Rel( 0x89, to ); -} - -/* jg rel32 */ -__forceinline u32* JG32( u32 to ) -{ - return J32Rel( 0x8F, to ); -} - -/* jge rel32 */ -__forceinline u32* JGE32( u32 to ) -{ - return J32Rel( 0x8D, to ); -} - -/* jl rel32 */ -__forceinline u32* JL32( u32 to ) -{ - return J32Rel( 0x8C, to ); -} - -/* jle rel32 */ -__forceinline u32* JLE32( u32 to ) -{ - return J32Rel( 0x8E, to ); -} - -/* ja rel32 */ -__forceinline u32* JA32( u32 to ) -{ - return J32Rel( 0x87, to ); -} - -/* jae rel32 */ -__forceinline u32* JAE32( u32 to ) -{ - return J32Rel( 0x83, to ); -} - -/* jne rel32 */ -__forceinline u32* JNE32( u32 to ) -{ - return J32Rel( 0x85, to ); -} - -/* jnz rel32 */ -__forceinline u32* JNZ32( u32 to ) -{ - return J32Rel( 0x85, to ); -} - -/* jng rel32 */ -__forceinline u32* JNG32( u32 to ) -{ - return J32Rel( 0x8E, to ); -} - -/* jnge rel32 */ -__forceinline u32* JNGE32( u32 to ) -{ - return J32Rel( 0x8C, to ); -} - -/* jnl rel32 */ -__forceinline u32* JNL32( u32 to ) -{ - return J32Rel( 0x8D, to ); -} - -/* jnle rel32 */ -__forceinline u32* JNLE32( u32 to ) -{ - return J32Rel( 0x8F, to ); -} - -/* jo rel32 */ -__forceinline u32* JO32( u32 to ) -{ - return J32Rel( 0x80, to ); -} - -/* jno rel32 */ -__forceinline u32* JNO32( u32 to ) -{ - return J32Rel( 0x81, to ); -} - - - -/* call func */ -__forceinline void CALLFunc( uptr func ) -{ - func -= ( (uptr)x86Ptr + 5 ); - assert( (sptr)func <= 0x7fffffff && (sptr)func >= -0x7fffffff ); - CALL32(func); -} - -/* call rel32 */ -__forceinline void CALL32( u32 to ) -{ - write8( 0xE8 ); - write32( to ); -} - -/* call r32 */ -__forceinline void CALL32R( x86IntRegType to ) -{ - write8( 0xFF ); - ModRM( 3, 2, to ); -} - -/* call r64 */ -__forceinline void CALL64R( x86IntRegType to ) -{ - RexB(0, to); - write8( 0xFF ); - ModRM( 3, 2, to ); -} - -/* call m32 */ -__forceinline void CALL32M( u32 to ) -{ - write8( 0xFF ); - ModRM( 0, 2, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -//////////////////////////////////// -// misc instructions / -//////////////////////////////////// - -/* cmp imm32 to r64 */ -__forceinline void CMP64I32toR( x86IntRegType to, u32 from ) -{ - RexB(1, to); - if ( to == EAX ) { - write8( 0x3D ); - } - else { - write8( 0x81 ); - ModRM( 3, 7, to ); - } - write32( from ); -} - -/* cmp m64 to r64 */ -__forceinline void CMP64MtoR( x86IntRegType to, uptr from ) -{ - RexR(1, to); - write8( 0x3B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// cmp r64 to r64 -__forceinline void CMP64RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(1,from,to); - write8( 0x39 ); - ModRM( 3, from, to ); -} - -/* cmp imm32 to r32 */ -__forceinline void CMP32ItoR( x86IntRegType to, u32 from ) -{ - RexB(0,to); - if ( to == EAX ) { - write8( 0x3D ); - } - else { - write8( 0x81 ); - ModRM( 3, 7, to ); - } - write32( from ); -} - -/* cmp imm32 to m32 */ -__forceinline void CMP32ItoM( uptr to, u32 from ) -{ - write8( 0x81 ); - ModRM( 0, 7, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -/* cmp r32 to r32 */ -__forceinline void CMP32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,from,to); - write8( 0x39 ); - ModRM( 3, from, to ); -} - -/* cmp m32 to r32 */ -__forceinline void CMP32MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x3B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// cmp imm8 to [r32] -__forceinline void CMP32I8toRm( x86IntRegType to, u8 from) -{ - RexB(0,to); - write8( 0x83 ); - ModRM( 0, 7, to ); - write8(from); -} - -// cmp imm32 to [r32+off] -__forceinline void CMP32I8toRmOffset8( x86IntRegType to, u8 from, u8 off) -{ - RexB(0,to); - write8( 0x83 ); - ModRM( 1, 7, to ); - write8(off); - write8(from); -} - -// cmp imm8 to [r32] -__forceinline void CMP32I8toM( uptr to, u8 from) -{ - write8( 0x83 ); - ModRM( 0, 7, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); -} - -/* cmp imm16 to r16 */ -__forceinline void CMP16ItoR( x86IntRegType to, u16 from ) -{ - write8( 0x66 ); - RexB(0,to); - if ( to == EAX ) - { - write8( 0x3D ); - } - else - { - write8( 0x81 ); - ModRM( 3, 7, to ); - } - write16( from ); -} - -/* cmp imm16 to m16 */ -__forceinline void CMP16ItoM( uptr to, u16 from ) -{ - write8( 0x66 ); - write8( 0x81 ); - ModRM( 0, 7, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); -} - -/* cmp r16 to r16 */ -__forceinline void CMP16RtoR( x86IntRegType to, x86IntRegType from ) -{ - write8( 0x66 ); - RexRB(0,from,to); - write8( 0x39 ); - ModRM( 3, from, to ); -} - -/* cmp m16 to r16 */ -__forceinline void CMP16MtoR( x86IntRegType to, uptr from ) -{ - write8( 0x66 ); - RexR(0,to); - write8( 0x3B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// cmp imm8 to r8 -__forceinline void CMP8ItoR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - if ( to == EAX ) - { - write8( 0x3C ); - } - else - { - write8( 0x80 ); - ModRM( 3, 7, to ); - } - write8( from ); -} - -// cmp m8 to r8 -__forceinline void CMP8MtoR( x86IntRegType to, uptr from ) -{ - RexR(0,to); - write8( 0x3A ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* test imm32 to r32 */ -__forceinline void TEST32ItoR( x86IntRegType to, u32 from ) -{ - RexB(0,to); - if ( to == EAX ) - { - write8( 0xA9 ); - } - else - { - write8( 0xF7 ); - ModRM( 3, 0, to ); - } - write32( from ); -} - -__forceinline void TEST32ItoM( uptr to, u32 from ) -{ - write8( 0xF7 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 8) ); - write32( from ); -} - -/* test r32 to r32 */ -__forceinline void TEST32RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0,from,to); - write8( 0x85 ); - ModRM( 3, from, to ); -} - -// test imm32 to [r32] -__forceinline void TEST32ItoRm( x86IntRegType to, u32 from ) -{ - RexB(0,to); - write8( 0xF7 ); - ModRM( 0, 0, to ); - write32(from); -} - -// test imm16 to r16 -__forceinline void TEST16ItoR( x86IntRegType to, u16 from ) -{ - write8(0x66); - RexB(0,to); - if ( to == EAX ) - { - write8( 0xA9 ); - } - else - { - write8( 0xF7 ); - ModRM( 3, 0, to ); - } - write16( from ); -} - -// test r16 to r16 -__forceinline void TEST16RtoR( x86IntRegType to, x86IntRegType from ) -{ - write8(0x66); - RexRB(0,from,to); - write8( 0x85 ); - ModRM( 3, from, to ); -} - -// test r8 to r8 -__forceinline void TEST8RtoR( x86IntRegType to, x86IntRegType from ) -{ - RexRB(0, from, to); - write8( 0x84 ); - ModRM( 3, from, to ); -} - - -// test imm8 to r8 -__forceinline void TEST8ItoR( x86IntRegType to, u8 from ) -{ - RexB(0,to); - if ( to == EAX ) - { - write8( 0xA8 ); - } - else - { - write8( 0xF6 ); - ModRM( 3, 0, to ); - } - write8( from ); -} - -// test imm8 to r8 -__forceinline void TEST8ItoM( uptr to, u8 from ) -{ - write8( 0xF6 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); -} - -/* sets r8 */ -__forceinline void SETS8R( x86IntRegType to ) -{ - SET8R( 0x98, to ); -} - -/* setl r8 */ -__forceinline void SETL8R( x86IntRegType to ) -{ - SET8R( 0x9C, to ); -} - -// setge r8 -__forceinline void SETGE8R( x86IntRegType to ) { SET8R(0x9d, to); } -// setg r8 -__forceinline void SETG8R( x86IntRegType to ) { SET8R(0x9f, to); } -// seta r8 -__forceinline void SETA8R( x86IntRegType to ) { SET8R(0x97, to); } -// setae r8 -__forceinline void SETAE8R( x86IntRegType to ) { SET8R(0x99, to); } -/* setb r8 */ -__forceinline void SETB8R( x86IntRegType to ) { SET8R( 0x92, to ); } -/* setb r8 */ -__forceinline void SETNZ8R( x86IntRegType to ) { SET8R( 0x95, to ); } -// setz r8 -__forceinline void SETZ8R( x86IntRegType to ) { SET8R(0x94, to); } -// sete r8 -__forceinline void SETE8R( x86IntRegType to ) { SET8R(0x94, to); } - -/* push imm32 */ -__forceinline void PUSH32I( u32 from ) -{; - write8( 0x68 ); - write32( from ); -} - -/* push r32 */ -__forceinline void PUSH32R( x86IntRegType from ) { write8( 0x50 | from ); } - -/* push m32 */ -__forceinline void PUSH32M( u32 from ) -{ - write8( 0xFF ); - ModRM( 0, 6, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -/* pop r32 */ -__forceinline void POP32R( x86IntRegType from ) { write8( 0x58 | from ); } - -/* pushad */ -__forceinline void PUSHA32( void ) { write8( 0x60 ); } - -/* popad */ -__forceinline void POPA32( void ) { write8( 0x61 ); } - -__forceinline void PUSHR(x86IntRegType from) { PUSH32R(from); } -__forceinline void POPR(x86IntRegType from) { POP32R(from); } - - -/* pushfd */ -__forceinline void PUSHFD( void ) { write8( 0x9C ); } -/* popfd */ -__forceinline void POPFD( void ) { write8( 0x9D ); } - -__forceinline void RET( void ) { write8( 0xC3 ); } -__forceinline void RET2( void ) { write16( 0xc3f3 ); } - -__forceinline void CBW( void ) { write16( 0x9866 ); } -__forceinline void CWD( void ) { write8( 0x98 ); } -__forceinline void CDQ( void ) { write8( 0x99 ); } -__forceinline void CWDE() { write8(0x98); } - -__forceinline void LAHF() { write8(0x9f); } -__forceinline void SAHF() { write8(0x9e); } - -__forceinline void BT32ItoR( x86IntRegType to, u8 from ) -{ - write16( 0xBA0F ); - ModRM(3, 4, to); - write8( from ); -} - -__forceinline void BTR32ItoR( x86IntRegType to, u8 from ) -{ - write16( 0xBA0F ); - ModRM(3, 6, to); - write8( from ); -} - -__forceinline void BSRRtoR(x86IntRegType to, x86IntRegType from) -{ - write16( 0xBD0F ); - ModRM( 3, from, to ); -} - -__forceinline void BSWAP32R( x86IntRegType to ) -{ - write8( 0x0F ); - write8( 0xC8 + to ); -} - -// to = from + offset -__forceinline void LEA16RtoR(x86IntRegType to, x86IntRegType from, u16 offset) -{ - write8(0x66); - LEA32RtoR(to, from, offset); -} - -__forceinline void LEA32RtoR(x86IntRegType to, x86IntRegType from, u32 offset) -{ - RexRB(0,to,from); - write8(0x8d); - - if( (from&7) == ESP ) { - if( offset == 0 ) { - ModRM(1, to, from); - write8(0x24); - } - else if( offset < 128 ) { - ModRM(1, to, from); - write8(0x24); - write8(offset); - } - else { - ModRM(2, to, from); - write8(0x24); - write32(offset); - } - } - else { - if( offset == 0 && from != EBP && from!=ESP ) { - ModRM(0, to, from); - } - else if( offset < 128 ) { - ModRM(1, to, from); - write8(offset); - } - else { - ModRM(2, to, from); - write32(offset); - } - } -} - -// to = from0 + from1 -__forceinline void LEA16RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1) -{ - write8(0x66); - LEA32RRtoR(to, from0, from1); -} - -__forceinline void LEA32RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1) -{ - RexRXB(0, to, from0, from1); - write8(0x8d); - - if( (from1&7) == EBP ) { - ModRM(1, to, 4); - ModRM(0, from0, from1); - write8(0); - } - else { - ModRM(0, to, 4); - ModRM(0, from0, from1); - } -} - -// to = from << scale (max is 3) -__forceinline void LEA16RStoR(x86IntRegType to, x86IntRegType from, u32 scale) -{ - write8(0x66); - LEA32RStoR(to, from, scale); -} - -// Don't inline recursive functions -void LEA32RStoR(x86IntRegType to, x86IntRegType from, u32 scale) -{ - if( to == from ) { - SHL32ItoR(to, scale); - return; - } - - if( from != ESP ) { - RexRXB(0,to,from,0); - write8(0x8d); - ModRM(0, to, 4); - ModRM(scale, from, 5); - write32(0); - } - else { - assert( to != ESP ); - MOV32RtoR(to, from); - LEA32RStoR(to, to, scale); - } -} \ No newline at end of file +XMMSSEType g_xmmtypes[XMMREGS] = { XMMT_INT }; diff --git a/pcsx2/x86/ix86/ix86.h b/pcsx2/x86/ix86/ix86.h index adb672cfd7..eaa568ba74 100644 --- a/pcsx2/x86/ix86/ix86.h +++ b/pcsx2/x86/ix86/ix86.h @@ -21,13 +21,26 @@ * alexey silinov * goldfinger * shadow < shadow@pcsx2.net > + * cottonvibes(@gmail.com) */ -#ifndef __IX86_H__ -#define __IX86_H__ - +#pragma once +#include "PrecompiledHeader.h" #include "PS2Etypes.h" // Basic types header +//------------------------------------------------------------------ +// Helper Macros +//------------------------------------------------------------------ +#define emitterT template inline /*__forceinline*/ + +#define MEMADDR(addr, oplen) (addr) + +#define Rex(w,r,x,b) assert(0); +#define RexR(w, reg) if( w||(reg)>=8 ) assert(0); +#define RexB(w, base) if( w||(base)>=8 ) assert(0); +#define RexRB(w, reg, base) if( w||(reg) >= 8 || (base)>=8 ) assert(0); +#define RexRXB(w, reg, index, base) if( w||(reg) >= 8 || (index) >= 8 || (base) >= 8 ) assert(0); + #define XMMREGS 8 #define X86REGS 8 @@ -158,1598 +171,81 @@ struct CPUINFO{ }; extern CPUINFO cpuinfo; +//------------------------------------------------------------------ -extern u8 *x86Ptr; +//------------------------------------------------------------------ +// write functions +//------------------------------------------------------------------ +extern u8 *x86Ptr[3]; extern u8 *j8Ptr[32]; extern u32 *j32Ptr[32]; -#define MEMADDR(addr, oplen) (addr) +emitterT void write8(u8 val ) { + *x86Ptr[I] = (u8)val; + x86Ptr[I]++; +} -#define Rex(w,r,x,b) assert(0); -#define RexR(w, reg) if( w||(reg)>=8 ) assert(0); -#define RexB(w, base) if( w||(base)>=8 ) assert(0); -#define RexRB(w, reg, base) if( w||(reg) >= 8 || (base)>=8 ) assert(0); -#define RexRXB(w, reg, index, base) if( w||(reg) >= 8 || (index) >= 8 || (base) >= 8 ) assert(0); +emitterT void write16(u16 val ) { + *(u16*)x86Ptr[I] = (u16)val; + x86Ptr[I] += 2; +} -extern __forceinline void write8( u8 val ); -extern __forceinline void write16( u16 val ); -extern __forceinline void write32( u32 val ); -extern void write64( u64 val ); +emitterT void write24(u32 val ) { + *(u8*)x86Ptr[I] = (u8)(val & 0xff); + x86Ptr[I]++; + *(u8*)x86Ptr[I] = (u8)((val >> 8) & 0xff); + x86Ptr[I]++; + *(u8*)x86Ptr[I] = (u8)((val >> 16) & 0xff); + x86Ptr[I]++; +} +emitterT void write32(u32 val ) { + *(u32*)x86Ptr[I] = val; + x86Ptr[I] += 4; +} -extern void x86SetPtr( u8 *ptr ); -extern void x86Shutdown( void ); - -extern void x86SetJ8( u8 *j8 ); -extern void x86SetJ8A( u8 *j8 ); -extern void x86SetJ16( u16 *j16 ); -extern void x86SetJ16A( u16 *j16 ); -extern void x86SetJ32( u32 *j32 ); -extern void x86SetJ32A( u32 *j32 ); - -extern void x86Align( int bytes ); -extern void x86AlignExecutable( int align ); - -u64 GetCPUTick( void ); - -// General Helper functions -extern void ModRM( int mod, int reg, int rm ); -extern void SibSB( int ss, int index, int base ); -extern void SET8R( int cc, int to ); -extern u8* J8Rel( int cc, int to ); -extern u32* J32Rel( int cc, u32 to ); -extern void CMOV32RtoR( int cc, int to, int from ); -extern void CMOV32MtoR( int cc, int to, uptr from ); - -//****************** -// IX86 intructions -//****************** - -// -// * scale values: -// * 0 - *1 -// * 1 - *2 -// * 2 - *4 -// * 3 - *8 -// - -extern void STC( void ); -extern void CLC( void ); -extern void NOP( void ); - -//////////////////////////////////// -// mov instructions // -//////////////////////////////////// - -// mov r64 to r64 -extern void MOV64RtoR( x86IntRegType to, x86IntRegType from ); -// mov r64 to m64 -extern void MOV64RtoM( uptr to, x86IntRegType from ); -// mov m64 to r64 -extern void MOV64MtoR( x86IntRegType to, uptr from ); -// mov sign ext imm32 to m64 -extern void MOV64I32toM( uptr to, u32 from ); -// mov sign ext imm32 to r64 -extern void MOV64I32toR( x86IntRegType to, s32 from); -// mov imm64 to r64 -extern void MOV64ItoR( x86IntRegType to, u64 from); -// mov imm64 to [r64+off] -extern void MOV64ItoRmOffset( x86IntRegType to, u32 from, int offset); -// mov [r64+offset] to r64 -extern void MOV64RmOffsettoR( x86IntRegType to, x86IntRegType from, int offset ); -// mov [r64][r64*scale] to r64 -extern void MOV64RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale); -// mov r64 to [r64+offset] -extern void MOV64RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset ); -// mov r64 to [r64][r64*scale] -extern void MOV64RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale); - -// mov r32 to r32 -extern void MOV32RtoR( x86IntRegType to, x86IntRegType from ); -// mov r32 to m32 -extern void MOV32RtoM( uptr to, x86IntRegType from ); -// mov m32 to r32 -extern void MOV32MtoR( x86IntRegType to, uptr from ); -// mov [r32] to r32 -extern void MOV32RmtoR( x86IntRegType to, x86IntRegType from ); -extern void MOV32RmtoROffset( x86IntRegType to, x86IntRegType from, int offset ); -// mov [r32][r32< subtract ST(0) from ST(1), store in ST(1) and POP stack -extern void FSUBP( void ); -// fmul ST(src) to fpu reg stack ST(0) -extern void FMUL32Rto0( x86IntRegType src ); -// fmul ST(0) to fpu reg stack ST(src) -extern void FMUL320toR( x86IntRegType src ); -// fdiv ST(src) to fpu reg stack ST(0) -extern void FDIV32Rto0( x86IntRegType src ); -// fdiv ST(0) to fpu reg stack ST(src) -extern void FDIV320toR( x86IntRegType src ); -// fdiv ST(0) to fpu reg stack ST(src), pop stack, store in ST(src) -extern void FDIV320toRP( x86IntRegType src ); - -// fadd m32 to fpu reg stack -extern void FADD32( u32 from ); -// fsub m32 to fpu reg stack -extern void FSUB32( u32 from ); -// fmul m32 to fpu reg stack -extern void FMUL32( u32 from ); -// fdiv m32 to fpu reg stack -extern void FDIV32( u32 from ); -// fcomi st, st( i) -extern void FCOMI( x86IntRegType src ); -// fcomip st, st( i) -extern void FCOMIP( x86IntRegType src ); -// fucomi st, st( i) -extern void FUCOMI( x86IntRegType src ); -// fucomip st, st( i) -extern void FUCOMIP( x86IntRegType src ); -// fcom m32 to fpu reg stack -extern void FCOM32( u32 from ); -// fabs fpu reg stack -extern void FABS( void ); -// fsqrt fpu reg stack -extern void FSQRT( void ); -// ftan fpu reg stack -extern void FPATAN( void ); -// fsin fpu reg stack -extern void FSIN( void ); -// fchs fpu reg stack -extern void FCHS( void ); - -// fcmovb fpu reg to fpu reg stack -extern void FCMOVB32( x86IntRegType from ); -// fcmove fpu reg to fpu reg stack -extern void FCMOVE32( x86IntRegType from ); -// fcmovbe fpu reg to fpu reg stack -extern void FCMOVBE32( x86IntRegType from ); -// fcmovu fpu reg to fpu reg stack -extern void FCMOVU32( x86IntRegType from ); -// fcmovnb fpu reg to fpu reg stack -extern void FCMOVNB32( x86IntRegType from ); -// fcmovne fpu reg to fpu reg stack -extern void FCMOVNE32( x86IntRegType from ); -// fcmovnbe fpu reg to fpu reg stack -extern void FCMOVNBE32( x86IntRegType from ); -// fcmovnu fpu reg to fpu reg stack -extern void FCMOVNU32( x86IntRegType from ); -extern void FCOMP32( u32 from ); -extern void FNSTSWtoAX( void ); - #define MMXONLY(code) code - -//****************** -// MMX instructions -//****************** - -// r64 = mm - -// movq m64 to r64 -extern void MOVQMtoR( x86MMXRegType to, uptr from ); -// movq r64 to m64 -extern void MOVQRtoM( uptr to, x86MMXRegType from ); - -// pand r64 to r64 -extern void PANDRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PANDNRtoR( x86MMXRegType to, x86MMXRegType from ); -// pand m64 to r64 ; -extern void PANDMtoR( x86MMXRegType to, uptr from ); -// pandn r64 to r64 -extern void PANDNRtoR( x86MMXRegType to, x86MMXRegType from ); -// pandn r64 to r64 -extern void PANDNMtoR( x86MMXRegType to, uptr from ); -// por r64 to r64 -extern void PORRtoR( x86MMXRegType to, x86MMXRegType from ); -// por m64 to r64 -extern void PORMtoR( x86MMXRegType to, uptr from ); -// pxor r64 to r64 -extern void PXORRtoR( x86MMXRegType to, x86MMXRegType from ); -// pxor m64 to r64 -extern void PXORMtoR( x86MMXRegType to, uptr from ); - -// psllq r64 to r64 -extern void PSLLQRtoR( x86MMXRegType to, x86MMXRegType from ); -// psllq m64 to r64 -extern void PSLLQMtoR( x86MMXRegType to, uptr from ); -// psllq imm8 to r64 -extern void PSLLQItoR( x86MMXRegType to, u8 from ); -// psrlq r64 to r64 -extern void PSRLQRtoR( x86MMXRegType to, x86MMXRegType from ); -// psrlq m64 to r64 -extern void PSRLQMtoR( x86MMXRegType to, uptr from ); -// psrlq imm8 to r64 -extern void PSRLQItoR( x86MMXRegType to, u8 from ); - -// paddusb r64 to r64 -extern void PADDUSBRtoR( x86MMXRegType to, x86MMXRegType from ); -// paddusb m64 to r64 -extern void PADDUSBMtoR( x86MMXRegType to, uptr from ); -// paddusw r64 to r64 -extern void PADDUSWRtoR( x86MMXRegType to, x86MMXRegType from ); -// paddusw m64 to r64 -extern void PADDUSWMtoR( x86MMXRegType to, uptr from ); - -// paddb r64 to r64 -extern void PADDBRtoR( x86MMXRegType to, x86MMXRegType from ); -// paddb m64 to r64 -extern void PADDBMtoR( x86MMXRegType to, uptr from ); -// paddw r64 to r64 -extern void PADDWRtoR( x86MMXRegType to, x86MMXRegType from ); -// paddw m64 to r64 -extern void PADDWMtoR( x86MMXRegType to, uptr from ); -// paddd r64 to r64 -extern void PADDDRtoR( x86MMXRegType to, x86MMXRegType from ); -// paddd m64 to r64 -extern void PADDDMtoR( x86MMXRegType to, uptr from ); -extern void PADDSBRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PADDSWRtoR( x86MMXRegType to, x86MMXRegType from ); - -// paddq m64 to r64 (sse2 only?) -extern void PADDQMtoR( x86MMXRegType to, uptr from ); -// paddq r64 to r64 (sse2 only?) -extern void PADDQRtoR( x86MMXRegType to, x86MMXRegType from ); - -extern void PSUBSBRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PSUBSWRtoR( x86MMXRegType to, x86MMXRegType from ); - -extern void PSUBBRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PSUBWRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PSUBDRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PSUBDMtoR( x86MMXRegType to, uptr from ); - -// psubq m64 to r64 (sse2 only?) -extern void PSUBQMtoR( x86MMXRegType to, uptr from ); -// psubq r64 to r64 (sse2 only?) -extern void PSUBQRtoR( x86MMXRegType to, x86MMXRegType from ); - -// pmuludq m64 to r64 (sse2 only?) -extern void PMULUDQMtoR( x86MMXRegType to, uptr from ); -// pmuludq r64 to r64 (sse2 only?) -extern void PMULUDQRtoR( x86MMXRegType to, x86MMXRegType from ); - -extern void PCMPEQBRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PCMPEQWRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PCMPEQDRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PCMPEQDMtoR( x86MMXRegType to, uptr from ); -extern void PCMPGTBRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PCMPGTWRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PCMPGTDRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PCMPGTDMtoR( x86MMXRegType to, uptr from ); -extern void PSRLWItoR( x86MMXRegType to, u8 from ); -extern void PSRLDItoR( x86MMXRegType to, u8 from ); -extern void PSRLDRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PSLLWItoR( x86MMXRegType to, u8 from ); -extern void PSLLDItoR( x86MMXRegType to, u8 from ); -extern void PSLLDRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PSRAWItoR( x86MMXRegType to, u8 from ); -extern void PSRADItoR( x86MMXRegType to, u8 from ); -extern void PSRADRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PUNPCKLDQRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PUNPCKLDQMtoR( x86MMXRegType to, uptr from ); -extern void PUNPCKHDQRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void PUNPCKHDQMtoR( x86MMXRegType to, uptr from ); -extern void MOVQ64ItoR( x86MMXRegType reg, u64 i ); //Prototype.Todo add all consts to end of block.not after jr $+8 -extern void MOVQRtoR( x86MMXRegType to, x86MMXRegType from ); -extern void MOVQRmtoROffset( x86MMXRegType to, x86IntRegType from, u32 offset ); -extern void MOVQRtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset ); -extern void MOVDMtoMMX( x86MMXRegType to, uptr from ); -extern void MOVDMMXtoM( uptr to, x86MMXRegType from ); -extern void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from ); -extern void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from ); -extern void MOVD32RmOffsettoMMX( x86MMXRegType to, x86IntRegType from, u32 offset ); -extern void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from ); -extern void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from ); -extern void MOVD32MMXtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset ); -extern void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 ); -extern void PSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8); -extern void PSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8); -extern void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from); - -// emms -extern void EMMS( void ); - -//**********************************************************************************/ -//PACKSSWB,PACKSSDW: Pack Saturate Signed Word 64bits -//********************************************************************************** -extern void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from); -extern void PACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType from); - -extern void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from); - -extern void SSE2_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from); -extern void SSE2_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from); - -//********************* -// SSE instructions * -//********************* -extern void SSE_MOVAPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MOVAPS_XMM_to_M128( uptr to, x86SSERegType from ); -extern void SSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSE_MOVUPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MOVUPS_XMM_to_M128( uptr to, x86SSERegType from ); - -extern void SSE_MOVSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MOVSS_XMM_to_M32( u32 to, x86SSERegType from ); -extern void SSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from ); -extern void SSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MOVSS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSE_MOVSS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ); - -extern void SSE2_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSE2_MOVQ_M64_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_MOVQ_XMM_to_M64( u32 to, x86SSERegType from ); - -extern void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ); -extern void SSE_MOVLPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSE_MOVLPS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ); - -extern void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ); -extern void SSE_MOVHPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSE_MOVHPS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ); - -extern void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from ); -extern void SSE_MOVLPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from ); -extern void SSE_MOVLPSRtoRmOffset( x86SSERegType to, x86IntRegType from, int offset ); - -extern void SSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ); -extern void SSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ); -extern void SSE_MOVAPSRtoRmOffset( x86IntRegType to, x86SSERegType from, int offset ); -extern void SSE_MOVAPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ); -extern void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ); -extern void SSE_MOVUPSRtoRm( x86IntRegType to, x86IntRegType from ); -extern void SSE_MOVUPSRmtoR( x86IntRegType to, x86IntRegType from ); - -extern void SSE_MOVUPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSE_MOVUPSRtoRmOffset( x86SSERegType to, x86IntRegType from, int offset ); - -extern void SSE2_MOVDQARtoRmOffset( x86IntRegType to, x86SSERegType from, int offset ); -extern void SSE2_MOVDQARmtoROffset( x86SSERegType to, x86IntRegType from, int offset ); - -extern void SSE_RCPPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_RCPPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_RCPSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_RCPSS_M32_to_XMM( x86SSERegType to, uptr from ); - -extern void SSE_ORPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_ORPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_XORPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_XORPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_ANDPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_ANDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_ANDNPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_ANDNPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_ADDPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_ADDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_ADDSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_ADDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_SUBPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_SUBPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_SUBSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_SUBSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MULPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MULPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MULSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MULSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPEQSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPEQSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPLTSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPLTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPLESS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPLESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPUNORDSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPUNORDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPNESS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPNESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPNLTSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPNLTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPNLESS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPNLESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPORDSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPORDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSE_UCOMISS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_UCOMISS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSE_PMAXSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ); -extern void SSE_PMINSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ); -extern void SSE_CVTPI2PS_MM_to_XMM( x86SSERegType to, x86MMXRegType from ); -extern void SSE_CVTPS2PI_M64_to_MM( x86MMXRegType to, uptr from ); -extern void SSE_CVTPS2PI_XMM_to_MM( x86MMXRegType to, x86SSERegType from ); - -extern void SSE_CVTPI2PS_M64_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from); -extern void SSE_CVTTSS2SI_XMM_to_R32(x86IntRegType to, x86SSERegType from); -extern void SSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from); -extern void SSE_CVTSI2SS_R_to_XMM(x86SSERegType to, x86IntRegType from); - -extern void SSE2_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_CVTDQ2PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_CVTPS2DQ_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSE2_MAXPD_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_MAXPD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MAXPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MAXPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MAXSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MAXSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_MINPD_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_MINPD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MINPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MINPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_MINSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_MINSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_RSQRTPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_RSQRTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_RSQRTSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_RSQRTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_SQRTPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_SQRTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_SQRTSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_SQRTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_UNPCKLPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_UNPCKLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_UNPCKHPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_UNPCKHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_SHUFPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ); -extern void SSE_SHUFPS_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ); -extern void SSE_SHUFPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset, u8 imm8 ); -extern void SSE_CMPEQPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPEQPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPLTPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPLTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPLEPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPLEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPUNORDPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPUNORDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPNEPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPNEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPNLTPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPNLTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPNLEPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPNLEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_CMPORDPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_CMPORDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_DIVPS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_DIVPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE_DIVSS_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE_DIVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -// VectorPath -extern void SSE2_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ); -extern void SSE2_PSHUFD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ); - -extern void SSE2_PSHUFLW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ); -extern void SSE2_PSHUFLW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ); -extern void SSE2_PSHUFHW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ); -extern void SSE2_PSHUFHW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ); - -extern void SSE2_SHUFPD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ); -extern void SSE2_SHUFPD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ); - -extern void SSE_STMXCSR( uptr from ); -extern void SSE_LDMXCSR( uptr from ); - - -//********************* -// SSE 2 Instructions* -//********************* -extern void SSE2_MOVDQA_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from); -extern void SSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from); - -extern void SSE2_MOVDQU_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from); -extern void SSE2_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from); - -extern void SSE2_PSRLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PSRLW_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PSRLW_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSRLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PSRLD_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PSRLD_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSRLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PSRLQ_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PSRLQ_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSRLDQ_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSRAW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PSRAW_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PSRAW_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSRAD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PSRAD_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PSRAD_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSLLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PSLLW_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PSLLW_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSLLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PSLLD_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PSLLD_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSLLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PSLLQ_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PSLLQ_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PSLLDQ_I8_to_XMM(x86SSERegType to, u8 imm8); -extern void SSE2_PMAXSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PMAXSW_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PMAXUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PMAXUB_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PMINSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PMINSW_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PMINUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PMINUB_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PADDSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PADDSB_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PADDSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PADDSW_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PSUBSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PSUBSB_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PSUBSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PSUBSW_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PSUBUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PSUBUSB_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PSUBUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PSUBUSW_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PAND_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PANDN_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PXOR_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PADDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PADDW_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PADDUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PADDUSB_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PADDUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_PADDUSW_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_PADDB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PADDB_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PADDD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PADDD_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PADDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PADDQ_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PMADDWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); - -//**********************************************************************************/ -//PACKSSWB,PACKSSDW: Pack Saturate Signed Word -//********************************************************************************** -extern void SSE2_PACKSSWB_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PACKSSWB_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PACKSSDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PACKSSDW_M128_to_XMM(x86SSERegType to, uptr from); - -extern void SSE2_PACKUSWB_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PACKUSWB_M128_to_XMM(x86SSERegType to, uptr from); - -//**********************************************************************************/ -//PUNPCKHWD: Unpack 16bit high -//********************************************************************************** -extern void SSE2_PUNPCKLBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PUNPCKLBW_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PUNPCKHBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PUNPCKHBW_M128_to_XMM(x86SSERegType to, uptr from); - -extern void SSE2_PUNPCKLWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PUNPCKLWD_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PUNPCKHWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PUNPCKHWD_M128_to_XMM(x86SSERegType to, uptr from); - -extern void SSE2_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from); - -extern void SSE2_PUNPCKLQDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PUNPCKLQDQ_M128_to_XMM(x86SSERegType to, uptr from); - -extern void SSE2_PUNPCKHQDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PUNPCKHQDQ_M128_to_XMM(x86SSERegType to, uptr from); - -// mult by half words -extern void SSE2_PMULLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PMULLW_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE2_PMULHW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PMULHW_M128_to_XMM(x86SSERegType to, uptr from); - -extern void SSE2_PMULUDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE2_PMULUDQ_M128_to_XMM(x86SSERegType to, uptr from); - - -//**********************************************************************************/ -//PMOVMSKB: Create 16bit mask from signs of 8bit integers -//********************************************************************************** -extern void SSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from); - -extern void SSE_MOVMSKPS_XMM_to_R32(x86IntRegType to, x86SSERegType from); -extern void SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from); - -//**********************************************************************************/ -//PEXTRW,PINSRW: Packed Extract/Insert Word * -//********************************************************************************** -extern void SSE_PEXTRW_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8 ); -extern void SSE_PINSRW_R32_to_XMM(x86SSERegType from, x86IntRegType to, u8 imm8 ); - - -//**********************************************************************************/ -//PSUBx: Subtract Packed Integers * -//********************************************************************************** -extern void SSE2_PSUBB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PSUBB_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PSUBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PSUBW_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PSUBD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PSUBD_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PSUBQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PSUBQ_M128_to_XMM(x86SSERegType to, uptr from ); -/////////////////////////////////////////////////////////////////////////////////////// -//**********************************************************************************/ -//PCMPxx: Compare Packed Integers * -//********************************************************************************** -extern void SSE2_PCMPGTB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PCMPGTB_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PCMPGTW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PCMPGTW_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PCMPGTD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PCMPGTD_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PCMPEQB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PCMPEQB_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PCMPEQW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PCMPEQW_M128_to_XMM(x86SSERegType to, uptr from ); -extern void SSE2_PCMPEQD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ); -extern void SSE2_PCMPEQD_M128_to_XMM(x86SSERegType to, uptr from ); -//**********************************************************************************/ -//MOVD: Move Dword(32bit) to /from XMM reg * -//********************************************************************************** -extern void SSE2_MOVD_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from ); -extern void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from ); -extern void SSE2_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSE2_MOVD_XMM_to_M32( u32 to, x86SSERegType from ); -extern void SSE2_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ); -extern void SSE2_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from ); -extern void SSE2_MOVD_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ); - -extern void SSE2_MOVQ_XMM_to_R( x86IntRegType to, x86SSERegType from ); -extern void SSE2_MOVQ_R_to_XMM( x86SSERegType to, x86IntRegType from ); - -//**********************************************************************************/ -//POR : SSE Bitwise OR * -//********************************************************************************** -extern void SSE2_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2_POR_M128_to_XMM( x86SSERegType to, uptr from ); - -extern void SSE3_HADDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE3_HADDPS_M128_to_XMM(x86SSERegType to, uptr from); - -extern void SSE3_MOVSLDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE3_MOVSLDUP_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE3_MOVSHDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE3_MOVSHDUP_M128_to_XMM(x86SSERegType to, uptr from); - -// SSSE3 - -extern void SSSE3_PABSB_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSSE3_PABSW_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSSE3_PABSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSSE3_PALIGNR_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); - -// SSE4.1 - -#ifndef _MM_MK_INSERTPS_NDX #define _MM_MK_INSERTPS_NDX(srcField, dstField, zeroMask) (((srcField)<<6) | ((dstField)<<4) | (zeroMask)) -#endif +extern void SysPrintf(const char *fmt, ...); -extern void SSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); -extern void SSE4_DPPS_M128_to_XMM(x86SSERegType to, uptr from, u8 imm8); -extern void SSE4_INSERTPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); -extern void SSE4_EXTRACTPS_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8); -extern void SSE4_BLENDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); -extern void SSE4_BLENDVPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE4_BLENDVPS_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE4_PMOVSXDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE4_PINSRD_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8); -extern void SSE4_PMAXSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE4_PMINSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE4_PMAXUD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE4_PMINUD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSE4_PMAXSD_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE4_PMINSD_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE4_PMAXUD_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE4_PMINUD_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSE4_PMULDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); - -//********************* -// SSE-X - uses both SSE,SSE2 code and tries to keep consistensies between the data -// Uses g_xmmtypes to infer the correct type. -//********************* -extern void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from ); -extern void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSEX_MOVDQARmtoROffset( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSEX_MOVDQARtoRmOffset( x86IntRegType to, x86SSERegType from, int offset ); - -extern void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from ); -extern void SSEX_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from ); -extern void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from ); -extern void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from ); -extern void SSEX_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSEX_MOVD_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ); - -extern void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -extern void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from); -extern void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from); -extern void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from); - -extern void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); - -//********************* -// 3DNOW instructions * -//********************* -extern void FEMMS( void ); -extern void PFCMPEQMtoR( x86IntRegType to, uptr from ); -extern void PFCMPGTMtoR( x86IntRegType to, uptr from ); -extern void PFCMPGEMtoR( x86IntRegType to, uptr from ); -extern void PFADDMtoR( x86IntRegType to, uptr from ); -extern void PFADDRtoR( x86IntRegType to, x86IntRegType from ); -extern void PFSUBMtoR( x86IntRegType to, uptr from ); -extern void PFSUBRtoR( x86IntRegType to, x86IntRegType from ); -extern void PFMULMtoR( x86IntRegType to, uptr from ); -extern void PFMULRtoR( x86IntRegType to, x86IntRegType from ); -extern void PFRCPMtoR( x86IntRegType to, uptr from ); -extern void PFRCPRtoR( x86IntRegType to, x86IntRegType from ); -extern void PFRCPIT1RtoR( x86IntRegType to, x86IntRegType from ); -extern void PFRCPIT2RtoR( x86IntRegType to, x86IntRegType from ); -extern void PFRSQRTRtoR( x86IntRegType to, x86IntRegType from ); -extern void PFRSQIT1RtoR( x86IntRegType to, x86IntRegType from ); -extern void PF2IDMtoR( x86IntRegType to, uptr from ); -extern void PI2FDMtoR( x86IntRegType to, uptr from ); -extern void PI2FDRtoR( x86IntRegType to, x86IntRegType from ); -extern void PFMAXMtoR( x86IntRegType to, uptr from ); -extern void PFMAXRtoR( x86IntRegType to, x86IntRegType from ); -extern void PFMINMtoR( x86IntRegType to, uptr from ); -extern void PFMINRtoR( x86IntRegType to, x86IntRegType from ); - -extern void SSE2EMU_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from); -extern void SSE2EMU_MOVQ_M64_to_XMM( x86SSERegType to, uptr from); -extern void SSE2EMU_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from); -extern void SSE2EMU_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ); -extern void SSE2EMU_MOVD_XMM_to_RmOffset(x86IntRegType to, x86SSERegType from, int offset ); - -extern void SSE2EMU_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from); -extern void SSE2EMU_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from); - -/* SSE2 emulated functions for SSE CPU's by kekko*/ - -extern void SSE2EMU_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ); -extern void SSE2EMU_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ); -extern void SSE2EMU_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); -extern void SSE2EMU_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ); -extern void SSE2EMU_MOVD_XMM_to_M32( u32 to, x86SSERegType from ); -extern void SSE2EMU_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from ); - -//////////////////////////////////////////////////// -#ifdef _DEBUG -#define WRITECHECK() CheckX86Ptr() -#else -#define WRITECHECK() -#endif - -__forceinline void write8(u8 val ) { - *x86Ptr = (u8)val; - x86Ptr++; -} - -__forceinline void write16(u16 val ) -{ - *(u16*)x86Ptr = (u16)val; - x86Ptr += 2; -} - -__forceinline void write24(u32 val ) -{ - *(u8*)x86Ptr = (u8)(val & 0xff); - x86Ptr++; - *(u8*)x86Ptr = (u8)((val >> 8) & 0xff); - x86Ptr++; - *(u8*)x86Ptr = (u8)((val >> 16) & 0xff); - x86Ptr++; -} - -__forceinline void write32(u32 val ) -{ - *(u32*)x86Ptr = val; - x86Ptr += 4; -} - -#endif // __IX86_H__ \ No newline at end of file +#include "ix86_macros.h" +#include "ix86.inl" +#include "ix86_3dnow.inl" +#include "ix86_fpu.inl" +#include "ix86_mmx.inl" +#include "ix86_sse.inl" diff --git a/pcsx2/x86/ix86/ix86.inl b/pcsx2/x86/ix86/ix86.inl new file mode 100644 index 0000000000..f09cb3b1bb --- /dev/null +++ b/pcsx2/x86/ix86/ix86.inl @@ -0,0 +1,3336 @@ +/* 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 +*/ +/* +* ix86 core v0.6.2 +* Authors: linuzappz +* alexey silinov +* goldfinger +* zerofrog(@gmail.com) +* cottonvibes(@gmail.com) +*/ + +#pragma once + +//------------------------------------------------------------------ +// ix86 instructions +//------------------------------------------------------------------ + +emitterT void WriteRmOffset(x86IntRegType to, s32 offset) +{ + if( (to&7) == ESP ) { + if( offset == 0 ) { + ModRM( 0, 0, 4 ); + SibSB( 0, ESP, 4 ); + } + else if( offset < 128 && offset >= -128 ) { + ModRM( 1, 0, 4 ); + SibSB( 0, ESP, 4 ); + write8(offset); + } + else { + ModRM( 2, 0, 4 ); + SibSB( 0, ESP, 4 ); + write32(offset); + } + } + else { + if( offset == 0 ) { + ModRM( 0, 0, to ); + } + else if( offset < 128 && offset >= -128 ) { + ModRM( 1, 0, to ); + write8(offset); + } + else { + ModRM( 2, 0, to ); + write32(offset); + } + } +} + +emitterT void WriteRmOffsetFrom(x86IntRegType to, x86IntRegType from, int offset) +{ + if ((from&7) == ESP) { + if( offset == 0 ) { + ModRM( 0, to, 0x4 ); + SibSB( 0, 0x4, 0x4 ); + } + else if( offset < 128 && offset >= -128 ) { + ModRM( 1, to, 0x4 ); + SibSB( 0, 0x4, 0x4 ); + write8(offset); + } + else { + ModRM( 2, to, 0x4 ); + SibSB( 0, 0x4, 0x4 ); + write32(offset); + } + } + else { + if( offset == 0 ) { + ModRM( 0, to, from ); + } + else if( offset < 128 && offset >= -128 ) { + ModRM( 1, to, from ); + write8(offset); + } + else { + ModRM( 2, to, from ); + write32(offset); + } + } +} + +emitterT void ModRM( s32 mod, s32 reg, s32 rm ) +{ + write8( ( mod << 6 ) | ( (reg & 7) << 3 ) | ( rm & 7 ) ); +} + +emitterT void SibSB( s32 ss, s32 index, s32 base ) +{ + write8( ( ss << 6 ) | ( (index & 7) << 3 ) | ( base & 7 ) ); +} + +emitterT void SET8R( int cc, int to ) +{ + RexB(0, to); + write8( 0x0F ); + write8( cc ); + write8( 0xC0 | ( to ) ); +} + +emitterT u8* J8Rel( int cc, int to ) +{ + write8( cc ); + write8( to ); + return (u8*)(x86Ptr[I] - 1); +} + +emitterT u16* J16Rel( int cc, u32 to ) +{ + write16( 0x0F66 ); + write8( cc ); + write16( to ); + return (u16*)( x86Ptr[I] - 2 ); +} + +emitterT u32* J32Rel( int cc, u32 to ) +{ + write8( 0x0F ); + write8( cc ); + write32( to ); + return (u32*)( x86Ptr[I] - 4 ); +} + +emitterT void CMOV32RtoR( int cc, int to, int from ) +{ + RexRB(0, to, from); + write8( 0x0F ); + write8( cc ); + ModRM( 3, to, from ); +} + +emitterT void CMOV32MtoR( int cc, int to, uptr from ) +{ + RexR(0, to); + write8( 0x0F ); + write8( cc ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +//////////////////////////////////////////////////// +emitterT void ex86SetPtr( u8* ptr ) +{ + x86Ptr[I] = ptr; +} + +//////////////////////////////////////////////////// +emitterT void ex86SetJ8( u8* j8 ) +{ + u32 jump = ( x86Ptr[I] - j8 ) - 1; + + if ( jump > 0x7f ) { + Console::Error( "j8 greater than 0x7f!!" ); + assert(0); + } + *j8 = (u8)jump; +} + +emitterT void ex86SetJ8A( u8* j8 ) +{ + u32 jump = ( x86Ptr[I] - j8 ) - 1; + + if ( jump > 0x7f ) { + Console::Error( "j8 greater than 0x7f!!" ); + assert(0); + } + + if( ((uptr)x86Ptr[I]&0xf) > 4 ) { + + uptr newjump = jump + 16-((uptr)x86Ptr[I]&0xf); + + if( newjump <= 0x7f ) { + jump = newjump; + while((uptr)x86Ptr[I]&0xf) *x86Ptr[I]++ = 0x90; + } + } + *j8 = (u8)jump; +} + +emitterT void ex86SetJ16( u16 *j16 ) +{ + // doesn't work + u32 jump = ( x86Ptr[I] - (u8*)j16 ) - 2; + + if ( jump > 0x7fff ) { + Console::Error( "j16 greater than 0x7fff!!" ); + assert(0); + } + *j16 = (u16)jump; +} + +emitterT void ex86SetJ16A( u16 *j16 ) +{ + if( ((uptr)x86Ptr[I]&0xf) > 4 ) { + while((uptr)x86Ptr[I]&0xf) *x86Ptr[I]++ = 0x90; + } + ex86SetJ16(j16); +} + +//////////////////////////////////////////////////// +emitterT void ex86SetJ32( u32* j32 ) +{ + *j32 = ( x86Ptr[I] - (u8*)j32 ) - 4; +} + +emitterT void ex86SetJ32A( u32* j32 ) +{ + while((uptr)x86Ptr[I]&0xf) *x86Ptr[I]++ = 0x90; + ex86SetJ32(j32); +} + +//////////////////////////////////////////////////// +emitterT void ex86Align( int bytes ) +{ + // forward align + x86Ptr[I] = (u8*)( ( (uptr)x86Ptr[I] + bytes - 1) & ~( bytes - 1 ) ); +} + +//////////////////////////////////////////////////// +// Generates executable code to align to the given alignment (could be useful for the second leg +// of if/else conditionals, which usually fall through a jump target label). +emitterT void ex86AlignExecutable( int align ) +{ + uptr newx86 = ( (uptr)x86Ptr[I] + align - 1) & ~( align - 1 ); + uptr bytes = ( newx86 - (uptr)x86Ptr[I] ); + + switch( bytes ) + { + case 0: break; + + case 1: eeNOP(); break; + case 2: eMOV32RtoR( ESI, ESI ); break; + case 3: write8(0x08D); write8(0x024); write8(0x024); break; + case 5: eNOP(); // falls through to 4... + case 4: write8(0x08D); write8(0x064); write8(0x024); write8(0); break; + case 6: write8(0x08D); write8(0x0B6); write32(0); break; + case 8: eNOP(); // falls through to 7... + case 7: write8(0x08D); write8(0x034); write8(0x035); write32(0); break; + + default: + { + // for larger alignments, just use a JMP... + u8* aligned_target = eJMP8(0); + x86Ptr[I] = (u8*)newx86; + ex86SetJ8( aligned_target ); + } + } + + jASSUME( x86Ptr[0] == (u8*)newx86 ); +} + +/********************/ +/* IX86 intructions */ +/********************/ + +emitterT void eSTC( void ) +{ + write8( 0xF9 ); +} + +emitterT void eCLC( void ) +{ + write8( 0xF8 ); +} + +// NOP 1-byte +emitterT void eNOP( void ) +{ + write8(0x90); +} + + +//////////////////////////////////// +// mov instructions / +//////////////////////////////////// + +/* mov r64 to r64 */ +emitterT void eMOV64RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(1, from, to); + write8( 0x89 ); + ModRM( 3, from, to ); +} + +/* mov r64 to m64 */ +emitterT void eMOV64RtoM( uptr to, x86IntRegType from ) +{ + RexR(1, from); + write8( 0x89 ); + ModRM( 0, from, DISP32 ); + write32( (u32)MEMADDR(to, 4) ); +} + +/* mov m64 to r64 */ +emitterT void eMOV64MtoR( x86IntRegType to, uptr from ) +{ + RexR(1, to); + write8( 0x8B ); + ModRM( 0, to, DISP32 ); + write32( (u32)MEMADDR(from, 4) ); +} + +/* mov imm32 to m64 */ +emitterT void eMOV64I32toM(uptr to, u32 from ) +{ + Rex(1, 0, 0, 0); + write8( 0xC7 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +// mov imm64 to r64 +emitterT void eMOV64ItoR( x86IntRegType to, u64 from) +{ + RexB(1, to); + write8( 0xB8 | (to & 0x7) ); + write64( from ); +} + +/* mov imm32 to r64 */ +emitterT void eMOV64I32toR( x86IntRegType to, s32 from ) +{ + RexB(1, to); + write8( 0xC7 ); + ModRM( 0, 0, to ); + write32( from ); +} + +// mov imm64 to [r64+off] +emitterT void eMOV64ItoRmOffset( x86IntRegType to, u32 from, int offset) +{ + RexB(1,to); + write8( 0xC7 ); + WriteRmOffset(to, offset); + write32(from); +} + +// mov [r64+offset] to r64 +emitterT void eMOV64RmOffsettoR( x86IntRegType to, x86IntRegType from, int offset ) +{ + RexRB(1, to, from); + write8( 0x8B ); + WriteRmOffsetFrom(to, from, offset); +} + +/* mov [r64][r64*scale] to r64 */ +emitterT void eMOV64RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) { + RexRXB(1, to, from2, from); + write8( 0x8B ); + ModRM( 0, to, 0x4 ); + SibSB(scale, from2, from ); +} + +/* mov r64 to [r64+offset] */ +emitterT void eMOV64RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset ) +{ + RexRB(1,from,to); + write8( 0x89 ); + WriteRmOffsetFrom(from, to, offset); +} + +/* mov r64 to [r64][r64*scale] */ +emitterT void eMOV64RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) { + RexRXB(1, to, from2, from); + write8( 0x89 ); + ModRM( 0, to, 0x4 ); + SibSB(scale, from2, from ); +} + + +/* mov r32 to r32 */ +emitterT void eMOV32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0, from, to); + write8( 0x89 ); + ModRM( 3, from, to ); +} + +/* mov r32 to m32 */ +emitterT void eMOV32RtoM( uptr to, x86IntRegType from ) +{ + RexR(0, from); + write8( 0x89 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* mov m32 to r32 */ +emitterT void eMOV32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0, to); + write8( 0x8B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* mov [r32] to r32 */ +emitterT void eMOV32RmtoR( x86IntRegType to, x86IntRegType from ) { + RexRB(0, to, from); + write8(0x8B); + WriteRmOffsetFrom(to, from, 0); +} + +emitterT void eMOV32RmtoROffset( x86IntRegType to, x86IntRegType from, int offset ) { + RexRB(0, to, from); + write8( 0x8B ); + WriteRmOffsetFrom(to, from, offset); +} + +/* mov [r32+r32*scale] to r32 */ +emitterT void eMOV32RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) { + RexRXB(0,to,from2,from); + write8( 0x8B ); + ModRM( 0, to, 0x4 ); + SibSB(scale, from2, from ); +} + +// mov r32 to [r32<( 0x8B ); + ModRM( 0, to, 0x4 ); + ModRM( scale, from1, 5); + write32(from2); +} + +/* mov r32 to [r32] */ +emitterT void eMOV32RtoRm( x86IntRegType to, x86IntRegType from ) { + RexRB(0, from, to); + if ((to&7) == ESP) { + write8( 0x89 ); + ModRM( 0, from, 0x4 ); + SibSB( 0, 0x4, 0x4 ); + } + else { + write8( 0x89 ); + ModRM( 0, from, to ); + } +} + +/* mov r32 to [r32][r32*scale] */ +emitterT void eMOV32RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) { + RexRXB(0, to, from2, from); + write8( 0x89 ); + ModRM( 0, to, 0x4 ); + SibSB(scale, from2, from ); +} + +/* mov imm32 to r32 */ +emitterT void eMOV32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0, to); + write8( 0xB8 | (to & 0x7) ); + write32( from ); +} + +/* mov imm32 to m32 */ +emitterT void eMOV32ItoM(uptr to, u32 from ) +{ + write8( 0xC7 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +// mov imm32 to [r32+off] +emitterT void eMOV32ItoRmOffset( x86IntRegType to, u32 from, int offset) +{ + RexB(0,to); + write8( 0xC7 ); + WriteRmOffset(to, offset); + write32(from); +} + +// mov r32 to [r32+off] +emitterT void eMOV32RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset) +{ + RexRB(0,from,to); + write8( 0x89 ); + WriteRmOffsetFrom(from, to, offset); +} + +/* mov r16 to m16 */ +emitterT void eMOV16RtoM(uptr to, x86IntRegType from ) +{ + write8( 0x66 ); + RexR(0,from); + write8( 0x89 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* mov m16 to r16 */ +emitterT void eMOV16MtoR( x86IntRegType to, uptr from ) +{ + write8( 0x66 ); + RexR(0,to); + write8( 0x8B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void eMOV16RmtoR( x86IntRegType to, x86IntRegType from) +{ + write8( 0x66 ); + RexRB(0,to,from); + write8( 0x8B ); + WriteRmOffsetFrom(to, from, 0); +} + +emitterT void eMOV16RmtoROffset( x86IntRegType to, x86IntRegType from, int offset ) +{ + write8( 0x66 ); + RexRB(0,to,from); + write8( 0x8B ); + WriteRmOffsetFrom(to, from, offset); +} + +emitterT void eMOV16RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale ) +{ + write8(0x66); + RexRXB(0,to,from1,0); + write8( 0x8B ); + ModRM( 0, to, SIB ); + SibSB( scale, from1, SIBDISP); + write32(from2); +} + +emitterT void eMOV16RtoRm(x86IntRegType to, x86IntRegType from) +{ + write8( 0x66 ); + RexRB(0,from,to); + write8( 0x89 ); + ModRM( 0, from, to ); +} + +/* mov imm16 to m16 */ +emitterT void eMOV16ItoM( uptr to, u16 from ) +{ + write8( 0x66 ); + write8( 0xC7 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 6) ); + write16( from ); +} + +/* mov r16 to [r32][r32*scale] */ +emitterT void eMOV16RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale) { + write8( 0x66 ); + RexRXB(0,to,from2,from); + write8( 0x89 ); + ModRM( 0, to, 0x4 ); + SibSB(scale, from2, from ); +} + +emitterT void eMOV16ItoR( x86IntRegType to, u16 from ) +{ + RexB(0, to); + write16( 0xB866 | ((to & 0x7)<<8) ); + write16( from ); +} + +// mov imm16 to [r16+off] +emitterT void eMOV16ItoRmOffset( x86IntRegType to, u16 from, u32 offset) +{ + write8(0x66); + RexB(0,to); + write8( 0xC7 ); + WriteRmOffset(to, offset); + write16(from); +} + +// mov r16 to [r16+off] +emitterT void eMOV16RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset) +{ + write8(0x66); + RexRB(0,from,to); + write8( 0x89 ); + WriteRmOffsetFrom(from, to, offset); +} + +/* mov r8 to m8 */ +emitterT void eMOV8RtoM( uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x88 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* mov m8 to r8 */ +emitterT void eMOV8MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x8A ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* mov [r32] to r8 */ +emitterT void eMOV8RmtoR(x86IntRegType to, x86IntRegType from) +{ + RexRB(0,to,from); + write8( 0x8A ); + WriteRmOffsetFrom(to, from, 0); +} + +emitterT void eMOV8RmtoROffset(x86IntRegType to, x86IntRegType from, int offset) +{ + RexRB(0,to,from); + write8( 0x8A ); + WriteRmOffsetFrom(to, from, offset); +} + +emitterT void eMOV8RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale ) +{ + RexRXB(0,to,from1,0); + write8( 0x8A ); + ModRM( 0, to, SIB ); + SibSB( scale, from1, SIBDISP); + write32(from2); +} + +emitterT void eMOV8RtoRm(x86IntRegType to, x86IntRegType from) +{ + RexRB(0,from,to); + write8( 0x88 ); + WriteRmOffsetFrom(from, to, 0); +} + +/* mov imm8 to m8 */ +emitterT void eMOV8ItoM( uptr to, u8 from ) +{ + write8( 0xC6 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); +} + +// mov imm8 to r8 +emitterT void eMOV8ItoR( x86IntRegType to, u8 from ) +{ + RexB(0, to); + write8( 0xB0 | (to & 0x7) ); + write8( from ); +} + +// mov imm8 to [r8+off] +emitterT void eMOV8ItoRmOffset( x86IntRegType to, u8 from, int offset) +{ + assert( to != ESP ); + RexB(0,to); + write8( 0xC6 ); + WriteRmOffset(to,offset); + write8(from); +} + +// mov r8 to [r8+off] +emitterT void eMOV8RtoRmOffset( x86IntRegType to, x86IntRegType from, int offset) +{ + assert( to != ESP ); + RexRB(0,from,to); + write8( 0x88 ); + WriteRmOffsetFrom(from,to,offset); +} + +/* movsx r8 to r32 */ +emitterT void eMOVSX32R8toR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xBE0F ); + ModRM( 3, to, from ); +} + +emitterT void eMOVSX32Rm8toR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xBE0F ); + ModRM( 0, to, from ); +} + +emitterT void eMOVSX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset ) +{ + RexRB(0,to,from); + write16( 0xBE0F ); + WriteRmOffsetFrom(to,from,offset); +} + +/* movsx m8 to r32 */ +emitterT void eMOVSX32M8toR( x86IntRegType to, u32 from ) +{ + RexR(0,to); + write16( 0xBE0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* movsx r16 to r32 */ +emitterT void eMOVSX32R16toR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xBF0F ); + ModRM( 3, to, from ); +} + +emitterT void eMOVSX32Rm16toR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xBF0F ); + ModRM( 0, to, from ); +} + +emitterT void eMOVSX32Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset ) +{ + RexRB(0,to,from); + write16( 0xBF0F ); + WriteRmOffsetFrom(to,from,offset); +} + +/* movsx m16 to r32 */ +emitterT void eMOVSX32M16toR( x86IntRegType to, u32 from ) +{ + RexR(0,to); + write16( 0xBF0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* movzx r8 to r32 */ +emitterT void eMOVZX32R8toR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xB60F ); + ModRM( 3, to, from ); +} + +emitterT void eMOVZX32Rm8toR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xB60F ); + ModRM( 0, to, from ); +} + +emitterT void eMOVZX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset ) +{ + RexRB(0,to,from); + write16( 0xB60F ); + WriteRmOffsetFrom(to,from,offset); +} + +/* movzx m8 to r32 */ +emitterT void eMOVZX32M8toR( x86IntRegType to, u32 from ) +{ + RexR(0,to); + write16( 0xB60F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* movzx r16 to r32 */ +emitterT void eMOVZX32R16toR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xB70F ); + ModRM( 3, to, from ); +} + +emitterT void eMOVZX32Rm16toR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xB70F ); + ModRM( 0, to, from ); +} + +emitterT void eMOVZX32Rm16toROffset( x86IntRegType to, x86IntRegType from, int offset ) +{ + RexRB(0,to,from); + write16( 0xB70F ); + WriteRmOffsetFrom(to,from,offset); +} + +/* movzx m16 to r32 */ +emitterT void eMOVZX32M16toR( x86IntRegType to, u32 from ) +{ + RexR(0,to); + write16( 0xB70F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* cmovbe r32 to r32 */ +emitterT void eCMOVBE32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x46, to, from ); +} + +/* cmovbe m32 to r32*/ +emitterT void eCMOVBE32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x46, to, from ); +} + +/* cmovb r32 to r32 */ +emitterT void eCMOVB32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x42, to, from ); +} + +/* cmovb m32 to r32*/ +emitterT void eCMOVB32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x42, to, from ); +} + +/* cmovae r32 to r32 */ +emitterT void eCMOVAE32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x43, to, from ); +} + +/* cmovae m32 to r32*/ +emitterT void eCMOVAE32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x43, to, from ); +} + +/* cmova r32 to r32 */ +emitterT void eCMOVA32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x47, to, from ); +} + +/* cmova m32 to r32*/ +emitterT void eCMOVA32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x47, to, from ); +} + +/* cmovo r32 to r32 */ +emitterT void eCMOVO32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x40, to, from ); +} + +/* cmovo m32 to r32 */ +emitterT void eCMOVO32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x40, to, from ); +} + +/* cmovp r32 to r32 */ +emitterT void eCMOVP32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x4A, to, from ); +} + +/* cmovp m32 to r32 */ +emitterT void eCMOVP32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x4A, to, from ); +} + +/* cmovs r32 to r32 */ +emitterT void eCMOVS32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x48, to, from ); +} + +/* cmovs m32 to r32 */ +emitterT void eCMOVS32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x48, to, from ); +} + +/* cmovno r32 to r32 */ +emitterT void eCMOVNO32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x41, to, from ); +} + +/* cmovno m32 to r32 */ +emitterT void eCMOVNO32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x41, to, from ); +} + +/* cmovnp r32 to r32 */ +emitterT void eCMOVNP32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x4B, to, from ); +} + +/* cmovnp m32 to r32 */ +emitterT void eCMOVNP32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x4B, to, from ); +} + +/* cmovns r32 to r32 */ +emitterT void eCMOVNS32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x49, to, from ); +} + +/* cmovns m32 to r32 */ +emitterT void eCMOVNS32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x49, to, from ); +} + +/* cmovne r32 to r32 */ +emitterT void eCMOVNE32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x45, to, from ); +} + +/* cmovne m32 to r32*/ +emitterT void eCMOVNE32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x45, to, from ); +} + +/* cmove r32 to r32*/ +emitterT void eCMOVE32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x44, to, from ); +} + +/* cmove m32 to r32*/ +emitterT void eCMOVE32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x44, to, from ); +} + +/* cmovg r32 to r32*/ +emitterT void eCMOVG32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x4F, to, from ); +} + +/* cmovg m32 to r32*/ +emitterT void eCMOVG32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x4F, to, from ); +} + +/* cmovge r32 to r32*/ +emitterT void eCMOVGE32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x4D, to, from ); +} + +/* cmovge m32 to r32*/ +emitterT void eCMOVGE32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x4D, to, from ); +} + +/* cmovl r32 to r32*/ +emitterT void eCMOVL32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x4C, to, from ); +} + +/* cmovl m32 to r32*/ +emitterT void eCMOVL32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x4C, to, from ); +} + +/* cmovle r32 to r32*/ +emitterT void eCMOVLE32RtoR( x86IntRegType to, x86IntRegType from ) +{ + CMOV32RtoR( 0x4E, to, from ); +} + +/* cmovle m32 to r32*/ +emitterT void eCMOVLE32MtoR( x86IntRegType to, uptr from ) +{ + CMOV32MtoR( 0x4E, to, from ); +} + +//////////////////////////////////// +// arithmetic instructions / +//////////////////////////////////// + +/* add imm32 to r64 */ +emitterT void eADD64ItoR( x86IntRegType to, u32 from ) +{ + Rex(1, 0, 0, to >> 3); + if ( to == EAX) { + write8( 0x05 ); + } + else { + write8( 0x81 ); + ModRM( 3, 0, to ); + } + write32( from ); +} + +/* add m64 to r64 */ +emitterT void eADD64MtoR( x86IntRegType to, uptr from ) +{ + Rex(1, to >> 3, 0, 0); + write8( 0x03 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* add r64 to r64 */ +emitterT void eADD64RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(1, from, to); + write8( 0x01 ); + ModRM( 3, from, to ); +} + +/* add imm32 to EAX */ +emitterT void eADD32ItoEAX( u32 from ) +{ + write8( 0x05 ); + write32( from ); +} + +/* add imm32 to r32 */ +emitterT void eADD32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0, to); + if(from < 0x80) + { + write8( 0x83 ); + ModRM( 3, 0, to ); + write8( from ); + } + else + { + if ( to == EAX ) { + eADD32ItoEAX(from); + } + else { + write8( 0x81 ); + ModRM( 3, 0, to ); + write32( from ); + } + } +} + +/* add imm32 to m32 */ +emitterT void eADD32ItoM( uptr to, u32 from ) +{ + /*if(from < 0x80) // crashes games in 64bit build; TODO: figure out why. + { + write8( 0x83 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 8) ); + write8( from ); + } + else*/ + { + write8( 0x81 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); + } +} + +// add imm32 to [r32+off] +emitterT void eADD32ItoRmOffset( x86IntRegType to, u32 from, s32 offset) +{ + RexB(0,to); + if(from < 0x80) + { + write8( 0x83 ); + WriteRmOffset(to,offset); + write8(from); + } + else + { + write8( 0x81 ); + WriteRmOffset(to,offset); + write32(from); + } +} + +/* add r32 to r32 */ +emitterT void eADD32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0, from, to); + write8( 0x01 ); + ModRM( 3, from, to ); +} + +/* add r32 to m32 */ +emitterT void eADD32RtoM(uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x01 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* add m32 to r32 */ +emitterT void eADD32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x03 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// add r16 to r16 +emitterT void eADD16RtoR( x86IntRegType to , x86IntRegType from ) +{ + write8(0x66); + RexRB(0,to,from); + write8( 0x03 ); + ModRM( 3, to, from ); +} + +/* add imm16 to r16 */ +emitterT void eADD16ItoR( x86IntRegType to, u16 from ) +{ + write8( 0x66 ); + RexB(0,to); + + if ( to == EAX) + { + write8( 0x05 ); + write16( from ); + } + else if(from < 0x80) + { + write8( 0x83 ); + ModRM( 3, 0, to ); + write8((u8)from ); + } + else + { + write8( 0x81 ); + ModRM( 3, 0, to ); + write16( from ); + } +} + +/* add imm16 to m16 */ +emitterT void eADD16ItoM( uptr to, u16 from ) +{ + write8( 0x66 ); + if(from < 0x80) + { + write8( 0x83 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 6) ); + write8((u8)from ); + } + else + { + write8( 0x81 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 6) ); + write16( from ); + } +} + +/* add r16 to m16 */ +emitterT void eADD16RtoM(uptr to, x86IntRegType from ) +{ + write8( 0x66 ); + RexR(0,from); + write8( 0x01 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* add m16 to r16 */ +emitterT void eADD16MtoR( x86IntRegType to, uptr from ) +{ + write8( 0x66 ); + RexR(0,to); + write8( 0x03 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// add m8 to r8 +emitterT void eADD8MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x02 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* adc imm32 to r32 */ +emitterT void eADC32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0,to); + if ( to == EAX ) { + write8( 0x15 ); + } + else { + write8( 0x81 ); + ModRM( 3, 2, to ); + } + write32( from ); +} + +/* adc imm32 to m32 */ +emitterT void eADC32ItoM( uptr to, u32 from ) +{ + write8( 0x81 ); + ModRM( 0, 2, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +/* adc r32 to r32 */ +emitterT void eADC32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,from,to); + write8( 0x11 ); + ModRM( 3, from, to ); +} + +/* adc m32 to r32 */ +emitterT void eADC32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x13 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// adc r32 to m32 +emitterT void eADC32RtoM( uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x11 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* inc r32 */ +emitterT void eINC32R( x86IntRegType to ) +{ + write8( 0x40 + to ); +} + +/* inc m32 */ +emitterT void eINC32M( u32 to ) +{ + write8( 0xFF ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* inc r16 */ +emitterT void eINC16R( x86IntRegType to ) +{ + write8( 0x66 ); + write8( 0x40 + to ); +} + +/* inc m16 */ +emitterT void eINC16M( u32 to ) +{ + write8( 0x66 ); + write8( 0xFF ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 4) ); +} + + +/* sub imm32 to r64 */ +emitterT void eSUB64ItoR( x86IntRegType to, u32 from ) +{ + RexB(1, to); + if ( to == EAX ) { + write8( 0x2D ); + } + else { + write8( 0x81 ); + ModRM( 3, 5, to ); + } + write32( from ); +} + +/* sub r64 to r64 */ +emitterT void eSUB64RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(1, from, to); + write8( 0x29 ); + ModRM( 3, from, to ); +} + +/* sub m64 to r64 */ +emitterT void eSUB64MtoR( x86IntRegType to, uptr from ) +{ + RexR(1, to); + write8( 0x2B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* sub imm32 to r32 */ +emitterT void eSUB32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0,to); + if ( to == EAX ) { + write8( 0x2D ); + } + else { + write8( 0x81 ); + ModRM( 3, 5, to ); + } + write32( from ); +} + +/* sub imm32 to m32 */ +emitterT void eSUB32ItoM( uptr to, u32 from ) +{ + write8( 0x81 ); + ModRM( 0, 5, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +/* sub r32 to r32 */ +emitterT void eSUB32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0, from, to); + write8( 0x29 ); + ModRM( 3, from, to ); +} + +/* sub m32 to r32 */ +emitterT void eSUB32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x2B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// sub r32 to m32 +emitterT void eSUB32RtoM( uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x29 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +// sub r16 to r16 +emitterT void eSUB16RtoR( x86IntRegType to, u16 from ) +{ + write8(0x66); + RexRB(0,to,from); + write8( 0x2b ); + ModRM( 3, to, from ); +} + +/* sub imm16 to r16 */ +emitterT void eSUB16ItoR( x86IntRegType to, u16 from ) { + write8( 0x66 ); + RexB(0,to); + if ( to == EAX ) { + write8( 0x2D ); + } + else { + write8( 0x81 ); + ModRM( 3, 5, to ); + } + write16( from ); +} + +/* sub imm16 to m16 */ +emitterT void eSUB16ItoM( uptr to, u16 from ) { + write8( 0x66 ); + write8( 0x81 ); + ModRM( 0, 5, DISP32 ); + write32( MEMADDR(to, 6) ); + write16( from ); +} + +/* sub m16 to r16 */ +emitterT void eSUB16MtoR( x86IntRegType to, uptr from ) { + write8( 0x66 ); + RexR(0,to); + write8( 0x2B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* sbb r64 to r64 */ +emitterT void eSBB64RtoR( x86IntRegType to, x86IntRegType from ) { + RexRB(1, from,to); + write8( 0x19 ); + ModRM( 3, from, to ); +} + +/* sbb imm32 to r32 */ +emitterT void eSBB32ItoR( x86IntRegType to, u32 from ) { + RexB(0,to); + if ( to == EAX ) { + write8( 0x1D ); + } + else { + write8( 0x81 ); + ModRM( 3, 3, to ); + } + write32( from ); +} + +/* sbb imm32 to m32 */ +emitterT void eSBB32ItoM( uptr to, u32 from ) { + write8( 0x81 ); + ModRM( 0, 3, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +/* sbb r32 to r32 */ +emitterT void eSBB32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,from,to); + write8( 0x19 ); + ModRM( 3, from, to ); +} + +/* sbb m32 to r32 */ +emitterT void eSBB32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x1B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* sbb r32 to m32 */ +emitterT void eSBB32RtoM( uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x19 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* dec r32 */ +emitterT void eDEC32R( x86IntRegType to ) +{ + write8( 0x48 + to ); +} + +/* dec m32 */ +emitterT void eDEC32M( u32 to ) +{ + write8( 0xFF ); + ModRM( 0, 1, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* dec r16 */ +emitterT void eDEC16R( x86IntRegType to ) +{ + write8( 0x66 ); + write8( 0x48 + to ); +} + +/* dec m16 */ +emitterT void eDEC16M( u32 to ) +{ + write8( 0x66 ); + write8( 0xFF ); + ModRM( 0, 1, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* mul eax by r32 to edx:eax */ +emitterT void eMUL32R( x86IntRegType from ) +{ + RexB(0,from); + write8( 0xF7 ); + ModRM( 3, 4, from ); +} + +/* imul eax by r32 to edx:eax */ +emitterT void eIMUL32R( x86IntRegType from ) +{ + RexB(0,from); + write8( 0xF7 ); + ModRM( 3, 5, from ); +} + +/* mul eax by m32 to edx:eax */ +emitterT void eMUL32M( u32 from ) +{ + write8( 0xF7 ); + ModRM( 0, 4, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* imul eax by m32 to edx:eax */ +emitterT void eIMUL32M( u32 from ) +{ + write8( 0xF7 ); + ModRM( 0, 5, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* imul r32 by r32 to r32 */ +emitterT void eIMUL32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write16( 0xAF0F ); + ModRM( 3, to, from ); +} + +/* div eax by r32 to edx:eax */ +emitterT void eDIV32R( x86IntRegType from ) +{ + RexB(0,from); + write8( 0xF7 ); + ModRM( 3, 6, from ); +} + +/* idiv eax by r32 to edx:eax */ +emitterT void eIDIV32R( x86IntRegType from ) +{ + RexB(0,from); + write8( 0xF7 ); + ModRM( 3, 7, from ); +} + +/* div eax by m32 to edx:eax */ +emitterT void eDIV32M( u32 from ) +{ + write8( 0xF7 ); + ModRM( 0, 6, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* idiv eax by m32 to edx:eax */ +emitterT void eIDIV32M( u32 from ) +{ + write8( 0xF7 ); + ModRM( 0, 7, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +//////////////////////////////////// +// shifting instructions / +//////////////////////////////////// + +/* shl imm8 to r64 */ +emitterT void eSHL64ItoR( x86IntRegType to, u8 from ) +{ + RexB(1, to); + if ( from == 1 ) + { + write8( 0xD1 ); + ModRM( 3, 4, to ); + return; + } + write8( 0xC1 ); + ModRM( 3, 4, to ); + write8( from ); +} + +/* shl cl to r64 */ +emitterT void eSHL64CLtoR( x86IntRegType to ) +{ + RexB(1, to); + write8( 0xD3 ); + ModRM( 3, 4, to ); +} + +/* shr imm8 to r64 */ +emitterT void eSHR64ItoR( x86IntRegType to, u8 from ) +{ + RexB(1,to); + if ( from == 1 ) { + write8( 0xD1 ); + ModRM( 3, 5, to ); + return; + } + write8( 0xC1 ); + ModRM( 3, 5, to ); + write8( from ); +} + +/* shr cl to r64 */ +emitterT void eSHR64CLtoR( x86IntRegType to ) +{ + RexB(1, to); + write8( 0xD3 ); + ModRM( 3, 5, to ); +} + +/* shl imm8 to r32 */ +emitterT void eSHL32ItoR( x86IntRegType to, u8 from ) +{ + RexB(0, to); + if ( from == 1 ) + { + write8( 0xD1 ); + write8( 0xE0 | (to & 0x7) ); + return; + } + write8( 0xC1 ); + ModRM( 3, 4, to ); + write8( from ); +} + +/* shl imm8 to m32 */ +emitterT void eSHL32ItoM( uptr to, u8 from ) +{ + if ( from == 1 ) + { + write8( 0xD1 ); + ModRM( 0, 4, DISP32 ); + write32( MEMADDR(to, 4) ); + } + else + { + write8( 0xC1 ); + ModRM( 0, 4, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); + } +} + +/* shl cl to r32 */ +emitterT void eSHL32CLtoR( x86IntRegType to ) +{ + RexB(0,to); + write8( 0xD3 ); + ModRM( 3, 4, to ); +} + +// shl imm8 to r16 +emitterT void eSHL16ItoR( x86IntRegType to, u8 from ) +{ + write8(0x66); + RexB(0,to); + if ( from == 1 ) + { + write8( 0xD1 ); + write8( 0xE0 | (to & 0x7) ); + return; + } + write8( 0xC1 ); + ModRM( 3, 4, to ); + write8( from ); +} + +// shl imm8 to r8 +emitterT void eSHL8ItoR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + if ( from == 1 ) + { + write8( 0xD0 ); + write8( 0xE0 | (to & 0x7) ); + return; + } + write8( 0xC0 ); + ModRM( 3, 4, to ); + write8( from ); +} + +/* shr imm8 to r32 */ +emitterT void eSHR32ItoR( x86IntRegType to, u8 from ) { + RexB(0,to); + if ( from == 1 ) + { + write8( 0xD1 ); + write8( 0xE8 | (to & 0x7) ); + } + else + { + write8( 0xC1 ); + ModRM( 3, 5, to ); + write8( from ); + } +} + +/* shr imm8 to m32 */ +emitterT void eSHR32ItoM( uptr to, u8 from ) +{ + if ( from == 1 ) + { + write8( 0xD1 ); + ModRM( 0, 5, DISP32 ); + write32( MEMADDR(to, 4) ); + } + else + { + write8( 0xC1 ); + ModRM( 0, 5, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); + } +} + +/* shr cl to r32 */ +emitterT void eSHR32CLtoR( x86IntRegType to ) +{ + RexB(0,to); + write8( 0xD3 ); + ModRM( 3, 5, to ); +} + +// shr imm8 to r16 +emitterT void eSHR16ItoR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + if ( from == 1 ) + { + write8( 0xD1 ); + ModRM( 3, 5, to ); + } + else + { + write8( 0xC1 ); + ModRM( 3, 5, to ); + write8( from ); + } +} + +// shr imm8 to r8 +emitterT void eSHR8ItoR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + if ( from == 1 ) + { + write8( 0xD0 ); + write8( 0xE8 | (to & 0x7) ); + } + else + { + write8( 0xC0 ); + ModRM( 3, 5, to ); + write8( from ); + } +} + +/* sar imm8 to r64 */ +emitterT void eSAR64ItoR( x86IntRegType to, u8 from ) +{ + RexB(1,to); + if ( from == 1 ) + { + write8( 0xD1 ); + ModRM( 3, 7, to ); + return; + } + write8( 0xC1 ); + ModRM( 3, 7, to ); + write8( from ); +} + +/* sar cl to r64 */ +emitterT void eSAR64CLtoR( x86IntRegType to ) +{ + RexB(1, to); + write8( 0xD3 ); + ModRM( 3, 7, to ); +} + +/* sar imm8 to r32 */ +emitterT void eSAR32ItoR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + if ( from == 1 ) + { + write8( 0xD1 ); + ModRM( 3, 7, to ); + return; + } + write8( 0xC1 ); + ModRM( 3, 7, to ); + write8( from ); +} + +/* sar imm8 to m32 */ +emitterT void eSAR32ItoM( uptr to, u8 from ) +{ + write8( 0xC1 ); + ModRM( 0, 7, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); +} + +/* sar cl to r32 */ +emitterT void eSAR32CLtoR( x86IntRegType to ) +{ + RexB(0,to); + write8( 0xD3 ); + ModRM( 3, 7, to ); +} + +// sar imm8 to r16 +emitterT void eSAR16ItoR( x86IntRegType to, u8 from ) +{ + write8(0x66); + RexB(0,to); + if ( from == 1 ) + { + write8( 0xD1 ); + ModRM( 3, 7, to ); + return; + } + write8( 0xC1 ); + ModRM( 3, 7, to ); + write8( from ); +} + +emitterT void eROR32ItoR( x86IntRegType to,u8 from ) +{ + RexB(0,to); + if ( from == 1 ) { + write8( 0xd1 ); + write8( 0xc8 | to ); + } + else + { + write8( 0xc1 ); + write8( 0xc8 | to ); + write8( from ); + } +} + +emitterT void eRCR32ItoR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + if ( from == 1 ) { + write8( 0xd1 ); + ModRM(3, 3, to); + } + else + { + write8( 0xc1 ); + ModRM(3, 3, to); + write8( from ); + } +} + +emitterT void eRCR32ItoM( uptr to, u8 from ) +{ + RexB(0,to); + if ( from == 1 ) { + write8( 0xd1 ); + ModRM( 0, 3, DISP32 ); + write32( MEMADDR(to, 8) ); + } + else + { + write8( 0xc1 ); + ModRM( 0, 3, DISP32 ); + write32( MEMADDR(to, 8) ); + write8( from ); + } +} + +// shld imm8 to r32 +emitterT void eSHLD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) +{ + RexRB(0,from,to); + write8( 0x0F ); + write8( 0xA4 ); + ModRM( 3, from, to ); + write8( shift ); +} + +// shrd imm8 to r32 +emitterT void eSHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) +{ + RexRB(0,from,to); + write8( 0x0F ); + write8( 0xAC ); + ModRM( 3, from, to ); + write8( shift ); +} + +//////////////////////////////////// +// logical instructions / +//////////////////////////////////// + +/* or imm32 to r32 */ +emitterT void eOR64ItoR( x86IntRegType to, u32 from ) +{ + RexB(1, to); + if ( to == EAX ) { + write8( 0x0D ); + } + else { + write8( 0x81 ); + ModRM( 3, 1, to ); + } + write32( from ); +} + +/* or m64 to r64 */ +emitterT void eOR64MtoR( x86IntRegType to, uptr from ) +{ + RexR(1, to); + write8( 0x0B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* or r64 to r64 */ +emitterT void eOR64RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(1, from, to); + write8( 0x09 ); + ModRM( 3, from, to ); +} + +// or r32 to m64 +emitterT void eOR64RtoM(uptr to, x86IntRegType from ) +{ + RexR(1,from); + write8( 0x09 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* or imm32 to r32 */ +emitterT void eOR32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0,to); + if ( to == EAX ) { + write8( 0x0D ); + } + else { + write8( 0x81 ); + ModRM( 3, 1, to ); + } + write32( from ); +} + +/* or imm32 to m32 */ +emitterT void eOR32ItoM(uptr to, u32 from ) +{ + write8( 0x81 ); + ModRM( 0, 1, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +/* or r32 to r32 */ +emitterT void eOR32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,from,to); + write8( 0x09 ); + ModRM( 3, from, to ); +} + +/* or r32 to m32 */ +emitterT void eOR32RtoM(uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x09 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* or m32 to r32 */ +emitterT void eOR32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x0B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// or r16 to r16 +emitterT void eOR16RtoR( x86IntRegType to, x86IntRegType from ) +{ + write8(0x66); + RexRB(0,from,to); + write8( 0x09 ); + ModRM( 3, from, to ); +} + +// or imm16 to r16 +emitterT void eOR16ItoR( x86IntRegType to, u16 from ) +{ + write8(0x66); + RexB(0,to); + if ( to == EAX ) { + write8( 0x0D ); + } + else { + write8( 0x81 ); + ModRM( 3, 1, to ); + } + write16( from ); +} + +// or imm16 to m316 +emitterT void eOR16ItoM( uptr to, u16 from ) +{ + write8(0x66); + write8( 0x81 ); + ModRM( 0, 1, DISP32 ); + write32( MEMADDR(to, 6) ); + write16( from ); +} + +/* or m16 to r16 */ +emitterT void eOR16MtoR( x86IntRegType to, uptr from ) +{ + write8(0x66); + RexR(0,to); + write8( 0x0B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// or r16 to m16 +emitterT void eOR16RtoM( uptr to, x86IntRegType from ) +{ + write8(0x66); + RexR(0,from); + write8( 0x09 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +// or r8 to r8 +emitterT void eOR8RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,from,to); + write8( 0x08 ); + ModRM( 3, from, to ); +} + +// or r8 to m8 +emitterT void eOR8RtoM( uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x08 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +// or imm8 to m8 +emitterT void eOR8ItoM( uptr to, u8 from ) +{ + write8( 0x80 ); + ModRM( 0, 1, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); +} + +// or m8 to r8 +emitterT void eOR8MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x0A ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* xor imm32 to r64 */ +emitterT void eXOR64ItoR( x86IntRegType to, u32 from ) +{ + RexB(1,to); + if ( to == EAX ) { + write8( 0x35 ); + } else { + write8( 0x81 ); + ModRM( 3, 6, to ); + } + write32( from ); +} + +/* xor r64 to r64 */ +emitterT void eXOR64RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(1, from, to); + write8( 0x31 ); + ModRM( 3, from, to ); +} + +/* xor m64 to r64 */ +emitterT void eXOR64MtoR( x86IntRegType to, uptr from ) +{ + RexR(1, to); + write8( 0x33 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* xor r64 to m64 */ +emitterT void eXOR64RtoM( uptr to, x86IntRegType from ) +{ + RexR(1,from); + write8( 0x31 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* xor imm32 to r32 */ +emitterT void eXOR32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0,to); + if ( to == EAX ) { + write8( 0x35 ); + } + else { + write8( 0x81 ); + ModRM( 3, 6, to ); + } + write32( from ); +} + +/* xor imm32 to m32 */ +emitterT void eXOR32ItoM( uptr to, u32 from ) +{ + write8( 0x81 ); + ModRM( 0, 6, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +/* xor r32 to r32 */ +emitterT void eXOR32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,from,to); + write8( 0x31 ); + ModRM( 3, from, to ); +} + +/* xor r16 to r16 */ +emitterT void eXOR16RtoR( x86IntRegType to, x86IntRegType from ) +{ + write8( 0x66 ); + RexRB(0,from,to); + write8( 0x31 ); + ModRM( 3, from, to ); +} + +/* xor r32 to m32 */ +emitterT void eXOR32RtoM( uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x31 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* xor m32 to r32 */ +emitterT void eXOR32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x33 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// xor imm16 to r16 +emitterT void eXOR16ItoR( x86IntRegType to, u16 from ) +{ + write8(0x66); + RexB(0,to); + if ( to == EAX ) { + write8( 0x35 ); + } + else { + write8( 0x81 ); + ModRM( 3, 6, to ); + } + write16( from ); +} + +// xor r16 to m16 +emitterT void eXOR16RtoM( uptr to, x86IntRegType from ) +{ + write8(0x66); + RexR(0,from); + write8( 0x31 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* and imm32 to r64 */ +emitterT void eAND64I32toR( x86IntRegType to, u32 from ) +{ + RexB(1, to); + if ( to == EAX ) { + write8( 0x25 ); + } else { + write8( 0x81 ); + ModRM( 3, 0x4, to ); + } + write32( from ); +} + +/* and m64 to r64 */ +emitterT void eAND64MtoR( x86IntRegType to, uptr from ) +{ + RexR(1, to); + write8( 0x23 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* and r64 to m64 */ +emitterT void eAND64RtoM( uptr to, x86IntRegType from ) +{ + RexR(1, from); + write8( 0x21 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* and r64 to r64 */ +emitterT void eAND64RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(1, from, to); + write8( 0x21 ); + ModRM( 3, from, to ); +} + +/* and imm32 to m64 */ +emitterT void eAND64I32toM( uptr to, u32 from ) +{ + Rex(1,0,0,0); + write8( 0x81 ); + ModRM( 0, 0x4, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +/* and imm32 to r32 */ +emitterT void eAND32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0,to); + if(from < 0x80) { + eAND32I8toR(to, (u8)from); + } + else { + if ( to == EAX ) { + write8( 0x25 ); + } + else { + write8( 0x81 ); + ModRM( 3, 0x4, to ); + } + write32( from ); + } +} + +/* and sign ext imm8 to r32 */ +emitterT void eAND32I8toR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + write8( 0x83 ); + ModRM( 3, 0x4, to ); + write8( from ); +} + +/* and imm32 to m32 */ +emitterT void eAND32ItoM( uptr to, u32 from ) +{ + if(from < 0x80) { + eAND32I8toM(to, (u8)from); + } + else { + write8( 0x81 ); + ModRM( 0, 0x4, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); + } +} + + +/* and sign ext imm8 to m32 */ +emitterT void eAND32I8toM( uptr to, u8 from ) +{ + write8( 0x83 ); + ModRM( 0, 0x4, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); +} + +/* and r32 to r32 */ +emitterT void eAND32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,from,to); + write8( 0x21 ); + ModRM( 3, from, to ); +} + +/* and r32 to m32 */ +emitterT void eAND32RtoM( uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x21 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* and m32 to r32 */ +emitterT void eAND32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x23 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// and r16 to r16 +emitterT void eAND16RtoR( x86IntRegType to, x86IntRegType from ) +{ + write8(0x66); + RexRB(0,to,from); + write8( 0x23 ); + ModRM( 3, to, from ); +} + +/* and imm16 to r16 */ +emitterT void eAND16ItoR( x86IntRegType to, u16 from ) +{ + write8(0x66); + RexB(0,to); + + if ( to == EAX ) { + write8( 0x25 ); + write16( from ); + } + else if ( from < 0x80 ) { + write8( 0x83 ); + ModRM( 3, 0x4, to ); + write8((u8)from ); + } + else { + write8( 0x81 ); + ModRM( 3, 0x4, to ); + write16( from ); + } +} + +/* and imm16 to m16 */ +emitterT void eAND16ItoM( uptr to, u16 from ) +{ + write8(0x66); + if ( from < 0x80 ) { + write8( 0x83 ); + ModRM( 0, 0x4, DISP32 ); + write32( MEMADDR(to, 6) ); + write8((u8)from ); + } + else + { + write8( 0x81 ); + ModRM( 0, 0x4, DISP32 ); + write32( MEMADDR(to, 6) ); + write16( from ); + + } +} + +/* and r16 to m16 */ +emitterT void eAND16RtoM( uptr to, x86IntRegType from ) +{ + write8( 0x66 ); + RexR(0,from); + write8( 0x21 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* and m16 to r16 */ +emitterT void eAND16MtoR( x86IntRegType to, uptr from ) +{ + write8( 0x66 ); + RexR(0,to); + write8( 0x23 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4)); +} + +/* and imm8 to r8 */ +emitterT void eAND8ItoR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + if ( to == EAX ) { + write8( 0x24 ); + } + else { + write8( 0x80 ); + ModRM( 3, 0x4, to ); + } + write8( from ); +} + +/* and imm8 to m8 */ +emitterT void eAND8ItoM( uptr to, u8 from ) +{ + write8( 0x80 ); + ModRM( 0, 0x4, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); +} + +// and r8 to r8 +emitterT void eAND8RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,to,from); + write8( 0x22 ); + ModRM( 3, to, from ); +} + +/* and r8 to m8 */ +emitterT void eAND8RtoM( uptr to, x86IntRegType from ) +{ + RexR(0,from); + write8( 0x20 ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* and m8 to r8 */ +emitterT void eAND8MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x22 ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4)); +} + +/* not r64 */ +emitterT void eNOT64R( x86IntRegType from ) +{ + RexB(1, from); + write8( 0xF7 ); + ModRM( 3, 2, from ); +} + +/* not r32 */ +emitterT void eNOT32R( x86IntRegType from ) +{ + RexB(0,from); + write8( 0xF7 ); + ModRM( 3, 2, from ); +} + +// not m32 +emitterT void eNOT32M( u32 from ) +{ + write8( 0xF7 ); + ModRM( 0, 2, DISP32 ); + write32( MEMADDR(from, 4)); +} + +/* neg r64 */ +emitterT void eNEG64R( x86IntRegType from ) +{ + RexB(1, from); + write8( 0xF7 ); + ModRM( 3, 3, from ); +} + +/* neg r32 */ +emitterT void eNEG32R( x86IntRegType from ) +{ + RexB(0,from); + write8( 0xF7 ); + ModRM( 3, 3, from ); +} + +emitterT void eNEG32M( u32 from ) +{ + write8( 0xF7 ); + ModRM( 0, 3, DISP32 ); + write32( MEMADDR(from, 4)); +} + +/* neg r16 */ +emitterT void eNEG16R( x86IntRegType from ) +{ + write8( 0x66 ); + RexB(0,from); + write8( 0xF7 ); + ModRM( 3, 3, from ); +} + +//////////////////////////////////// +// jump instructions / +//////////////////////////////////// + +emitterT u8* JMP( uptr to ) { + uptr jump = ( x86Ptr[0] - (u8*)to ) - 1; + + if ( jump > 0x7f ) { + assert( to <= 0xffffffff ); + return (u8*)eJMP32( to ); + } + else { + return (u8*)eJMP8( to ); + } +} + +/* jmp rel8 */ +emitterT u8* eJMP8( u8 to ) +{ + write8( 0xEB ); + write8( to ); + return x86Ptr[I] - 1; +} + +/* jmp rel32 */ +emitterT u32* eJMP32( uptr to ) +{ + assert( (sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff ); + write8( 0xE9 ); + write32( to ); + return (u32*)(x86Ptr[I] - 4 ); +} + +/* jmp r32/r64 */ +emitterT void eJMPR( x86IntRegType to ) +{ + RexB(0, to); + write8( 0xFF ); + ModRM( 3, 4, to ); +} + +// jmp m32 +emitterT void eJMP32M( uptr to ) +{ + write8( 0xFF ); + ModRM( 0, 4, DISP32 ); + write32( MEMADDR(to, 4)); +} + +/* jp rel8 */ +emitterT u8* eJP8( u8 to ) { + return J8Rel( 0x7A, to ); +} + +/* jnp rel8 */ +emitterT u8* eJNP8( u8 to ) { + return J8Rel( 0x7B, to ); +} + +/* je rel8 */ +emitterT u8* eJE8( u8 to ) { + return J8Rel( 0x74, to ); +} + +/* jz rel8 */ +emitterT u8* eJZ8( u8 to ) +{ + return J8Rel( 0x74, to ); +} + +/* js rel8 */ +emitterT u8* eJS8( u8 to ) +{ + return J8Rel( 0x78, to ); +} + +/* jns rel8 */ +emitterT u8* eJNS8( u8 to ) +{ + return J8Rel( 0x79, to ); +} + +/* jg rel8 */ +emitterT u8* eJG8( u8 to ) +{ + return J8Rel( 0x7F, to ); +} + +/* jge rel8 */ +emitterT u8* eJGE8( u8 to ) +{ + return J8Rel( 0x7D, to ); +} + +/* jl rel8 */ +emitterT u8* eJL8( u8 to ) +{ + return J8Rel( 0x7C, to ); +} + +/* ja rel8 */ +emitterT u8* eJA8( u8 to ) +{ + return J8Rel( 0x77, to ); +} + +emitterT u8* eJAE8( u8 to ) +{ + return J8Rel( 0x73, to ); +} + +/* jb rel8 */ +emitterT u8* eJB8( u8 to ) +{ + return J8Rel( 0x72, to ); +} + +/* jbe rel8 */ +emitterT u8* eJBE8( u8 to ) +{ + return J8Rel( 0x76, to ); +} + +/* jle rel8 */ +emitterT u8* eJLE8( u8 to ) +{ + return J8Rel( 0x7E, to ); +} + +/* jne rel8 */ +emitterT u8* eJNE8( u8 to ) +{ + return J8Rel( 0x75, to ); +} + +/* jnz rel8 */ +emitterT u8* eJNZ8( u8 to ) +{ + return J8Rel( 0x75, to ); +} + +/* jng rel8 */ +emitterT u8* eJNG8( u8 to ) +{ + return J8Rel( 0x7E, to ); +} + +/* jnge rel8 */ +emitterT u8* eJNGE8( u8 to ) +{ + return J8Rel( 0x7C, to ); +} + +/* jnl rel8 */ +emitterT u8* eJNL8( u8 to ) +{ + return J8Rel( 0x7D, to ); +} + +/* jnle rel8 */ +emitterT u8* eJNLE8( u8 to ) +{ + return J8Rel( 0x7F, to ); +} + +/* jo rel8 */ +emitterT u8* eJO8( u8 to ) +{ + return J8Rel( 0x70, to ); +} + +/* jno rel8 */ +emitterT u8* eJNO8( u8 to ) +{ + return J8Rel( 0x71, to ); +} +/* Untested and slower, use 32bit versions instead +// ja rel16 +emitterT u16* eJA16( u16 to ) +{ +return J16Rel( 0x87, to ); +} + +// jb rel16 +emitterT u16* eJB16( u16 to ) +{ +return J16Rel( 0x82, to ); +} + +// je rel16 +emitterT u16* eJE16( u16 to ) +{ +return J16Rel( 0x84, to ); +} + +// jz rel16 +emitterT u16* eJZ16( u16 to ) +{ +return J16Rel( 0x84, to ); +} +*/ +// jb rel32 +emitterT u32* eJB32( u32 to ) +{ + return J32Rel( 0x82, to ); +} + +/* je rel32 */ +emitterT u32* eJE32( u32 to ) +{ + return J32Rel( 0x84, to ); +} + +/* jz rel32 */ +emitterT u32* eJZ32( u32 to ) +{ + return J32Rel( 0x84, to ); +} + +/* js rel32 */ +emitterT u32* eJS32( u32 to ) +{ + return J32Rel( 0x88, to ); +} + +/* jns rel32 */ +emitterT u32* eJNS32( u32 to ) +{ + return J32Rel( 0x89, to ); +} + +/* jg rel32 */ +emitterT u32* eJG32( u32 to ) +{ + return J32Rel( 0x8F, to ); +} + +/* jge rel32 */ +emitterT u32* eJGE32( u32 to ) +{ + return J32Rel( 0x8D, to ); +} + +/* jl rel32 */ +emitterT u32* eJL32( u32 to ) +{ + return J32Rel( 0x8C, to ); +} + +/* jle rel32 */ +emitterT u32* eJLE32( u32 to ) +{ + return J32Rel( 0x8E, to ); +} + +/* ja rel32 */ +emitterT u32* eJA32( u32 to ) +{ + return J32Rel( 0x87, to ); +} + +/* jae rel32 */ +emitterT u32* eJAE32( u32 to ) +{ + return J32Rel( 0x83, to ); +} + +/* jne rel32 */ +emitterT u32* eJNE32( u32 to ) +{ + return J32Rel( 0x85, to ); +} + +/* jnz rel32 */ +emitterT u32* eJNZ32( u32 to ) +{ + return J32Rel( 0x85, to ); +} + +/* jng rel32 */ +emitterT u32* eJNG32( u32 to ) +{ + return J32Rel( 0x8E, to ); +} + +/* jnge rel32 */ +emitterT u32* eJNGE32( u32 to ) +{ + return J32Rel( 0x8C, to ); +} + +/* jnl rel32 */ +emitterT u32* eJNL32( u32 to ) +{ + return J32Rel( 0x8D, to ); +} + +/* jnle rel32 */ +emitterT u32* eJNLE32( u32 to ) +{ + return J32Rel( 0x8F, to ); +} + +/* jo rel32 */ +emitterT u32* eJO32( u32 to ) +{ + return J32Rel( 0x80, to ); +} + +/* jno rel32 */ +emitterT u32* eJNO32( u32 to ) +{ + return J32Rel( 0x81, to ); +} + + + +/* call func */ +emitterT void eCALLFunc( uptr func ) +{ + func -= ( (uptr)x86Ptr[0] + 5 ); + assert( (sptr)func <= 0x7fffffff && (sptr)func >= -0x7fffffff ); + eCALL32(func); +} + +/* call rel32 */ +emitterT void eCALL32( u32 to ) +{ + write8( 0xE8 ); + write32( to ); +} + +/* call r32 */ +emitterT void eCALL32R( x86IntRegType to ) +{ + write8( 0xFF ); + ModRM( 3, 2, to ); +} + +/* call r64 */ +emitterT void eCALL64R( x86IntRegType to ) +{ + RexB(0, to); + write8( 0xFF ); + ModRM( 3, 2, to ); +} + +/* call m32 */ +emitterT void eCALL32M( u32 to ) +{ + write8( 0xFF ); + ModRM( 0, 2, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +//////////////////////////////////// +// misc instructions / +//////////////////////////////////// + +/* cmp imm32 to r64 */ +emitterT void eCMP64I32toR( x86IntRegType to, u32 from ) +{ + RexB(1, to); + if ( to == EAX ) { + write8( 0x3D ); + } + else { + write8( 0x81 ); + ModRM( 3, 7, to ); + } + write32( from ); +} + +/* cmp m64 to r64 */ +emitterT void eCMP64MtoR( x86IntRegType to, uptr from ) +{ + RexR(1, to); + write8( 0x3B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// cmp r64 to r64 +emitterT void eCMP64RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(1,from,to); + write8( 0x39 ); + ModRM( 3, from, to ); +} + +/* cmp imm32 to r32 */ +emitterT void eCMP32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0,to); + if ( to == EAX ) { + write8( 0x3D ); + } + else { + write8( 0x81 ); + ModRM( 3, 7, to ); + } + write32( from ); +} + +/* cmp imm32 to m32 */ +emitterT void eCMP32ItoM( uptr to, u32 from ) +{ + write8( 0x81 ); + ModRM( 0, 7, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +/* cmp r32 to r32 */ +emitterT void eCMP32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,from,to); + write8( 0x39 ); + ModRM( 3, from, to ); +} + +/* cmp m32 to r32 */ +emitterT void eCMP32MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x3B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// cmp imm8 to [r32] +emitterT void eCMP32I8toRm( x86IntRegType to, u8 from) +{ + RexB(0,to); + write8( 0x83 ); + ModRM( 0, 7, to ); + write8(from); +} + +// cmp imm32 to [r32+off] +emitterT void eCMP32I8toRmOffset8( x86IntRegType to, u8 from, u8 off) +{ + RexB(0,to); + write8( 0x83 ); + ModRM( 1, 7, to ); + write8(off); + write8(from); +} + +// cmp imm8 to [r32] +emitterT void eCMP32I8toM( uptr to, u8 from) +{ + write8( 0x83 ); + ModRM( 0, 7, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); +} + +/* cmp imm16 to r16 */ +emitterT void eCMP16ItoR( x86IntRegType to, u16 from ) +{ + write8( 0x66 ); + RexB(0,to); + if ( to == EAX ) + { + write8( 0x3D ); + } + else + { + write8( 0x81 ); + ModRM( 3, 7, to ); + } + write16( from ); +} + +/* cmp imm16 to m16 */ +emitterT void eCMP16ItoM( uptr to, u16 from ) +{ + write8( 0x66 ); + write8( 0x81 ); + ModRM( 0, 7, DISP32 ); + write32( MEMADDR(to, 6) ); + write16( from ); +} + +/* cmp r16 to r16 */ +emitterT void eCMP16RtoR( x86IntRegType to, x86IntRegType from ) +{ + write8( 0x66 ); + RexRB(0,from,to); + write8( 0x39 ); + ModRM( 3, from, to ); +} + +/* cmp m16 to r16 */ +emitterT void eCMP16MtoR( x86IntRegType to, uptr from ) +{ + write8( 0x66 ); + RexR(0,to); + write8( 0x3B ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// cmp imm8 to r8 +emitterT void eCMP8ItoR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + if ( to == EAX ) + { + write8( 0x3C ); + } + else + { + write8( 0x80 ); + ModRM( 3, 7, to ); + } + write8( from ); +} + +// cmp m8 to r8 +emitterT void eCMP8MtoR( x86IntRegType to, uptr from ) +{ + RexR(0,to); + write8( 0x3A ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* test imm32 to r32 */ +emitterT void eTEST32ItoR( x86IntRegType to, u32 from ) +{ + RexB(0,to); + if ( to == EAX ) + { + write8( 0xA9 ); + } + else + { + write8( 0xF7 ); + ModRM( 3, 0, to ); + } + write32( from ); +} + +emitterT void eTEST32ItoM( uptr to, u32 from ) +{ + write8( 0xF7 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 8) ); + write32( from ); +} + +/* test r32 to r32 */ +emitterT void eTEST32RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0,from,to); + write8( 0x85 ); + ModRM( 3, from, to ); +} + +// test imm32 to [r32] +emitterT void eTEST32ItoRm( x86IntRegType to, u32 from ) +{ + RexB(0,to); + write8( 0xF7 ); + ModRM( 0, 0, to ); + write32(from); +} + +// test imm16 to r16 +emitterT void eTEST16ItoR( x86IntRegType to, u16 from ) +{ + write8(0x66); + RexB(0,to); + if ( to == EAX ) + { + write8( 0xA9 ); + } + else + { + write8( 0xF7 ); + ModRM( 3, 0, to ); + } + write16( from ); +} + +// test r16 to r16 +emitterT void eTEST16RtoR( x86IntRegType to, x86IntRegType from ) +{ + write8(0x66); + RexRB(0,from,to); + write8( 0x85 ); + ModRM( 3, from, to ); +} + +// test r8 to r8 +emitterT void eTEST8RtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0, from, to); + write8( 0x84 ); + ModRM( 3, from, to ); +} + + +// test imm8 to r8 +emitterT void eTEST8ItoR( x86IntRegType to, u8 from ) +{ + RexB(0,to); + if ( to == EAX ) + { + write8( 0xA8 ); + } + else + { + write8( 0xF6 ); + ModRM( 3, 0, to ); + } + write8( from ); +} + +// test imm8 to r8 +emitterT void eTEST8ItoM( uptr to, u8 from ) +{ + write8( 0xF6 ); + ModRM( 0, 0, DISP32 ); + write32( MEMADDR(to, 5) ); + write8( from ); +} + +/* sets r8 */ +emitterT void eSETS8R( x86IntRegType to ) +{ + SET8R( 0x98, to ); +} + +/* setl r8 */ +emitterT void eSETL8R( x86IntRegType to ) +{ + SET8R( 0x9C, to ); +} + +// setge r8 +emitterT void eSETGE8R( x86IntRegType to ) { SET8R(0x9d, to); } +// setg r8 +emitterT void eSETG8R( x86IntRegType to ) { SET8R(0x9f, to); } +// seta r8 +emitterT void eSETA8R( x86IntRegType to ) { SET8R(0x97, to); } +// setae r8 +emitterT void eSETAE8R( x86IntRegType to ) { SET8R(0x99, to); } +/* setb r8 */ +emitterT void eSETB8R( x86IntRegType to ) { SET8R( 0x92, to ); } +/* setb r8 */ +emitterT void eSETNZ8R( x86IntRegType to ) { SET8R( 0x95, to ); } +// setz r8 +emitterT void eSETZ8R( x86IntRegType to ) { SET8R(0x94, to); } +// sete r8 +emitterT void eSETE8R( x86IntRegType to ) { SET8R(0x94, to); } + +/* push imm32 */ +emitterT void ePUSH32I( u32 from ) +{; +write8( 0x68 ); +write32( from ); +} + +/* push r32 */ +emitterT void ePUSH32R( x86IntRegType from ) { write8( 0x50 | from ); } + +/* push m32 */ +emitterT void ePUSH32M( u32 from ) +{ + write8( 0xFF ); + ModRM( 0, 6, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* pop r32 */ +emitterT void ePOP32R( x86IntRegType from ) { write8( 0x58 | from ); } + +/* pushad */ +emitterT void ePUSHA32( void ) { write8( 0x60 ); } + +/* popad */ +emitterT void ePOPA32( void ) { write8( 0x61 ); } + +emitterT void ePUSHR(x86IntRegType from) { ePUSH32R(from); } +emitterT void ePOPR(x86IntRegType from) { ePOP32R(from); } + + +/* pushfd */ +emitterT void ePUSHFD( void ) { write8( 0x9C ); } +/* popfd */ +emitterT void ePOPFD( void ) { write8( 0x9D ); } + +emitterT void eRET( void ) { write8( 0xC3 ); } +emitterT void eRET2( void ) { write16( 0xc3f3 ); } + +emitterT void eCBW( void ) { write16( 0x9866 ); } +emitterT void eCWD( void ) { write8( 0x98 ); } +emitterT void eCDQ( void ) { write8( 0x99 ); } +emitterT void eCWDE() { write8(0x98); } + +emitterT void eLAHF() { write8(0x9f); } +emitterT void eSAHF() { write8(0x9e); } + +emitterT void eBT32ItoR( x86IntRegType to, u8 from ) +{ + write16( 0xBA0F ); + ModRM(3, 4, to); + write8( from ); +} + +emitterT void eBTR32ItoR( x86IntRegType to, u8 from ) +{ + write16( 0xBA0F ); + ModRM(3, 6, to); + write8( from ); +} + +emitterT void eBSRRtoR(x86IntRegType to, x86IntRegType from) +{ + write16( 0xBD0F ); + ModRM( 3, from, to ); +} + +emitterT void eBSWAP32R( x86IntRegType to ) +{ + write8( 0x0F ); + write8( 0xC8 + to ); +} + +// to = from + offset +emitterT void eLEA16RtoR(x86IntRegType to, x86IntRegType from, u16 offset) +{ + write8(0x66); + eLEA32RtoR(to, from, offset); +} + +emitterT void eLEA32RtoR(x86IntRegType to, x86IntRegType from, u32 offset) +{ + RexRB(0,to,from); + write8(0x8d); + + if( (from&7) == ESP ) { + if( offset == 0 ) { + ModRM(1, to, from); + write8(0x24); + } + else if( offset < 128 ) { + ModRM(1, to, from); + write8(0x24); + write8(offset); + } + else { + ModRM(2, to, from); + write8(0x24); + write32(offset); + } + } + else { + if( offset == 0 && from != EBP && from!=ESP ) { + ModRM(0, to, from); + } + else if( offset < 128 ) { + ModRM(1, to, from); + write8(offset); + } + else { + ModRM(2, to, from); + write32(offset); + } + } +} + +// to = from0 + from1 +emitterT void eLEA16RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1) +{ + write8(0x66); + eLEA32RRtoR(to, from0, from1); +} + +emitterT void eLEA32RRtoR(x86IntRegType to, x86IntRegType from0, x86IntRegType from1) +{ + RexRXB(0, to, from0, from1); + write8(0x8d); + + if( (from1&7) == EBP ) { + ModRM(1, to, 4); + ModRM(0, from0, from1); + write8(0); + } + else { + ModRM(0, to, 4); + ModRM(0, from0, from1); + } +} + +// to = from << scale (max is 3) +emitterT void eLEA16RStoR(x86IntRegType to, x86IntRegType from, u32 scale) +{ + write8(0x66); + eLEA32RStoR(to, from, scale); +} + +// Don't inline recursive functions +emitterT void eLEA32RStoR(x86IntRegType to, x86IntRegType from, u32 scale) +{ + if( to == from ) { + eSHL32ItoR(to, scale); + return; + } + + if( from != ESP ) { + RexRXB(0,to,from,0); + write8(0x8d); + ModRM(0, to, 4); + ModRM(scale, from, 5); + write32(0); + } + else { + assert( to != ESP ); + eMOV32RtoR(to, from); + eLEA32RStoR(to, to, scale); + } +} diff --git a/pcsx2/x86/ix86/ix86_3dnow.inl b/pcsx2/x86/ix86/ix86_3dnow.inl new file mode 100644 index 0000000000..5fdcce2347 --- /dev/null +++ b/pcsx2/x86/ix86/ix86_3dnow.inl @@ -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( 0x0E0F ); +} + +emitterT void ePFCMPEQMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0xB0 ); +} + +emitterT void ePFCMPGTMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0xA0 ); +} + +emitterT void ePFCMPGEMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0x90 ); +} + +emitterT void ePFADDMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0x9E ); +} + +emitterT void ePFADDRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0x9E ); +} + +emitterT void ePFSUBMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0x9A ); +} + +emitterT void ePFSUBRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0x9A ); +} + +emitterT void ePFMULMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0xB4 ); +} + +emitterT void ePFMULRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0xB4 ); +} + +emitterT void ePFRCPMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0x96 ); +} + +emitterT void ePFRCPRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0x96 ); +} + +emitterT void ePFRCPIT1RtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0xA6 ); +} + +emitterT void ePFRCPIT2RtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0xB6 ); +} + +emitterT void ePFRSQRTRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0x97 ); +} + +emitterT void ePFRSQIT1RtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0xA7 ); +} + +emitterT void ePF2IDMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0x1D ); +} + +emitterT void ePF2IDRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0x1D ); +} + +emitterT void ePI2FDMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0x0D ); +} + +emitterT void ePI2FDRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0x0D ); +} + +emitterT void ePFMAXMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0xA4 ); +} + +emitterT void ePFMAXRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0xA4 ); +} + +emitterT void ePFMINMtoR( x86IntRegType to, uptr from ) +{ + write16( 0x0F0F ); + ModRM( 0, to, DISP32 ); + write32( from ); + write8( 0x94 ); +} + +emitterT void ePFMINRtoR( x86IntRegType to, x86IntRegType from ) +{ + write16( 0x0F0F ); + ModRM( 3, to, from ); + write8( 0x94 ); +} diff --git a/pcsx2/x86/ix86/ix86_fpu.inl b/pcsx2/x86/ix86/ix86_fpu.inl new file mode 100644 index 0000000000..ae20b6c4ec --- /dev/null +++ b/pcsx2/x86/ix86/ix86_fpu.inl @@ -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( 0xDB ); + ModRM( 0, 0x0, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* fistp m32 from fpu reg stack */ +emitterT void eFISTP32( u32 from ) +{ + write8( 0xDB ); + ModRM( 0, 0x3, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* fld m32 to fpu reg stack */ +emitterT void eFLD32( u32 from ) +{ + write8( 0xD9 ); + ModRM( 0, 0x0, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// fld st(i) +emitterT void eFLD(int st) { write16(0xc0d9+(st<<8)); } +emitterT void eFLD1() { write16(0xe8d9); } +emitterT void eFLDL2E() { write16(0xead9); } + +/* fst m32 from fpu reg stack */ +emitterT void eFST32( u32 to ) +{ + write8( 0xD9 ); + ModRM( 0, 0x2, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +/* fstp m32 from fpu reg stack */ +emitterT void eFSTP32( u32 to ) +{ + write8( 0xD9 ); + ModRM( 0, 0x3, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +// fstp st(i) +emitterT void eFSTP(int st) { write16(0xd8dd+(st<<8)); } + +/* fldcw fpu control word from m16 */ +emitterT void eFLDCW( u32 from ) +{ + write8( 0xD9 ); + ModRM( 0, 0x5, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* fnstcw fpu control word to m16 */ +emitterT void eFNSTCW( u32 to ) +{ + write8( 0xD9 ); + ModRM( 0, 0x7, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +emitterT void eFNSTSWtoAX() { write16(0xE0DF); } +emitterT void eFXAM() { write16(0xe5d9); } +emitterT void eFDECSTP() { write16(0xf6d9); } +emitterT void eFRNDINT() { write16(0xfcd9); } +emitterT void eFXCH(int st) { write16(0xc8d9+(st<<8)); } +emitterT void eF2XM1() { write16(0xf0d9); } +emitterT void eFSCALE() { write16(0xfdd9); } +emitterT void eFPATAN(void) { write16(0xf3d9); } +emitterT void eFSIN(void) { write16(0xfed9); } + +/* fadd ST(src) to fpu reg stack ST(0) */ +emitterT void eFADD32Rto0( x86IntRegType src ) +{ + write8( 0xD8 ); + write8( 0xC0 + src ); +} + +/* fadd ST(0) to fpu reg stack ST(src) */ +emitterT void eFADD320toR( x86IntRegType src ) +{ + write8( 0xDC ); + write8( 0xC0 + src ); +} + +/* fsub ST(src) to fpu reg stack ST(0) */ +emitterT void eFSUB32Rto0( x86IntRegType src ) +{ + write8( 0xD8 ); + write8( 0xE0 + src ); +} + +/* fsub ST(0) to fpu reg stack ST(src) */ +emitterT void eFSUB320toR( x86IntRegType src ) +{ + write8( 0xDC ); + write8( 0xE8 + src ); +} + +/* fsubp -> substract ST(0) from ST(1), store in ST(1) and POP stack */ +emitterT void eFSUBP( void ) +{ + write8( 0xDE ); + write8( 0xE9 ); +} + +/* fmul ST(src) to fpu reg stack ST(0) */ +emitterT void eFMUL32Rto0( x86IntRegType src ) +{ + write8( 0xD8 ); + write8( 0xC8 + src ); +} + +/* fmul ST(0) to fpu reg stack ST(src) */ +emitterT void eFMUL320toR( x86IntRegType src ) +{ + write8( 0xDC ); + write8( 0xC8 + src ); +} + +/* fdiv ST(src) to fpu reg stack ST(0) */ +emitterT void eFDIV32Rto0( x86IntRegType src ) +{ + write8( 0xD8 ); + write8( 0xF0 + src ); +} + +/* fdiv ST(0) to fpu reg stack ST(src) */ +emitterT void eFDIV320toR( x86IntRegType src ) +{ + write8( 0xDC ); + write8( 0xF8 + src ); +} + +emitterT void eFDIV320toRP( x86IntRegType src ) +{ + write8( 0xDE ); + write8( 0xF8 + src ); +} + +/* fadd m32 to fpu reg stack */ +emitterT void eFADD32( u32 from ) +{ + write8( 0xD8 ); + ModRM( 0, 0x0, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* fsub m32 to fpu reg stack */ +emitterT void eFSUB32( u32 from ) +{ + write8( 0xD8 ); + ModRM( 0, 0x4, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* fmul m32 to fpu reg stack */ +emitterT void eFMUL32( u32 from ) +{ + write8( 0xD8 ); + ModRM( 0, 0x1, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* fdiv m32 to fpu reg stack */ +emitterT void eFDIV32( u32 from ) +{ + write8( 0xD8 ); + ModRM( 0, 0x6, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* fabs fpu reg stack */ +emitterT void eFABS( void ) +{ + write16( 0xE1D9 ); +} + +/* fsqrt fpu reg stack */ +emitterT void eFSQRT( void ) +{ + write16( 0xFAD9 ); +} + +/* fchs fpu reg stack */ +emitterT void eFCHS( void ) +{ + write16( 0xE0D9 ); +} + +/* fcomi st, st(i) */ +emitterT void eFCOMI( x86IntRegType src ) +{ + write8( 0xDB ); + write8( 0xF0 + src ); +} + +/* fcomip st, st(i) */ +emitterT void eFCOMIP( x86IntRegType src ) +{ + write8( 0xDF ); + write8( 0xF0 + src ); +} + +/* fucomi st, st(i) */ +emitterT void eFUCOMI( x86IntRegType src ) +{ + write8( 0xDB ); + write8( 0xE8 + src ); +} + +/* fucomip st, st(i) */ +emitterT void eFUCOMIP( x86IntRegType src ) +{ + write8( 0xDF ); + write8( 0xE8 + src ); +} + +/* fcom m32 to fpu reg stack */ +emitterT void eFCOM32( u32 from ) +{ + write8( 0xD8 ); + ModRM( 0, 0x2, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* fcomp m32 to fpu reg stack */ +emitterT void eFCOMP32( u32 from ) +{ + write8( 0xD8 ); + ModRM( 0, 0x3, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +#define FCMOV32( low, high ) \ + { \ + write8( low ); \ + write8( 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 ); } diff --git a/pcsx2/x86/ix86/ix86_mmx.inl b/pcsx2/x86/ix86/ix86_mmx.inl new file mode 100644 index 0000000000..de9365fa3a --- /dev/null +++ b/pcsx2/x86/ix86/ix86_mmx.inl @@ -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( 0x6F0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* movq r64 to m64 */ +emitterT void eMOVQRtoM( uptr to, x86MMXRegType from ) +{ + write16( 0x7F0F ); + ModRM( 0, from, DISP32 ); + write32(MEMADDR(to, 4)); +} + +/* pand r64 to r64 */ +emitterT void ePANDRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xDB0F ); + ModRM( 3, to, from ); +} + +emitterT void ePANDNRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xDF0F ); + ModRM( 3, to, from ); +} + +/* por r64 to r64 */ +emitterT void ePORRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xEB0F ); + ModRM( 3, to, from ); +} + +/* pxor r64 to r64 */ +emitterT void ePXORRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xEF0F ); + ModRM( 3, to, from ); +} + +/* psllq r64 to r64 */ +emitterT void ePSLLQRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xF30F ); + ModRM( 3, to, from ); +} + +/* psllq m64 to r64 */ +emitterT void ePSLLQMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xF30F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* psllq imm8 to r64 */ +emitterT void ePSLLQItoR( x86MMXRegType to, u8 from ) +{ + write16( 0x730F ); + ModRM( 3, 6, to); + write8( from ); +} + +/* psrlq r64 to r64 */ +emitterT void ePSRLQRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xD30F ); + ModRM( 3, to, from ); +} + +/* psrlq m64 to r64 */ +emitterT void ePSRLQMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xD30F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* psrlq imm8 to r64 */ +emitterT void ePSRLQItoR( x86MMXRegType to, u8 from ) +{ + write16( 0x730F ); + ModRM( 3, 2, to); + write8( from ); +} + +/* paddusb r64 to r64 */ +emitterT void ePADDUSBRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xDC0F ); + ModRM( 3, to, from ); +} + +/* paddusb m64 to r64 */ +emitterT void ePADDUSBMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xDC0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* paddusw r64 to r64 */ +emitterT void ePADDUSWRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xDD0F ); + ModRM( 3, to, from ); +} + +/* paddusw m64 to r64 */ +emitterT void ePADDUSWMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xDD0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* paddb r64 to r64 */ +emitterT void ePADDBRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xFC0F ); + ModRM( 3, to, from ); +} + +/* paddb m64 to r64 */ +emitterT void ePADDBMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xFC0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* paddw r64 to r64 */ +emitterT void ePADDWRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xFD0F ); + ModRM( 3, to, from ); +} + +/* paddw m64 to r64 */ +emitterT void ePADDWMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xFD0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* paddd r64 to r64 */ +emitterT void ePADDDRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xFE0F ); + ModRM( 3, to, from ); +} + +/* paddd m64 to r64 */ +emitterT void ePADDDMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xFE0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* emms */ +emitterT void eEMMS() +{ + write16( 0x770F ); +} + +emitterT void ePADDSBRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xEC0F ); + ModRM( 3, to, from ); +} + +emitterT void ePADDSWRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xED0F ); + ModRM( 3, to, from ); +} + +// paddq m64 to r64 (sse2 only?) +emitterT void ePADDQMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xD40F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// paddq r64 to r64 (sse2 only?) +emitterT void ePADDQRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xD40F ); + ModRM( 3, to, from ); +} + +emitterT void ePSUBSBRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xE80F ); + ModRM( 3, to, from ); +} + +emitterT void ePSUBSWRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xE90F ); + ModRM( 3, to, from ); +} + + +emitterT void ePSUBBRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xF80F ); + ModRM( 3, to, from ); +} + +emitterT void ePSUBWRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xF90F ); + ModRM( 3, to, from ); +} + +emitterT void ePSUBDRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xFA0F ); + ModRM( 3, to, from ); +} + +emitterT void ePSUBDMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xFA0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void ePSUBUSBRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xD80F ); + ModRM( 3, to, from ); +} + +emitterT void ePSUBUSWRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xD90F ); + ModRM( 3, to, from ); +} + +// psubq m64 to r64 (sse2 only?) +emitterT void ePSUBQMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xFB0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// psubq r64 to r64 (sse2 only?) +emitterT void ePSUBQRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xFB0F ); + ModRM( 3, to, from ); +} + +// pmuludq m64 to r64 (sse2 only?) +emitterT void ePMULUDQMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xF40F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +// pmuludq r64 to r64 (sse2 only?) +emitterT void ePMULUDQRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xF40F ); + ModRM( 3, to, from ); +} + +emitterT void ePCMPEQBRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x740F ); + ModRM( 3, to, from ); +} + +emitterT void ePCMPEQWRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x750F ); + ModRM( 3, to, from ); +} + +emitterT void ePCMPEQDRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x760F ); + ModRM( 3, to, from ); +} + +emitterT void ePCMPEQDMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0x760F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void ePCMPGTBRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x640F ); + ModRM( 3, to, from ); +} + +emitterT void ePCMPGTWRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x650F ); + ModRM( 3, to, from ); +} + +emitterT void ePCMPGTDRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x660F ); + ModRM( 3, to, from ); +} + +emitterT void ePCMPGTDMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0x660F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void ePSRLWItoR( x86MMXRegType to, u8 from ) +{ + write16( 0x710F ); + ModRM( 3, 2 , to ); + write8( from ); +} + +emitterT void ePSRLDItoR( x86MMXRegType to, u8 from ) +{ + write16( 0x720F ); + ModRM( 3, 2 , to ); + write8( from ); +} + +emitterT void ePSRLDRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xD20F ); + ModRM( 3, to, from ); +} + +emitterT void ePSLLWItoR( x86MMXRegType to, u8 from ) +{ + write16( 0x710F ); + ModRM( 3, 6 , to ); + write8( from ); +} + +emitterT void ePSLLDItoR( x86MMXRegType to, u8 from ) +{ + write16( 0x720F ); + ModRM( 3, 6 , to ); + write8( from ); +} + +emitterT void ePSLLDRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xF20F ); + ModRM( 3, to, from ); +} + +emitterT void ePSRAWItoR( x86MMXRegType to, u8 from ) +{ + write16( 0x710F ); + ModRM( 3, 4 , to ); + write8( from ); +} + +emitterT void ePSRADItoR( x86MMXRegType to, u8 from ) +{ + write16( 0x720F ); + ModRM( 3, 4 , to ); + write8( from ); +} + +emitterT void ePSRADRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0xE20F ); + ModRM( 3, to, from ); +} + +/* por m64 to r64 */ +emitterT void ePORMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xEB0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* pxor m64 to r64 */ +emitterT void ePXORMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xEF0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* pand m64 to r64 */ +emitterT void ePANDMtoR( x86MMXRegType to, uptr from ) +{ + //u64 rip = (u64)x86Ptr[0] + 7; + write16( 0xDB0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void ePANDNMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0xDF0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void ePUNPCKHDQRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x6A0F ); + ModRM( 3, to, from ); +} + +emitterT void ePUNPCKHDQMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0x6A0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void ePUNPCKLDQRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x620F ); + ModRM( 3, to, from ); +} + +emitterT void ePUNPCKLDQMtoR( x86MMXRegType to, uptr from ) +{ + write16( 0x620F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void eMOVQ64ItoR( x86MMXRegType reg, u64 i ) +{ + eMOVQMtoR( reg, ( uptr )(x86Ptr[0]) + 2 + 7 ); + eJMP8( 8 ); + write64( i ); +} + +emitterT void eMOVQRtoR( x86MMXRegType to, x86MMXRegType from ) +{ + write16( 0x6F0F ); + ModRM( 3, to, from ); +} + +emitterT void eMOVQRmtoROffset( x86MMXRegType to, x86IntRegType from, u32 offset ) +{ + write16( 0x6F0F ); + + if( offset < 128 ) { + ModRM( 1, to, from ); + write8(offset); + } + else { + ModRM( 2, to, from ); + write32(offset); + } +} + +emitterT void eMOVQRtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset ) +{ + write16( 0x7F0F ); + + if( offset < 128 ) { + ModRM( 1, from , to ); + write8(offset); + } + else { + ModRM( 2, from, to ); + write32(offset); + } +} + +/* movd m32 to r64 */ +emitterT void eMOVDMtoMMX( x86MMXRegType to, uptr from ) +{ + write16( 0x6E0F ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +/* movd r64 to m32 */ +emitterT void eMOVDMMXtoM( uptr to, x86MMXRegType from ) +{ + write16( 0x7E0F ); + ModRM( 0, from, DISP32 ); + write32( MEMADDR(to, 4) ); +} + +emitterT void eMOVD32RtoMMX( x86MMXRegType to, x86IntRegType from ) +{ + write16( 0x6E0F ); + ModRM( 3, to, from ); +} + +emitterT void eMOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from ) +{ + write16( 0x6E0F ); + ModRM( 0, to, from ); +} + +emitterT void eMOVD32RmOffsettoMMX( x86MMXRegType to, x86IntRegType from, u32 offset ) +{ + write16( 0x6E0F ); + + if( offset < 128 ) { + ModRM( 1, to, from ); + write8(offset); + } + else { + ModRM( 2, to, from ); + write32(offset); + } +} + +emitterT void eMOVD32MMXtoR( x86IntRegType to, x86MMXRegType from ) +{ + write16( 0x7E0F ); + ModRM( 3, from, to ); +} + +emitterT void eMOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from ) +{ + write16( 0x7E0F ); + ModRM( 0, from, to ); + if( to >= 4 ) { + // no idea why + assert( to == ESP ); + write8(0x24); + } + +} + +emitterT void eMOVD32MMXtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset ) +{ + write16( 0x7E0F ); + + if( offset < 128 ) { + ModRM( 1, from, to ); + write8(offset); + } + else { + ModRM( 2, from, to ); + write32(offset); + } +} + +///* movd r32 to r64 */ +//emitterT void eMOVD32MMXtoMMX( x86MMXRegType to, x86MMXRegType from ) +//{ +// write16( 0x6E0F ); +// ModRM( 3, to, from ); +//} +// +///* movq r64 to r32 */ +//emitterT void eMOVD64MMXtoMMX( x86MMXRegType to, x86MMXRegType from ) +//{ +// write16( 0x7E0F ); +// ModRM( 3, from, to ); +//} + +// untested +emitterT void ePACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from) +{ + write16( 0x630F ); + ModRM( 3, to, from ); +} + +emitterT void ePACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType from) +{ + write16( 0x6B0F ); + ModRM( 3, to, from ); +} + +emitterT void ePMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from) +{ + write16( 0xD70F ); + ModRM( 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( 0xc40f ); + ModRM( 3, to, from ); + write8( imm8 ); +} + +emitterT void ePSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8) +{ + write16(0x700f); + ModRM( 3, to, from ); + write8(imm8); +} + +emitterT void ePSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8) +{ + write16( 0x700f ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); + write8(imm8); +} + +emitterT void eMASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from) +{ + write16(0xf70f); + ModRM( 3, to, from ); +} diff --git a/pcsx2/x86/ix86/ix86_sse.inl b/pcsx2/x86/ix86/ix86_sse.inl new file mode 100644 index 0000000000..5423bdca0f --- /dev/null +++ b/pcsx2/x86/ix86/ix86_sse.inl @@ -0,0 +1,1407 @@ +/* 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" + +//------------------------------------------------------------------ +// SSE instructions +//------------------------------------------------------------------ + +#define SSEMtoR( code, overb ) \ + assert( to < XMMREGS ) ; \ + RexR(0, to); \ + write16( code ); \ + ModRM( 0, to, DISP32 ); \ + write32( MEMADDR(from, 4 + overb) ); \ + +#define SSERtoM( code, overb ) \ + assert( from < XMMREGS) ; \ + RexR(0, from); \ + write16( code ); \ + ModRM( 0, from, DISP32 ); \ + write32( MEMADDR(to, 4 + overb) ); \ + +#define SSE_SS_MtoR( code, overb ) \ + assert( to < XMMREGS ) ; \ + write8( 0xf3 ); \ + RexR(0, to); \ + write16( code ); \ + ModRM( 0, to, DISP32 ); \ + write32( MEMADDR(from, 4 + overb) ); \ + +#define SSE_SS_RtoM( code, overb ) \ + assert( from < XMMREGS) ; \ + write8( 0xf3 ); \ + RexR(0, from); \ + write16( code ); \ + ModRM( 0, from, DISP32 ); \ + write32( MEMADDR(to, 4 + overb) ); \ + +#define SSERtoR( code ) \ + assert( to < XMMREGS && from < XMMREGS) ; \ + RexRB(0, to, from); \ + write16( code ); \ + ModRM( 3, to, from ); + +#define SSEMtoR66( code ) \ + write8( 0x66 ); \ + SSEMtoR( code, 0 ); + +#define SSERtoM66( code ) \ + write8( 0x66 ); \ + SSERtoM( code, 0 ); + +#define SSERtoR66( code ) \ + write8( 0x66 ); \ + SSERtoR( code ); + +#define _SSERtoR66( code ) \ + assert( to < XMMREGS && from < XMMREGS) ; \ + write8( 0x66 ); \ + RexRB(0, from, to); \ + write16( code ); \ + ModRM( 3, from, to ); + +#define SSE_SS_RtoR( code ) \ + assert( to < XMMREGS && from < XMMREGS) ; \ + write8( 0xf3 ); \ + RexRB(0, to, from); \ + write16( code ); \ + ModRM( 3, to, from ); + +#define CMPPSMtoR( op ) \ + SSEMtoR( 0xc20f, 1 ); \ + write8( op ); + +#define CMPPSRtoR( op ) \ + SSERtoR( 0xc20f ); \ + write8( op ); + +#define CMPSSMtoR( op ) \ + SSE_SS_MtoR( 0xc20f, 1 ); \ + write8( op ); + +#define CMPSSRtoR( op ) \ + SSE_SS_RtoR( 0xc20f ); \ + write8( op ); + +/* movups [r32][r32*scale] to xmm1 */ +emitterT void eSSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) +{ + RexRXB(0, to, from2, from); + write16( 0x100f ); + ModRM( 0, to, 0x4 ); + SibSB( scale, from2, from ); +} + +/* movups xmm1 to [r32][r32*scale] */ +emitterT void eSSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) +{ + RexRXB(1, to, from2, from); + write16( 0x110f ); + ModRM( 0, to, 0x4 ); + SibSB( scale, from2, from ); +} + +/* movups [r32] to r32 */ +emitterT void eSSE_MOVUPSRmtoR( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0, to, from); + write16( 0x100f ); + ModRM( 0, to, from ); +} + +/* movups r32 to [r32] */ +emitterT void eSSE_MOVUPSRtoRm( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0, from, to); + write16( 0x110f ); + ModRM( 0, from, to ); +} + +/* movlps [r32] to r32 */ +emitterT void eSSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from ) +{ + RexRB(1, to, from); + write16( 0x120f ); + ModRM( 0, to, from ); +} + +emitterT void eSSE_MOVLPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset ) +{ + RexRB(0, to, from); + write16( 0x120f ); + WriteRmOffsetFrom(to, from, offset); +} + +/* movaps r32 to [r32] */ +emitterT void eSSE_MOVLPSRtoRm( x86IntRegType to, x86IntRegType from ) +{ + RexRB(0, from, to); + write16( 0x130f ); + ModRM( 0, from, to ); +} + +emitterT void eSSE_MOVLPSRtoRmOffset( x86SSERegType to, x86IntRegType from, int offset ) +{ + RexRB(0, from, to); + write16( 0x130f ); + WriteRmOffsetFrom(from, to, offset); +} + +/* movaps [r32][r32*scale] to xmm1 */ +emitterT void eSSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) +{ + assert( from != EBP ); + RexRXB(0, to, from2, from); + write16( 0x280f ); + ModRM( 0, to, 0x4 ); + SibSB( scale, from2, from ); +} + +/* movaps xmm1 to [r32][r32*scale] */ +emitterT void eSSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) +{ + assert( from != EBP ); + RexRXB(0, to, from2, from); + write16( 0x290f ); + ModRM( 0, to, 0x4 ); + SibSB( scale, from2, from ); +} + +// movaps [r32+offset] to r32 +emitterT void eSSE_MOVAPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset ) +{ + RexRB(0, to, from); + write16( 0x280f ); + WriteRmOffsetFrom(to, from, offset); +} + +// movaps r32 to [r32+offset] +emitterT void eSSE_MOVAPSRtoRmOffset( x86IntRegType to, x86SSERegType from, int offset ) +{ + RexRB(0, from, to); + write16( 0x290f ); + WriteRmOffsetFrom(from, to, offset); +} + +// movdqa [r32+offset] to r32 +emitterT void eSSE2_MOVDQARmtoROffset( x86SSERegType to, x86IntRegType from, int offset ) +{ + write8(0x66); + RexRB(0, to, from); + write16( 0x6f0f ); + WriteRmOffsetFrom(to, from, offset); +} + +// movdqa r32 to [r32+offset] +emitterT void eSSE2_MOVDQARtoRmOffset( x86IntRegType to, x86SSERegType from, int offset ) +{ + write8(0x66); + RexRB(0, from, to); + write16( 0x7f0f ); + WriteRmOffsetFrom(from, to, offset); +} + +// movups [r32+offset] to r32 +emitterT void eSSE_MOVUPSRmtoROffset( x86SSERegType to, x86IntRegType from, int offset ) +{ + RexRB(0, to, from); + write16( 0x100f ); + WriteRmOffsetFrom(to, from, offset); +} + +// movups r32 to [r32+offset] +emitterT void eSSE_MOVUPSRtoRmOffset( x86SSERegType to, x86IntRegType from, int offset ) +{ + RexRB(0, from, to); + write16( 0x110f ); + WriteRmOffsetFrom(from, to, offset); +} + +//**********************************************************************************/ +//MOVAPS: Move aligned Packed Single Precision FP values * +//********************************************************************************** +emitterT void eSSE_MOVAPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x280f, 0 ); } +emitterT void eSSE_MOVAPS_XMM_to_M128( uptr to, x86SSERegType from ) { SSERtoM( 0x290f, 0 ); } +emitterT void eSSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { if (to != from) { SSERtoR( 0x280f ); } } + +emitterT void eSSE_MOVUPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x100f, 0 ); } +emitterT void eSSE_MOVUPS_XMM_to_M128( uptr to, x86SSERegType from ) { SSERtoM( 0x110f, 0 ); } + +emitterT void eSSE2_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + write8(0xf2); + SSERtoR( 0x100f); +} + +emitterT void eSSE2_MOVQ_M64_to_XMM( x86SSERegType to, uptr from ) +{ + write8(0xf3); SSEMtoR( 0x7e0f, 0); +} + +emitterT void eSSE2_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + write8(0xf3); SSERtoR( 0x7e0f); +} + +emitterT void eSSE2_MOVQ_XMM_to_M64( u32 to, x86SSERegType from ) +{ + SSERtoM66(0xd60f); +} + +emitterT void eSSE2_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from) +{ + write8(0xf2); + SSERtoR( 0xd60f); +} +emitterT void eSSE2_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from) +{ + write8(0xf3); + SSERtoR( 0xd60f); +} + +//**********************************************************************************/ +//MOVSS: Move Scalar Single-Precision FP value * +//********************************************************************************** +emitterT void eSSE_MOVSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x100f, 0 ); } +emitterT void eSSE_MOVSS_XMM_to_M32( u32 to, x86SSERegType from ) { SSE_SS_RtoM( 0x110f, 0 ); } +emitterT void eSSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from ) +{ + write8(0xf3); + RexRB(0, from, to); + write16(0x110f); + ModRM(0, from, to); +} + +emitterT void eSSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { if (to != from) { SSE_SS_RtoR( 0x100f ); } } + +emitterT void eSSE_MOVSS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) +{ + write8(0xf3); + RexRB(0, to, from); + write16( 0x100f ); + WriteRmOffsetFrom(to, from, offset); +} + +emitterT void eSSE_MOVSS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ) +{ + write8(0xf3); + RexRB(0, from, to); + write16(0x110f); + WriteRmOffsetFrom(from, to, offset); +} + +emitterT void eSSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xf70f ); } +//**********************************************************************************/ +//MOVLPS: Move low Packed Single-Precision FP * +//********************************************************************************** +emitterT void eSSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x120f, 0 ); } +emitterT void eSSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x130f, 0 ); } + +emitterT void eSSE_MOVLPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) +{ + RexRB(0, to, from); + write16( 0x120f ); + WriteRmOffsetFrom(to, from, offset); +} + +emitterT void eSSE_MOVLPS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ) +{ + RexRB(0, from, to); + write16(0x130f); + WriteRmOffsetFrom(from, to, offset); +} + +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MOVHPS: Move High Packed Single-Precision FP * +//********************************************************************************** +emitterT void eSSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x160f, 0 ); } +emitterT void eSSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x170f, 0 ); } + +emitterT void eSSE_MOVHPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) +{ + RexRB(0, to, from); + write16( 0x160f ); + WriteRmOffsetFrom(to, from, offset); +} + +emitterT void eSSE_MOVHPS_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ) +{ + RexRB(0, from, to); + write16(0x170f); + WriteRmOffsetFrom(from, to, offset); +} + +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MOVLHPS: Moved packed Single-Precision FP low to high * +//********************************************************************************** +emitterT void eSSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x160f ); } + +////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MOVHLPS: Moved packed Single-Precision FP High to Low * +//********************************************************************************** +emitterT void eSSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x120f ); } + +/////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//ANDPS: Logical Bit-wise AND for Single FP * +//********************************************************************************** +emitterT void eSSE_ANDPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x540f, 0 ); } +emitterT void eSSE_ANDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x540f ); } + +/////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//ANDNPS : Logical Bit-wise AND NOT of Single-precision FP values * +//********************************************************************************** +emitterT void eSSE_ANDNPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x550f, 0 ); } +emitterT void eSSE_ANDNPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR( 0x550f ); } + +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//RCPPS : Packed Single-Precision FP Reciprocal * +//********************************************************************************** +emitterT void eSSE_RCPPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x530f ); } +emitterT void eSSE_RCPPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x530f, 0 ); } + +emitterT void eSSE_RCPSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR(0x530f); } +emitterT void eSSE_RCPSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR(0x530f, 0); } + +////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//ORPS : Bit-wise Logical OR of Single-Precision FP Data * +//********************************************************************************** +emitterT void eSSE_ORPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x560f, 0 ); } +emitterT void eSSE_ORPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x560f ); } + +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//XORPS : Bitwise Logical XOR of Single-Precision FP Values * +//********************************************************************************** +emitterT void eSSE_XORPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x570f, 0 ); } +emitterT void eSSE_XORPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x570f ); } + +/////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//ADDPS : ADD Packed Single-Precision FP Values * +//********************************************************************************** +emitterT void eSSE_ADDPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x580f, 0 ); } +emitterT void eSSE_ADDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x580f ); } + +//////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//ADDSS : ADD Scalar Single-Precision FP Values * +//********************************************************************************** +emitterT void eSSE_ADDSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x580f, 0 ); } +emitterT void eSSE_ADDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x580f ); } + +///////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//SUBPS: Packed Single-Precision FP Subtract * +//********************************************************************************** +emitterT void eSSE_SUBPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5c0f, 0 ); } +emitterT void eSSE_SUBPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5c0f ); } + +/////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//SUBSS : Scalar Single-Precision FP Subtract * +//********************************************************************************** +emitterT void eSSE_SUBSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x5c0f, 0 ); } +emitterT void eSSE_SUBSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x5c0f ); } + +///////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MULPS : Packed Single-Precision FP Multiply * +//********************************************************************************** +emitterT void eSSE_MULPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x590f, 0 ); } +emitterT void eSSE_MULPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x590f ); } + +//////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MULSS : Scalar Single-Precision FP Multiply * +//********************************************************************************** +emitterT void eSSE_MULSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x590f, 0 ); } +emitterT void eSSE_MULSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x590f ); } + +//////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//Packed Single-Precission FP compare (CMPccPS) * +//********************************************************************************** +//missing SSE_CMPPS_I8_to_XMM +// SSE_CMPPS_M32_to_XMM +// SSE_CMPPS_XMM_to_XMM +emitterT void eSSE_CMPEQPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 0 ); } +emitterT void eSSE_CMPEQPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 0 ); } +emitterT void eSSE_CMPLTPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 1 ); } +emitterT void eSSE_CMPLTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 1 ); } +emitterT void eSSE_CMPLEPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 2 ); } +emitterT void eSSE_CMPLEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 2 ); } +emitterT void eSSE_CMPUNORDPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 3 ); } +emitterT void eSSE_CMPUNORDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 3 ); } +emitterT void eSSE_CMPNEPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 4 ); } +emitterT void eSSE_CMPNEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 4 ); } +emitterT void eSSE_CMPNLTPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 5 ); } +emitterT void eSSE_CMPNLTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 5 ); } +emitterT void eSSE_CMPNLEPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 6 ); } +emitterT void eSSE_CMPNLEPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 6 ); } +emitterT void eSSE_CMPORDPS_M128_to_XMM( x86SSERegType to, uptr from ) { CMPPSMtoR( 7 ); } +emitterT void eSSE_CMPORDPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPPSRtoR( 7 ); } + +/////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//Scalar Single-Precission FP compare (CMPccSS) * +//********************************************************************************** +//missing SSE_CMPSS_I8_to_XMM +// SSE_CMPSS_M32_to_XMM +// SSE_CMPSS_XMM_to_XMM +emitterT void eSSE_CMPEQSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 0 ); } +emitterT void eSSE_CMPEQSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 0 ); } +emitterT void eSSE_CMPLTSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 1 ); } +emitterT void eSSE_CMPLTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 1 ); } +emitterT void eSSE_CMPLESS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 2 ); } +emitterT void eSSE_CMPLESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 2 ); } +emitterT void eSSE_CMPUNORDSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 3 ); } +emitterT void eSSE_CMPUNORDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 3 ); } +emitterT void eSSE_CMPNESS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 4 ); } +emitterT void eSSE_CMPNESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 4 ); } +emitterT void eSSE_CMPNLTSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 5 ); } +emitterT void eSSE_CMPNLTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 5 ); } +emitterT void eSSE_CMPNLESS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 6 ); } +emitterT void eSSE_CMPNLESS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 6 ); } +emitterT void eSSE_CMPORDSS_M32_to_XMM( x86SSERegType to, uptr from ) { CMPSSMtoR( 7 ); } +emitterT void eSSE_CMPORDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { CMPSSRtoR( 7 ); } + +emitterT void eSSE_UCOMISS_M32_to_XMM( x86SSERegType to, uptr from ) +{ + RexR(0, to); + write16( 0x2e0f ); + ModRM( 0, to, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +emitterT void eSSE_UCOMISS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + RexRB(0, to, from); + write16( 0x2e0f ); + ModRM( 3, to, from ); +} + +////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//RSQRTPS : Packed Single-Precision FP Square Root Reciprocal * +//********************************************************************************** +emitterT void eSSE_RSQRTPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x520f, 0 ); } +emitterT void eSSE_RSQRTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x520f ); } + +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//RSQRTSS : Scalar Single-Precision FP Square Root Reciprocal * +//********************************************************************************** +emitterT void eSSE_RSQRTSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x520f, 0 ); } +emitterT void eSSE_RSQRTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x520f ); } + +//////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//SQRTPS : Packed Single-Precision FP Square Root * +//********************************************************************************** +emitterT void eSSE_SQRTPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x510f, 0 ); } +emitterT void eSSE_SQRTPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x510f ); } + +////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//SQRTSS : Scalar Single-Precision FP Square Root * +//********************************************************************************** +emitterT void eSSE_SQRTSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x510f, 0 ); } +emitterT void eSSE_SQRTSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x510f ); } + +//////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MAXPS: Return Packed Single-Precision FP Maximum * +//********************************************************************************** +emitterT void eSSE_MAXPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5f0f, 0 ); } +emitterT void eSSE_MAXPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5f0f ); } + +emitterT void eSSE2_MAXPD_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0x5f0f ); } +emitterT void eSSE2_MAXPD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0x5f0f ); } + +///////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MAXSS: Return Scalar Single-Precision FP Maximum * +//********************************************************************************** +emitterT void eSSE_MAXSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x5f0f, 0 ); } +emitterT void eSSE_MAXSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x5f0f ); } + +///////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//CVTPI2PS: Packed Signed INT32 to Packed Single FP Conversion * +//********************************************************************************** +emitterT void eSSE_CVTPI2PS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x2a0f, 0 ); } +emitterT void eSSE_CVTPI2PS_MM_to_XMM( x86SSERegType to, x86MMXRegType from ) { SSERtoR( 0x2a0f ); } + +/////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//CVTPS2PI: Packed Single FP to Packed Signed INT32 Conversion * +//********************************************************************************** +emitterT void eSSE_CVTPS2PI_M64_to_MM( x86MMXRegType to, uptr from ) { SSEMtoR( 0x2d0f, 0 ); } +emitterT void eSSE_CVTPS2PI_XMM_to_MM( x86MMXRegType to, x86SSERegType from ) { SSERtoR( 0x2d0f ); } + +emitterT void eSSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from) { write8(0xf3); SSEMtoR(0x2c0f, 0); } +emitterT void eSSE_CVTTSS2SI_XMM_to_R32(x86IntRegType to, x86SSERegType from) +{ + write8(0xf3); + RexRB(0, to, from); + write16(0x2c0f); + ModRM(3, to, from); +} + +emitterT void eSSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from) { write8(0xf3); SSEMtoR(0x2a0f, 0); } +emitterT void eSSE_CVTSI2SS_R_to_XMM(x86SSERegType to, x86IntRegType from) +{ + write8(0xf3); + RexRB(0, to, from); + write16(0x2a0f); + ModRM(3, to, from); +} + +/////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//CVTDQ2PS: Packed Signed INT32 to Packed Single Precision FP Conversion * +//********************************************************************************** +emitterT void eSSE2_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5b0f, 0 ); } +emitterT void eSSE2_CVTDQ2PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5b0f ); } + +//**********************************************************************************/ +//CVTPS2DQ: Packed Single Precision FP to Packed Signed INT32 Conversion * +//********************************************************************************** +emitterT void eSSE2_CVTPS2DQ_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0x5b0f ); } +emitterT void eSSE2_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0x5b0f ); } + +emitterT void eSSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ write8(0xf3); SSERtoR(0x5b0f); } +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MINPS: Return Packed Single-Precision FP Minimum * +//********************************************************************************** +emitterT void eSSE_MINPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5d0f, 0 ); } +emitterT void eSSE_MINPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5d0f ); } + +emitterT void eSSE2_MINPD_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0x5d0f ); } +emitterT void eSSE2_MINPD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0x5d0f ); } + +////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MINSS: Return Scalar Single-Precision FP Minimum * +//********************************************************************************** +emitterT void eSSE_MINSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x5d0f, 0 ); } +emitterT void eSSE_MINSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x5d0f ); } + +/////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//PMAXSW: Packed Signed Integer Word Maximum * +//********************************************************************************** +//missing + // SSE_PMAXSW_M64_to_MM +// SSE2_PMAXSW_M128_to_XMM +// SSE2_PMAXSW_XMM_to_XMM +emitterT void eSSE_PMAXSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ){ SSERtoR( 0xEE0F ); } + +/////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//PMINSW: Packed Signed Integer Word Minimum * +//********************************************************************************** +//missing + // SSE_PMINSW_M64_to_MM +// SSE2_PMINSW_M128_to_XMM +// SSE2_PMINSW_XMM_to_XMM +emitterT void eSSE_PMINSW_MM_to_MM( x86MMXRegType to, x86MMXRegType from ){ SSERtoR( 0xEA0F ); } + +////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//SHUFPS: Shuffle Packed Single-Precision FP Values * +//********************************************************************************** +emitterT void eSSE_SHUFPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { SSERtoR( 0xC60F ); write8( imm8 ); } +emitterT void eSSE_SHUFPS_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSEMtoR( 0xC60F, 1 ); write8( imm8 ); } + +emitterT void eSSE_SHUFPS_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset, u8 imm8 ) +{ + RexRB(0, to, from); + write16(0xc60f); + WriteRmOffsetFrom(to, from, offset); + write8(imm8); +} + +////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//SHUFPD: Shuffle Packed Double-Precision FP Values * +//********************************************************************************** +emitterT void eSSE2_SHUFPD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { SSERtoR66( 0xC60F ); write8( imm8 ); } +emitterT void eSSE2_SHUFPD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSEMtoR66( 0xC60F ); write8( imm8 ); } + +//////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//PSHUFD: Shuffle Packed DoubleWords * +//********************************************************************************** +emitterT void eSSE2_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) +{ + SSERtoR66( 0x700F ); + write8( imm8 ); +} +emitterT void eSSE2_PSHUFD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSEMtoR66( 0x700F ); write8( imm8 ); } + +emitterT void eSSE2_PSHUFLW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { write8(0xF2); SSERtoR(0x700F); write8(imm8); } +emitterT void eSSE2_PSHUFLW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { write8(0xF2); SSEMtoR(0x700F, 1); write8(imm8); } +emitterT void eSSE2_PSHUFHW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { write8(0xF3); SSERtoR(0x700F); write8(imm8); } +emitterT void eSSE2_PSHUFHW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { write8(0xF3); SSEMtoR(0x700F, 1); write8(imm8); } + +/////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//UNPCKLPS: Unpack and Interleave low Packed Single-Precision FP Data * +//********************************************************************************** +emitterT void eSSE_UNPCKLPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR(0x140f, 0); } +emitterT void eSSE_UNPCKLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x140F ); } + +//////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//UNPCKHPS: Unpack and Interleave High Packed Single-Precision FP Data * +//********************************************************************************** +emitterT void eSSE_UNPCKHPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR(0x150f, 0); } +emitterT void eSSE_UNPCKHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x150F ); } + +//////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//DIVPS : Packed Single-Precision FP Divide * +//********************************************************************************** +emitterT void eSSE_DIVPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5e0F, 0 ); } +emitterT void eSSE_DIVPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5e0F ); } + +////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//DIVSS : Scalar Single-Precision FP Divide * +//********************************************************************************** +emitterT void eSSE_DIVSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x5e0F, 0 ); } +emitterT void eSSE_DIVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR( 0x5e0F ); } + +///////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//STMXCSR : Store Streaming SIMD Extension Control/Status * +//********************************************************************************** +emitterT void eSSE_STMXCSR( uptr from ) { + write16( 0xAE0F ); + ModRM( 0, 0x3, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//LDMXCSR : Load Streaming SIMD Extension Control/Status * +//********************************************************************************** +emitterT void eSSE_LDMXCSR( uptr from ) { + write16( 0xAE0F ); + ModRM( 0, 0x2, DISP32 ); + write32( MEMADDR(from, 4) ); +} + +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//PADDB,PADDW,PADDD : Add Packed Integers * +//********************************************************************************** +emitterT void eSSE2_PADDB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFC0F ); } +emitterT void eSSE2_PADDB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFC0F ); } +emitterT void eSSE2_PADDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFD0F ); } +emitterT void eSSE2_PADDW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFD0F ); } +emitterT void eSSE2_PADDD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFE0F ); } +emitterT void eSSE2_PADDD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFE0F ); } +emitterT void eSSE2_PADDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD40F ); } +emitterT void eSSE2_PADDQ_M128_to_XMM(x86SSERegType to, uptr from ) { SSEMtoR66( 0xD40F ); } + +/////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//PCMPxx: Compare Packed Integers * +//********************************************************************************** +emitterT void eSSE2_PCMPGTB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x640F ); } +emitterT void eSSE2_PCMPGTB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x640F ); } +emitterT void eSSE2_PCMPGTW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x650F ); } +emitterT void eSSE2_PCMPGTW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x650F ); } +emitterT void eSSE2_PCMPGTD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x660F ); } +emitterT void eSSE2_PCMPGTD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x660F ); } +emitterT void eSSE2_PCMPEQB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x740F ); } +emitterT void eSSE2_PCMPEQB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x740F ); } +emitterT void eSSE2_PCMPEQW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x750F ); } +emitterT void eSSE2_PCMPEQW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x750F ); } +emitterT void eSSE2_PCMPEQD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0x760F ); } +emitterT void eSSE2_PCMPEQD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0x760F ); } + +//////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//PEXTRW,PINSRW: Packed Extract/Insert Word * +//********************************************************************************** +emitterT void eSSE_PEXTRW_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8 ){ SSERtoR66(0xC50F); write8( imm8 ); } +emitterT void eSSE_PINSRW_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8 ){ SSERtoR66(0xC40F); write8( imm8 ); } + +//////////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//PSUBx: Subtract Packed Integers * +//********************************************************************************** +emitterT void eSSE2_PSUBB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xF80F ); } +emitterT void eSSE2_PSUBB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xF80F ); } +emitterT void eSSE2_PSUBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xF90F ); } +emitterT void eSSE2_PSUBW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xF90F ); } +emitterT void eSSE2_PSUBD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFA0F ); } +emitterT void eSSE2_PSUBD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFA0F ); } +emitterT void eSSE2_PSUBQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFB0F ); } +emitterT void eSSE2_PSUBQ_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFB0F ); } + +/////////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//MOVD: Move Dword(32bit) to /from XMM reg * +//********************************************************************************** +emitterT void eSSE2_MOVD_M32_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66(0x6E0F); } +emitterT void eSSE2_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from ) { SSERtoR66(0x6E0F); } + +emitterT void eSSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from ) +{ + write8(0x66); + RexRB(0, to, from); + write16( 0x6e0f ); + ModRM( 0, to, from); +} + +emitterT void eSSE2_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) +{ + write8(0x66); + RexRB(0, to, from); + write16( 0x6e0f ); + WriteRmOffsetFrom(to, from, offset); +} + +emitterT void eSSE2_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) { SSERtoM66(0x7E0F); } +emitterT void eSSE2_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) { _SSERtoR66(0x7E0F); } + +emitterT void eSSE2_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from ) +{ + write8(0x66); + RexRB(0, from, to); + write16( 0x7e0f ); + ModRM( 0, from, to ); +} + +emitterT void eSSE2_MOVD_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ) +{ + write8(0x66); + RexRB(0, from, to); + write16( 0x7e0f ); + WriteRmOffsetFrom(from, to, offset); +} + +//////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//POR : SSE Bitwise OR * +//********************************************************************************** +emitterT void eSSE2_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xEB0F ); } +emitterT void eSSE2_POR_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEB0F ); } + +// logical and to &= from +emitterT void eSSE2_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDB0F ); } +emitterT void eSSE2_PAND_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDB0F ); } + +// to = (~to) & from +emitterT void eSSE2_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDF0F ); } +emitterT void eSSE2_PANDN_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDF0F ); } + +///////////////////////////////////////////////////////////////////////////////////// +//**********************************************************************************/ +//PXOR : SSE Bitwise XOR * +//********************************************************************************** +emitterT void eSSE2_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xEF0F ); } +emitterT void eSSE2_PXOR_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEF0F ) }; +/////////////////////////////////////////////////////////////////////////////////////// + +emitterT void eSSE2_MOVDQA_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0x6F0F); } +emitterT void eSSE2_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from ) { SSERtoM66(0x7F0F); } +emitterT void eSSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { if (to != from) { SSERtoR66(0x6F0F); } } + +emitterT void eSSE2_MOVDQU_M128_to_XMM(x86SSERegType to, uptr from) { write8(0xF3); SSEMtoR(0x6F0F, 0); } +emitterT void eSSE2_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from) { write8(0xF3); SSERtoM(0x7F0F, 0); } +emitterT void eSSE2_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { write8(0xF3); SSERtoR(0x6F0F); } + +// shift right logical + +emitterT void eSSE2_PSRLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD10F); } +emitterT void eSSE2_PSRLW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD10F); } +emitterT void eSSE2_PSRLW_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x710F ); + ModRM( 3, 2 , to ); + write8( imm8 ); +} + +emitterT void eSSE2_PSRLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD20F); } +emitterT void eSSE2_PSRLD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD20F); } +emitterT void eSSE2_PSRLD_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x720F ); + ModRM( 3, 2 , to ); + write8( imm8 ); +} + +emitterT void eSSE2_PSRLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD30F); } +emitterT void eSSE2_PSRLQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD30F); } +emitterT void eSSE2_PSRLQ_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x730F ); + ModRM( 3, 2 , to ); + write8( imm8 ); +} + +emitterT void eSSE2_PSRLDQ_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x730F ); + ModRM( 3, 3 , to ); + write8( imm8 ); +} + +// shift right arithmetic + +emitterT void eSSE2_PSRAW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xE10F); } +emitterT void eSSE2_PSRAW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xE10F); } +emitterT void eSSE2_PSRAW_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x710F ); + ModRM( 3, 4 , to ); + write8( imm8 ); +} + +emitterT void eSSE2_PSRAD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xE20F); } +emitterT void eSSE2_PSRAD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xE20F); } +emitterT void eSSE2_PSRAD_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x720F ); + ModRM( 3, 4 , to ); + write8( imm8 ); +} + +// shift left logical + +emitterT void eSSE2_PSLLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF10F); } +emitterT void eSSE2_PSLLW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF10F); } +emitterT void eSSE2_PSLLW_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x710F ); + ModRM( 3, 6 , to ); + write8( imm8 ); +} + +emitterT void eSSE2_PSLLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF20F); } +emitterT void eSSE2_PSLLD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF20F); } +emitterT void eSSE2_PSLLD_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x720F ); + ModRM( 3, 6 , to ); + write8( imm8 ); +} + +emitterT void eSSE2_PSLLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF30F); } +emitterT void eSSE2_PSLLQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF30F); } +emitterT void eSSE2_PSLLQ_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x730F ); + ModRM( 3, 6 , to ); + write8( imm8 ); +} + +emitterT void eSSE2_PSLLDQ_I8_to_XMM(x86SSERegType to, u8 imm8) +{ + write8( 0x66 ); + RexB(0, to); + write16( 0x730F ); + ModRM( 3, 7 , to ); + write8( imm8 ); +} + +emitterT void eSSE2_PMAXSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xEE0F ); } +emitterT void eSSE2_PMAXSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEE0F ); } + +emitterT void eSSE2_PMAXUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDE0F ); } +emitterT void eSSE2_PMAXUB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDE0F ); } + +emitterT void eSSE2_PMINSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xEA0F ); } +emitterT void eSSE2_PMINSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEA0F ); } + +emitterT void eSSE2_PMINUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDA0F ); } +emitterT void eSSE2_PMINUB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDA0F ); } + +emitterT void eSSE2_PADDSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xEC0F ); } +emitterT void eSSE2_PADDSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEC0F ); } + +emitterT void eSSE2_PADDSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xED0F ); } +emitterT void eSSE2_PADDSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xED0F ); } + +emitterT void eSSE2_PSUBSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xE80F ); } +emitterT void eSSE2_PSUBSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xE80F ); } + +emitterT void eSSE2_PSUBSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xE90F ); } +emitterT void eSSE2_PSUBSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xE90F ); } + +emitterT void eSSE2_PSUBUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD80F ); } +emitterT void eSSE2_PSUBUSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xD80F ); } +emitterT void eSSE2_PSUBUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD90F ); } +emitterT void eSSE2_PSUBUSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xD90F ); } + +emitterT void eSSE2_PADDUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDC0F ); } +emitterT void eSSE2_PADDUSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDC0F ); } +emitterT void eSSE2_PADDUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDD0F ); } +emitterT void eSSE2_PADDUSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDD0F ); } + +//**********************************************************************************/ +//PACKSSWB,PACKSSDW: Pack Saturate Signed Word +//********************************************************************************** +emitterT void eSSE2_PACKSSWB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x630F ); } +emitterT void eSSE2_PACKSSWB_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x630F ); } +emitterT void eSSE2_PACKSSDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x6B0F ); } +emitterT void eSSE2_PACKSSDW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x6B0F ); } + +emitterT void eSSE2_PACKUSWB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x670F ); } +emitterT void eSSE2_PACKUSWB_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x670F ); } + +//**********************************************************************************/ +//PUNPCKHWD: Unpack 16bit high +//********************************************************************************** +emitterT void eSSE2_PUNPCKLBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x600F ); } +emitterT void eSSE2_PUNPCKLBW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x600F ); } + +emitterT void eSSE2_PUNPCKHBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x680F ); } +emitterT void eSSE2_PUNPCKHBW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x680F ); } + +emitterT void eSSE2_PUNPCKLWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x610F ); } +emitterT void eSSE2_PUNPCKLWD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x610F ); } +emitterT void eSSE2_PUNPCKHWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x690F ); } +emitterT void eSSE2_PUNPCKHWD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x690F ); } + +emitterT void eSSE2_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x620F ); } +emitterT void eSSE2_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x620F ); } +emitterT void eSSE2_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x6A0F ); } +emitterT void eSSE2_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x6A0F ); } + +emitterT void eSSE2_PUNPCKLQDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x6C0F ); } +emitterT void eSSE2_PUNPCKLQDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x6C0F ); } + +emitterT void eSSE2_PUNPCKHQDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0x6D0F ); } +emitterT void eSSE2_PUNPCKHQDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0x6D0F ); } + +emitterT void eSSE2_PMULLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0xD50F ); } +emitterT void eSSE2_PMULLW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0xD50F ); } +emitterT void eSSE2_PMULHW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0xE50F ); } +emitterT void eSSE2_PMULHW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0xE50F ); } + +emitterT void eSSE2_PMULUDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0xF40F ); } +emitterT void eSSE2_PMULUDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0xF40F ); } + +emitterT void eSSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0xD70F); } + +emitterT void eSSE_MOVMSKPS_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR(0x500F); } +emitterT void eSSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0x500F); } + +emitterT void eSSE2_PMADDWD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF50F); } + +emitterT void eSSE3_HADDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { write8(0xf2); SSERtoR( 0x7c0f ); } +emitterT void eSSE3_HADDPS_M128_to_XMM(x86SSERegType to, uptr from) { write8(0xf2); SSEMtoR( 0x7c0f, 0 ); } + +emitterT void eSSE3_MOVSLDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { + write8(0xf3); + RexRB(0, to, from); + write16( 0x120f); + ModRM( 3, to, from ); +} + +emitterT void eSSE3_MOVSLDUP_M128_to_XMM(x86SSERegType to, uptr from) { write8(0xf3); SSEMtoR(0x120f, 0); } +emitterT void eSSE3_MOVSHDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { write8(0xf3); SSERtoR(0x160f); } +emitterT void eSSE3_MOVSHDUP_M128_to_XMM(x86SSERegType to, uptr from) { write8(0xf3); SSEMtoR(0x160f, 0); } + +// SSSE3 + +emitterT void eSSSE3_PABSB_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x1C380F); + ModRM(3, to, from); +} + +emitterT void eSSSE3_PABSW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x1D380F); + ModRM(3, to, from); +} + +emitterT void eSSSE3_PABSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x1E380F); + ModRM(3, to, from); +} + +emitterT void eSSSE3_PALIGNR_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x0F3A0F); + ModRM(3, to, from); + write8(imm8); +} + +// SSE4.1 + +emitterT void eSSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) +{ + write8(0x66); + write24(0x403A0F); + ModRM(3, to, from); + write8(imm8); +} + +emitterT void eSSE4_DPPS_M128_to_XMM(x86SSERegType to, uptr from, u8 imm8) +{ + write8(0x66); + write24(0x403A0F); + ModRM(0, to, DISP32); + write32(MEMADDR(from, 4)); + write8(imm8); +} + +emitterT void eSSE4_INSERTPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x213A0F); + ModRM(3, to, from); + write8(imm8); +} + +emitterT void eSSE4_EXTRACTPS_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x173A0F); + ModRM(3, to, from); + write8(imm8); +} + +emitterT void eSSE4_BLENDPS_XMM_to_XMM(x86IntRegType to, x86SSERegType from, u8 imm8) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x0C3A0F); + ModRM(3, to, from); + write8(imm8); +} + +emitterT void eSSE4_BLENDVPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x14380F); + ModRM(3, to, from); +} + +emitterT void eSSE4_BLENDVPS_M128_to_XMM(x86SSERegType to, uptr from) +{ + write8(0x66); + RexR(0, to); + write24(0x14380F); + ModRM(0, to, DISP32); + write32(MEMADDR(from, 4)); +} + +emitterT void eSSE4_PMOVSXDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x25380F); + ModRM(3, to, from); +} + +emitterT void eSSE4_PINSRD_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x223A0F); + ModRM(3, to, from); + write8(imm8); +} + +emitterT void eSSE4_PMAXSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x3D380F); + ModRM(3, to, from); +} + +emitterT void eSSE4_PMINSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x39380F); + ModRM(3, to, from); +} + +emitterT void eSSE4_PMAXUD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x3F380F); + ModRM(3, to, from); +} + +emitterT void eSSE4_PMINUD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x3B380F); + ModRM(3, to, from); +} + +emitterT void eSSE4_PMAXSD_M128_to_XMM(x86SSERegType to, uptr from) +{ + write8(0x66); + RexR(0, to); + write24(0x3D380F); + ModRM( 0, to, DISP32 ); + write32(MEMADDR(from, 4)); +} + +emitterT void eSSE4_PMINSD_M128_to_XMM(x86SSERegType to, uptr from) +{ + write8(0x66); + RexR(0, to); + write24(0x39380F); + ModRM( 0, to, DISP32 ); + write32(MEMADDR(from, 4)); +} + +emitterT void eSSE4_PMAXUD_M128_to_XMM(x86SSERegType to, uptr from) +{ + write8(0x66); + RexR(0, to); + write24(0x3F380F); + ModRM( 0, to, DISP32 ); + write32(MEMADDR(from, 4)); +} + +emitterT void eSSE4_PMINUD_M128_to_XMM(x86SSERegType to, uptr from) +{ + write8(0x66); + RexR(0, to); + write24(0x3B380F); + ModRM( 0, to, DISP32 ); + write32(MEMADDR(from, 4)); +} + +emitterT void eSSE4_PMULDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + write8(0x66); + RexRB(0, to, from); + write24(0x28380F); + ModRM(3, to, from); +} + +// SSE-X +__forceinline void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQA_M128_to_XMM(to, from); + else SSE_MOVAPS_M128_to_XMM(to, from); +} + +__forceinline void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_M128(to, from); + else SSE_MOVAPS_XMM_to_M128(to, from); +} + +__forceinline void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_XMM(to, from); + else SSE_MOVAPS_XMM_to_XMM(to, from); +} + +__forceinline void SSEX_MOVDQARmtoROffset( x86SSERegType to, x86IntRegType from, int offset ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQARmtoROffset(to, from, offset); + else SSE_MOVAPSRmtoROffset(to, from, offset); +} + +__forceinline void SSEX_MOVDQARtoRmOffset( x86IntRegType to, x86SSERegType from, int offset ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQARtoRmOffset(to, from, offset); + else SSE_MOVAPSRtoRmOffset(to, from, offset); +} + +__forceinline void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQU_M128_to_XMM(to, from); + else SSE_MOVAPS_M128_to_XMM(to, from); +} + +__forceinline void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQU_XMM_to_M128(to, from); + else SSE_MOVAPS_XMM_to_M128(to, from); +} + +__forceinline void SSEX_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQU_XMM_to_XMM(to, from); + else SSE_MOVAPS_XMM_to_XMM(to, from); +} + +__forceinline void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_M32_to_XMM(to, from); + else SSE_MOVSS_M32_to_XMM(to, from); +} + +__forceinline void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_M32(to, from); + else SSE_MOVSS_XMM_to_M32(to, from); +} + +__forceinline void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_Rm(to, from); + else SSE_MOVSS_XMM_to_Rm(to, from); +} + +__forceinline void SSEX_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_RmOffset_to_XMM(to, from, offset); + else SSE_MOVSS_RmOffset_to_XMM(to, from, offset); +} + +__forceinline void SSEX_MOVD_XMM_to_RmOffset( x86IntRegType to, x86SSERegType from, int offset ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_RmOffset(to, from, offset); + else SSE_MOVSS_XMM_to_RmOffset(to, from, offset); +} + +__forceinline void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_POR_M128_to_XMM(to, from); + else SSE_ORPS_M128_to_XMM(to, from); +} + +__forceinline void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_POR_XMM_to_XMM(to, from); + else SSE_ORPS_XMM_to_XMM(to, from); +} + +__forceinline void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PXOR_M128_to_XMM(to, from); + else SSE_XORPS_M128_to_XMM(to, from); +} + +__forceinline void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PXOR_XMM_to_XMM(to, from); + else SSE_XORPS_XMM_to_XMM(to, from); +} + +__forceinline void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PAND_M128_to_XMM(to, from); + else SSE_ANDPS_M128_to_XMM(to, from); +} + +__forceinline void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PAND_XMM_to_XMM(to, from); + else SSE_ANDPS_XMM_to_XMM(to, from); +} + +__forceinline void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from ) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PANDN_M128_to_XMM(to, from); + else SSE_ANDNPS_M128_to_XMM(to, from); +} + +__forceinline void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PANDN_XMM_to_XMM(to, from); + else SSE_ANDNPS_XMM_to_XMM(to, from); +} + +__forceinline void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKLDQ_M128_to_XMM(to, from); + else SSE_UNPCKLPS_M128_to_XMM(to, from); +} + +__forceinline void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKLDQ_XMM_to_XMM(to, from); + else SSE_UNPCKLPS_XMM_to_XMM(to, from); +} + +__forceinline void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from) +{ + if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKHDQ_M128_to_XMM(to, from); + else SSE_UNPCKHPS_M128_to_XMM(to, from); +} + +__forceinline void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) +{ + if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKHDQ_XMM_to_XMM(to, from); + else SSE_UNPCKHPS_XMM_to_XMM(to, from); +} + +__forceinline void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) +{ + if( g_xmmtypes[from] == XMMT_INT ) { + SSE2_PUNPCKHQDQ_XMM_to_XMM(to, from); + if( to != from ) SSE2_PSHUFD_XMM_to_XMM(to, to, 0x4e); + } + else { + SSE_MOVHLPS_XMM_to_XMM(to, from); + } +} \ No newline at end of file diff --git a/pcsx2/x86/microVU_Lower.cpp b/pcsx2/x86/microVU_Lower.cpp index fa2e149909..e36a9dfa9b 100644 --- a/pcsx2/x86/microVU_Lower.cpp +++ b/pcsx2/x86/microVU_Lower.cpp @@ -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