2009-09-08 12:08:10 +00:00
|
|
|
/* PCSX2 - PS2 Emulator for PCs
|
|
|
|
* Copyright (C) 2002-2009 PCSX2 Dev Team
|
2009-10-18 19:26:07 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
2009-04-14 01:26:57 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 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 PCSX2.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
2009-04-14 01:26:57 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ix86 definitions v0.9.0
|
|
|
|
*
|
|
|
|
* Original Authors (v0.6.2 and prior):
|
|
|
|
* linuzappz <linuzappz@pcsx.net>
|
|
|
|
* alexey silinov
|
|
|
|
* goldfinger
|
|
|
|
* zerofrog(@gmail.com)
|
|
|
|
*
|
|
|
|
* Authors of v0.9.0:
|
|
|
|
* Jake.Stine(@gmail.com)
|
|
|
|
* cottonvibes(@gmail.com)
|
|
|
|
* sudonim(1@gmail.com)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
namespace x86Emitter
|
|
|
|
{
|
2009-04-29 04:24:46 +00:00
|
|
|
extern void xStoreReg( const xRegisterSSE& src );
|
|
|
|
extern void xRestoreReg( const xRegisterSSE& dest );
|
|
|
|
|
2009-04-19 02:14:50 +00:00
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Group 1 Instruction Class
|
|
|
|
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::xImpl_G1Logic<Internal::G1Type_AND,0x54> xAND;
|
|
|
|
extern const Internal::xImpl_G1Logic<Internal::G1Type_OR,0x56> xOR;
|
|
|
|
extern const Internal::xImpl_G1Logic<Internal::G1Type_XOR,0x57> xXOR;
|
2009-04-20 00:06:51 +00:00
|
|
|
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::xImpl_G1Arith<Internal::G1Type_ADD,0x58> xADD;
|
|
|
|
extern const Internal::xImpl_G1Arith<Internal::G1Type_SUB,0x5c> xSUB;
|
|
|
|
extern const Internal::xImpl_G1Compare xCMP;
|
2009-04-20 03:10:05 +00:00
|
|
|
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::xImpl_Group1<Internal::G1Type_ADC> xADC;
|
|
|
|
extern const Internal::xImpl_Group1<Internal::G1Type_SBB> xSBB;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Group 2 Instruction Class
|
|
|
|
//
|
|
|
|
// Optimization Note: For Imm forms, we ignore the instruction if the shift count is
|
|
|
|
// zero. This is a safe optimization since any zero-value shift does not affect any
|
|
|
|
// flags.
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::MovImplAll xMOV;
|
2009-04-24 11:25:10 +00:00
|
|
|
extern const Internal::xImpl_Test xTEST;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::Group2ImplAll<Internal::G2Type_ROL> xROL;
|
|
|
|
extern const Internal::Group2ImplAll<Internal::G2Type_ROR> xROR;
|
|
|
|
extern const Internal::Group2ImplAll<Internal::G2Type_RCL> xRCL;
|
|
|
|
extern const Internal::Group2ImplAll<Internal::G2Type_RCR> xRCR;
|
|
|
|
extern const Internal::Group2ImplAll<Internal::G2Type_SHL> xSHL;
|
|
|
|
extern const Internal::Group2ImplAll<Internal::G2Type_SHR> xSHR;
|
|
|
|
extern const Internal::Group2ImplAll<Internal::G2Type_SAR> xSAR;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Group 3 Instruction Class
|
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern const Internal::xImpl_Group3<Internal::G3Type_NOT> xNOT;
|
|
|
|
extern const Internal::xImpl_Group3<Internal::G3Type_NEG> xNEG;
|
|
|
|
extern const Internal::xImpl_Group3<Internal::G3Type_MUL> xUMUL;
|
|
|
|
extern const Internal::xImpl_Group3<Internal::G3Type_DIV> xUDIV;
|
|
|
|
extern const Internal::xImpl_iDiv xDIV;
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::xImpl_iMul xMUL;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern const Internal::xImpl_IncDec<false> xINC;
|
|
|
|
extern const Internal::xImpl_IncDec<true> xDEC;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::MovExtendImplAll<false> xMOVZX;
|
|
|
|
extern const Internal::MovExtendImplAll<true> xMOVSX;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::DwordShiftImplAll<false> xSHLD;
|
|
|
|
extern const Internal::DwordShiftImplAll<true> xSHRD;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern const Internal::xImpl_Group8<Internal::G8Type_BT> xBT;
|
|
|
|
extern const Internal::xImpl_Group8<Internal::G8Type_BTR> xBTR;
|
|
|
|
extern const Internal::xImpl_Group8<Internal::G8Type_BTS> xBTS;
|
|
|
|
extern const Internal::xImpl_Group8<Internal::G8Type_BTC> xBTC;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern const Internal::xImpl_JmpCall<true> xJMP;
|
|
|
|
extern const Internal::xImpl_JmpCall<false> xCALL;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern const Internal::xImpl_BitScan<0xbc> xBSF;
|
|
|
|
extern const Internal::xImpl_BitScan<0xbd> xBSR;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::CMovImplGeneric xCMOV;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::CMovImplAll<Jcc_Above> xCMOVA;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_AboveOrEqual> xCMOVAE;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_Below> xCMOVB;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_BelowOrEqual> xCMOVBE;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::CMovImplAll<Jcc_Greater> xCMOVG;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_GreaterOrEqual> xCMOVGE;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_Less> xCMOVL;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_LessOrEqual> xCMOVLE;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::CMovImplAll<Jcc_Zero> xCMOVZ;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_Equal> xCMOVE;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_NotZero> xCMOVNZ;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_NotEqual> xCMOVNE;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::CMovImplAll<Jcc_Overflow> xCMOVO;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_NotOverflow> xCMOVNO;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_Carry> xCMOVC;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_NotCarry> xCMOVNC;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::CMovImplAll<Jcc_Signed> xCMOVS;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_Unsigned> xCMOVNS;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_ParityEven> xCMOVPE;
|
|
|
|
extern const Internal::CMovImplAll<Jcc_ParityOdd> xCMOVPO;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::SetImplGeneric xSET;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::SetImplAll<Jcc_Above> xSETA;
|
|
|
|
extern const Internal::SetImplAll<Jcc_AboveOrEqual> xSETAE;
|
|
|
|
extern const Internal::SetImplAll<Jcc_Below> xSETB;
|
|
|
|
extern const Internal::SetImplAll<Jcc_BelowOrEqual> xSETBE;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::SetImplAll<Jcc_Greater> xSETG;
|
|
|
|
extern const Internal::SetImplAll<Jcc_GreaterOrEqual> xSETGE;
|
|
|
|
extern const Internal::SetImplAll<Jcc_Less> xSETL;
|
|
|
|
extern const Internal::SetImplAll<Jcc_LessOrEqual> xSETLE;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::SetImplAll<Jcc_Zero> xSETZ;
|
|
|
|
extern const Internal::SetImplAll<Jcc_Equal> xSETE;
|
|
|
|
extern const Internal::SetImplAll<Jcc_NotZero> xSETNZ;
|
|
|
|
extern const Internal::SetImplAll<Jcc_NotEqual> xSETNE;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::SetImplAll<Jcc_Overflow> xSETO;
|
|
|
|
extern const Internal::SetImplAll<Jcc_NotOverflow> xSETNO;
|
|
|
|
extern const Internal::SetImplAll<Jcc_Carry> xSETC;
|
|
|
|
extern const Internal::SetImplAll<Jcc_NotCarry> xSETNC;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::SetImplAll<Jcc_Signed> xSETS;
|
|
|
|
extern const Internal::SetImplAll<Jcc_Unsigned> xSETNS;
|
|
|
|
extern const Internal::SetImplAll<Jcc_ParityEven> xSETPE;
|
|
|
|
extern const Internal::SetImplAll<Jcc_ParityOdd> xSETPO;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Miscellaneous Instructions
|
|
|
|
// These are all defined inline or in ix86.cpp.
|
|
|
|
//
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern void xBSWAP( const xRegister32& to );
|
2009-04-15 15:45:52 +00:00
|
|
|
|
2009-04-14 01:26:57 +00:00
|
|
|
// ----- Lea Instructions (Load Effective Address) -----
|
|
|
|
// Note: alternate (void*) forms of these instructions are not provided since those
|
|
|
|
// forms are functionally equivalent to Mov reg,imm, and thus better written as MOVs
|
|
|
|
// instead.
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern void xLEA( xRegister32 to, const ModSibBase& src, bool preserve_flags=false );
|
|
|
|
extern void xLEA( xRegister16 to, const ModSibBase& src, bool preserve_flags=false );
|
2009-04-14 01:26:57 +00:00
|
|
|
|
|
|
|
// ----- Push / Pop Instructions -----
|
2009-04-15 21:00:32 +00:00
|
|
|
// Note: pushad/popad implementations are intentionally left out. The instructions are
|
|
|
|
// invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead.
|
2009-04-14 01:26:57 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern void xPOP( const ModSibBase& from );
|
|
|
|
extern void xPUSH( const ModSibBase& from );
|
2009-04-15 21:00:32 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern void xPOP( xRegister32 from );
|
2009-04-15 21:00:32 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern void xPUSH( u32 imm );
|
|
|
|
extern void xPUSH( xRegister32 from );
|
2009-04-15 21:00:32 +00:00
|
|
|
|
|
|
|
// pushes the EFLAGS register onto the stack
|
2009-04-24 11:25:10 +00:00
|
|
|
extern void xPUSHFD();
|
2009-04-15 21:00:32 +00:00
|
|
|
// pops the EFLAGS register from the stack
|
2009-04-24 11:25:10 +00:00
|
|
|
extern void xPOPFD();
|
2009-04-15 21:00:32 +00:00
|
|
|
|
|
|
|
// ----- Miscellaneous Instructions -----
|
|
|
|
// Various Instructions with no parameter and no special encoding logic.
|
|
|
|
|
2009-10-18 19:26:07 +00:00
|
|
|
extern void xLEAVE();
|
2009-04-24 11:25:10 +00:00
|
|
|
extern void xRET();
|
|
|
|
extern void xCBW();
|
|
|
|
extern void xCWD();
|
|
|
|
extern void xCDQ();
|
|
|
|
extern void xCWDE();
|
2009-04-15 21:00:32 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern void xLAHF();
|
|
|
|
extern void xSAHF();
|
2009-04-15 21:00:32 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
extern void xSTC();
|
|
|
|
extern void xCLC();
|
2009-04-15 21:00:32 +00:00
|
|
|
|
|
|
|
// NOP 1-byte
|
2009-04-24 11:25:10 +00:00
|
|
|
extern void xNOP();
|
2009-04-15 15:45:52 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// JMP / Jcc Instructions!
|
|
|
|
|
2009-04-24 13:49:00 +00:00
|
|
|
extern void xJcc( JccComparisonType comparison, const void* target );
|
2009-05-07 08:21:57 +00:00
|
|
|
extern s8* xJcc8( JccComparisonType comparison=Jcc_Unconditional, s8 displacement=0 );
|
|
|
|
extern s32* xJcc32( JccComparisonType comparison=Jcc_Unconditional, s32 displacement=0 );
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-24 11:25:10 +00:00
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Conditional jumps to fixed targets.
|
|
|
|
// Jumps accept any pointer as a valid target (function or data), and will generate either
|
|
|
|
// 8 or 32 bit displacement versions of the jump, depending on relative displacement of
|
|
|
|
// the target (efficient!)
|
|
|
|
//
|
|
|
|
|
2009-04-24 13:49:00 +00:00
|
|
|
template< typename T > __forceinline void xJE( T* func ) { xJcc( Jcc_Equal, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJZ( T* func ) { xJcc( Jcc_Zero, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJNE( T* func ) { xJcc( Jcc_NotEqual, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJNZ( T* func ) { xJcc( Jcc_NotZero, (void*)(uptr)func ); }
|
|
|
|
|
|
|
|
template< typename T > __forceinline void xJO( T* func ) { xJcc( Jcc_Overflow, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJNO( T* func ) { xJcc( Jcc_NotOverflow, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJC( T* func ) { xJcc( Jcc_Carry, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJNC( T* func ) { xJcc( Jcc_NotCarry, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJS( T* func ) { xJcc( Jcc_Signed, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJNS( T* func ) { xJcc( Jcc_Unsigned, (void*)(uptr)func ); }
|
|
|
|
|
|
|
|
template< typename T > __forceinline void xJPE( T* func ) { xJcc( Jcc_ParityEven, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJPO( T* func ) { xJcc( Jcc_ParityOdd, (void*)(uptr)func ); }
|
|
|
|
|
|
|
|
template< typename T > __forceinline void xJL( T* func ) { xJcc( Jcc_Less, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJLE( T* func ) { xJcc( Jcc_LessOrEqual, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJG( T* func ) { xJcc( Jcc_Greater, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJGE( T* func ) { xJcc( Jcc_GreaterOrEqual, (void*)(uptr)func ); }
|
|
|
|
|
|
|
|
template< typename T > __forceinline void xJB( T* func ) { xJcc( Jcc_Below, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJBE( T* func ) { xJcc( Jcc_BelowOrEqual, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJA( T* func ) { xJcc( Jcc_Above, (void*)(uptr)func ); }
|
|
|
|
template< typename T > __forceinline void xJAE( T* func ) { xJcc( Jcc_AboveOrEqual, (void*)(uptr)func ); }
|
2009-04-24 11:25:10 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Forward Jump Helpers (act as labels!)
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-04-15 15:45:52 +00:00
|
|
|
#define DEFINE_FORWARD_JUMP( label, cond ) \
|
|
|
|
template< typename OperandType > \
|
2009-04-20 03:10:05 +00:00
|
|
|
class xForward##label : public xForwardJump<OperandType> \
|
2009-04-15 15:45:52 +00:00
|
|
|
{ \
|
|
|
|
public: \
|
2009-04-20 03:10:05 +00:00
|
|
|
xForward##label() : xForwardJump<OperandType>( cond ) {} \
|
2009-04-15 15:45:52 +00:00
|
|
|
};
|
2009-04-14 01:26:57 +00:00
|
|
|
|
2009-04-15 15:45:52 +00:00
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Note: typedefs below are defined individually in order to appease Intellisense
|
|
|
|
// resolution. Including them into the class definition macro above breaks it.
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
typedef xForwardJump<s8> xForwardJump8;
|
|
|
|
typedef xForwardJump<s32> xForwardJump32;
|
2009-04-15 15:45:52 +00:00
|
|
|
|
|
|
|
DEFINE_FORWARD_JUMP( JA, Jcc_Above );
|
|
|
|
DEFINE_FORWARD_JUMP( JB, Jcc_Below );
|
|
|
|
DEFINE_FORWARD_JUMP( JAE, Jcc_AboveOrEqual );
|
|
|
|
DEFINE_FORWARD_JUMP( JBE, Jcc_BelowOrEqual );
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
typedef xForwardJA<s8> xForwardJA8;
|
|
|
|
typedef xForwardJA<s32> xForwardJA32;
|
|
|
|
typedef xForwardJB<s8> xForwardJB8;
|
|
|
|
typedef xForwardJB<s32> xForwardJB32;
|
|
|
|
typedef xForwardJAE<s8> xForwardJAE8;
|
|
|
|
typedef xForwardJAE<s32> xForwardJAE32;
|
|
|
|
typedef xForwardJBE<s8> xForwardJBE8;
|
|
|
|
typedef xForwardJBE<s32> xForwardJBE32;
|
2009-04-15 15:45:52 +00:00
|
|
|
|
|
|
|
DEFINE_FORWARD_JUMP( JG, Jcc_Greater );
|
|
|
|
DEFINE_FORWARD_JUMP( JL, Jcc_Less );
|
|
|
|
DEFINE_FORWARD_JUMP( JGE, Jcc_GreaterOrEqual );
|
|
|
|
DEFINE_FORWARD_JUMP( JLE, Jcc_LessOrEqual );
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
typedef xForwardJG<s8> xForwardJG8;
|
|
|
|
typedef xForwardJG<s32> xForwardJG32;
|
|
|
|
typedef xForwardJL<s8> xForwardJL8;
|
|
|
|
typedef xForwardJL<s32> xForwardJL32;
|
|
|
|
typedef xForwardJGE<s8> xForwardJGE8;
|
|
|
|
typedef xForwardJGE<s32> xForwardJGE32;
|
|
|
|
typedef xForwardJLE<s8> xForwardJLE8;
|
|
|
|
typedef xForwardJLE<s32> xForwardJLE32;
|
2009-04-15 15:45:52 +00:00
|
|
|
|
|
|
|
DEFINE_FORWARD_JUMP( JZ, Jcc_Zero );
|
|
|
|
DEFINE_FORWARD_JUMP( JE, Jcc_Equal );
|
|
|
|
DEFINE_FORWARD_JUMP( JNZ, Jcc_NotZero );
|
|
|
|
DEFINE_FORWARD_JUMP( JNE, Jcc_NotEqual );
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
typedef xForwardJZ<s8> xForwardJZ8;
|
|
|
|
typedef xForwardJZ<s32> xForwardJZ32;
|
|
|
|
typedef xForwardJE<s8> xForwardJE8;
|
|
|
|
typedef xForwardJE<s32> xForwardJE32;
|
|
|
|
typedef xForwardJNZ<s8> xForwardJNZ8;
|
|
|
|
typedef xForwardJNZ<s32> xForwardJNZ32;
|
|
|
|
typedef xForwardJNE<s8> xForwardJNE8;
|
|
|
|
typedef xForwardJNE<s32> xForwardJNE32;
|
2009-04-15 15:45:52 +00:00
|
|
|
|
|
|
|
DEFINE_FORWARD_JUMP( JS, Jcc_Signed );
|
|
|
|
DEFINE_FORWARD_JUMP( JNS, Jcc_Unsigned );
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
typedef xForwardJS<s8> xForwardJS8;
|
|
|
|
typedef xForwardJS<s32> xForwardJS32;
|
|
|
|
typedef xForwardJNS<s8> xForwardJNS8;
|
|
|
|
typedef xForwardJNS<s32> xForwardJNS32;
|
2009-04-15 15:45:52 +00:00
|
|
|
|
|
|
|
DEFINE_FORWARD_JUMP( JO, Jcc_Overflow );
|
|
|
|
DEFINE_FORWARD_JUMP( JNO, Jcc_NotOverflow );
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
typedef xForwardJO<s8> xForwardJO8;
|
|
|
|
typedef xForwardJO<s32> xForwardJO32;
|
|
|
|
typedef xForwardJNO<s8> xForwardJNO8;
|
|
|
|
typedef xForwardJNO<s32> xForwardJNO32;
|
2009-04-15 15:45:52 +00:00
|
|
|
|
|
|
|
DEFINE_FORWARD_JUMP( JC, Jcc_Carry );
|
|
|
|
DEFINE_FORWARD_JUMP( JNC, Jcc_NotCarry );
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
typedef xForwardJC<s8> xForwardJC8;
|
|
|
|
typedef xForwardJC<s32> xForwardJC32;
|
|
|
|
typedef xForwardJNC<s8> xForwardJNC8;
|
|
|
|
typedef xForwardJNC<s32> xForwardJNC32;
|
2009-04-15 15:45:52 +00:00
|
|
|
|
|
|
|
DEFINE_FORWARD_JUMP( JPE, Jcc_ParityEven );
|
|
|
|
DEFINE_FORWARD_JUMP( JPO, Jcc_ParityOdd );
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
typedef xForwardJPE<s8> xForwardJPE8;
|
|
|
|
typedef xForwardJPE<s32> xForwardJPE32;
|
|
|
|
typedef xForwardJPO<s8> xForwardJPO8;
|
|
|
|
typedef xForwardJPO<s32> xForwardJPO32;
|
2009-04-19 02:14:50 +00:00
|
|
|
|
2009-04-19 05:24:20 +00:00
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
|
2009-04-23 12:39:59 +00:00
|
|
|
extern void xEMMS();
|
|
|
|
extern void xSTMXCSR( u32* dest );
|
|
|
|
extern void xLDMXCSR( const u32* src );
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-23 12:39:59 +00:00
|
|
|
extern void xMOVDZX( const xRegisterSSE& to, const xRegister32& from );
|
|
|
|
extern void xMOVDZX( const xRegisterSSE& to, const ModSibBase& src );
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-23 12:39:59 +00:00
|
|
|
extern void xMOVDZX( const xRegisterMMX& to, const xRegister32& from );
|
|
|
|
extern void xMOVDZX( const xRegisterMMX& to, const ModSibBase& src );
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-23 12:39:59 +00:00
|
|
|
extern void xMOVD( const xRegister32& to, const xRegisterSSE& from );
|
|
|
|
extern void xMOVD( const ModSibBase& dest, const xRegisterSSE& from );
|
2009-04-19 16:34:29 +00:00
|
|
|
|
2009-04-23 12:39:59 +00:00
|
|
|
extern void xMOVD( const xRegister32& to, const xRegisterMMX& from );
|
|
|
|
extern void xMOVD( const ModSibBase& dest, const xRegisterMMX& from );
|
2009-04-21 05:29:14 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern void xMOVQ( const xRegisterMMX& to, const xRegisterMMX& from );
|
|
|
|
extern void xMOVQ( const xRegisterMMX& to, const xRegisterSSE& from );
|
|
|
|
extern void xMOVQ( const xRegisterSSE& to, const xRegisterMMX& from );
|
|
|
|
|
|
|
|
extern void xMOVQ( const ModSibBase& dest, const xRegisterSSE& from );
|
|
|
|
extern void xMOVQ( const ModSibBase& dest, const xRegisterMMX& from );
|
|
|
|
extern void xMOVQ( const xRegisterMMX& to, const ModSibBase& src );
|
|
|
|
|
|
|
|
extern void xMOVQZX( const xRegisterSSE& to, const ModSibBase& src );
|
|
|
|
extern void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from );
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern void xMOVSS( const xRegisterSSE& to, const xRegisterSSE& from );
|
|
|
|
extern void xMOVSS( const ModSibBase& to, const xRegisterSSE& from );
|
|
|
|
extern void xMOVSD( const xRegisterSSE& to, const xRegisterSSE& from );
|
|
|
|
extern void xMOVSD( const ModSibBase& to, const xRegisterSSE& from );
|
|
|
|
|
|
|
|
extern void xMOVSSZX( const xRegisterSSE& to, const ModSibBase& from );
|
|
|
|
extern void xMOVSDZX( const xRegisterSSE& to, const ModSibBase& from );
|
|
|
|
|
|
|
|
extern void xMOVNTDQA( const xRegisterSSE& to, const ModSibBase& from );
|
|
|
|
extern void xMOVNTDQA( const ModSibBase& to, const xRegisterSSE& from );
|
|
|
|
|
|
|
|
extern void xMOVNTPD( const ModSibBase& to, const xRegisterSSE& from );
|
|
|
|
extern void xMOVNTPS( const ModSibBase& to, const xRegisterSSE& from );
|
|
|
|
extern void xMOVNTQ( const ModSibBase& to, const xRegisterMMX& from );
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-21 21:42:33 +00:00
|
|
|
extern void xMOVMSKPS( const xRegister32& to, const xRegisterSSE& from );
|
|
|
|
extern void xMOVMSKPD( const xRegister32& to, const xRegisterSSE& from );
|
2009-04-21 05:29:14 +00:00
|
|
|
|
2009-04-23 12:39:59 +00:00
|
|
|
extern void xMASKMOV( const xRegisterSSE& to, const xRegisterSSE& from );
|
|
|
|
extern void xMASKMOV( const xRegisterMMX& to, const xRegisterMMX& from );
|
|
|
|
extern void xPMOVMSKB( const xRegister32& to, const xRegisterSSE& from );
|
|
|
|
extern void xPMOVMSKB( const xRegister32& to, const xRegisterMMX& from );
|
|
|
|
extern void xPALIGNR( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
|
|
|
|
extern void xPALIGNR( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm8 );
|
2009-04-21 21:30:47 +00:00
|
|
|
|
2009-04-20 15:22:02 +00:00
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
|
2009-04-23 12:39:59 +00:00
|
|
|
extern const Internal::SimdImpl_MoveSSE<0x00,true> xMOVAPS;
|
|
|
|
extern const Internal::SimdImpl_MoveSSE<0x00,false> xMOVUPS;
|
2009-04-20 00:06:51 +00:00
|
|
|
|
|
|
|
#ifdef ALWAYS_USE_MOVAPS
|
2009-04-23 12:39:59 +00:00
|
|
|
extern const Internal::SimdImpl_MoveSSE<0,true> xMOVDQA;
|
|
|
|
extern const Internal::SimdImpl_MoveSSE<0,false> xMOVDQU;
|
|
|
|
extern const Internal::SimdImpl_MoveSSE<0,true> xMOVAPD;
|
|
|
|
extern const Internal::SimdImpl_MoveSSE<0,false> xMOVUPD;
|
2009-04-20 00:06:51 +00:00
|
|
|
#else
|
2009-04-23 12:39:59 +00:00
|
|
|
extern const Internal::SimdImpl_MoveDQ<0x66, 0x6f, 0x7f> xMOVDQA;
|
|
|
|
extern const Internal::SimdImpl_MoveDQ<0xf3, 0x6f, 0x7f> xMOVDQU;
|
|
|
|
extern const Internal::SimdImpl_MoveSSE<0x66,true> xMOVAPD;
|
|
|
|
extern const Internal::SimdImpl_MoveSSE<0x66,false> xMOVUPD;
|
2009-04-20 00:06:51 +00:00
|
|
|
#endif
|
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::MovhlImpl_RtoR<0x16> xMOVLH;
|
|
|
|
extern const Internal::MovhlImpl_RtoR<0x12> xMOVHL;
|
2009-04-20 00:06:51 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
extern const Internal::MovhlImplAll<0x16> xMOVH;
|
|
|
|
extern const Internal::MovhlImplAll<0x12> xMOVL;
|
2009-04-20 00:06:51 +00:00
|
|
|
|
2009-04-23 12:39:59 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegSSE<0xf3,0x12> xMOVSLDUP;
|
|
|
|
extern const Internal::SimdImpl_DestRegSSE<0xf3,0x16> xMOVSHDUP;
|
|
|
|
|
|
|
|
extern void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
|
|
|
|
extern void xINSERTPS( const xRegisterSSE& to, const ModSibStrict<u32>& from, u8 imm8 );
|
|
|
|
|
|
|
|
extern void xEXTRACTPS( const xRegister32& to, const xRegisterSSE& from, u8 imm8 );
|
|
|
|
extern void xEXTRACTPS( const ModSibStrict<u32>& dest, const xRegisterSSE& from, u8 imm8 );
|
|
|
|
|
2009-04-20 15:22:02 +00:00
|
|
|
// ------------------------------------------------------------------------
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-04-21 05:29:14 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegEither<0x66,0xdb> xPAND;
|
|
|
|
extern const Internal::SimdImpl_DestRegEither<0x66,0xdf> xPANDN;
|
|
|
|
extern const Internal::SimdImpl_DestRegEither<0x66,0xeb> xPOR;
|
|
|
|
extern const Internal::SimdImpl_DestRegEither<0x66,0xef> xPXOR;
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-04-19 16:34:29 +00:00
|
|
|
|
2009-05-19 23:37:20 +00:00
|
|
|
extern const Internal::SimdImpl_COMI<true> xCOMI;
|
|
|
|
extern const Internal::SimdImpl_COMI<false> xUCOMI;
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-05-19 23:37:20 +00:00
|
|
|
extern const Internal::SimdImpl_MinMax<0x5f> xMAX;
|
|
|
|
extern const Internal::SimdImpl_MinMax<0x5d> xMIN;
|
|
|
|
extern const Internal::SimdImpl_Shuffle<0xc6> xSHUF;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-20 03:10:05 +00:00
|
|
|
// ------------------------------------------------------------------------
|
2009-04-23 12:39:59 +00:00
|
|
|
|
|
|
|
extern const Internal::SimdImpl_DestRegSSE<0x66,0x1738> xPTEST;
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-04-21 05:29:14 +00:00
|
|
|
extern const Internal::SimdImpl_Compare<SSE2_Equal> xCMPEQ;
|
|
|
|
extern const Internal::SimdImpl_Compare<SSE2_Less> xCMPLT;
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::SimdImpl_Compare<SSE2_LessOrEqual> xCMPLE;
|
2009-04-21 05:29:14 +00:00
|
|
|
extern const Internal::SimdImpl_Compare<SSE2_Unordered> xCMPUNORD;
|
|
|
|
extern const Internal::SimdImpl_Compare<SSE2_NotEqual> xCMPNE;
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::SimdImpl_Compare<SSE2_NotLess> xCMPNLT;
|
|
|
|
extern const Internal::SimdImpl_Compare<SSE2_NotLessOrEqual> xCMPNLE;
|
|
|
|
extern const Internal::SimdImpl_Compare<SSE2_Ordered> xCMPORD;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// OMG Evil. I went cross-eyed an hour ago doing this.
|
|
|
|
//
|
2009-04-21 01:40:45 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf3,0xe6,xRegisterSSE,xRegisterSSE,u64> xCVTDQ2PD;
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x00,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTDQ2PS;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf2,0xe6,xRegisterSSE,xRegisterSSE,u128> xCVTPD2DQ;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x66,0x2d,xRegisterMMX,xRegisterSSE,u128> xCVTPD2PI;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x66,0x5a,xRegisterSSE,xRegisterSSE,u128> xCVTPD2PS;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-21 01:40:45 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x66,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PD;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x00,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PS;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x66,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTPS2DQ;
|
2009-04-21 01:40:45 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x00,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTPS2PD;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x00,0x2d,xRegisterMMX,xRegisterSSE,u64> xCVTPS2PI;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-21 01:40:45 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf2,0x2d,xRegister32, xRegisterSSE,u64> xCVTSD2SI;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf2,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTSD2SS;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf2,0x2a,xRegisterMMX,xRegister32, u32> xCVTSI2SD;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf3,0x2a,xRegisterSSE,xRegister32, u32> xCVTSI2SS;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-21 01:40:45 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf3,0x5a,xRegisterSSE,xRegisterSSE,u32> xCVTSS2SD;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf3,0x2d,xRegister32, xRegisterSSE,u32> xCVTSS2SI;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-20 19:25:35 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x66,0xe6,xRegisterSSE,xRegisterSSE,u128> xCVTTPD2DQ;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x66,0x2c,xRegisterMMX,xRegisterSSE,u128> xCVTTPD2PI;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf3,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTTPS2DQ;
|
2009-04-21 01:40:45 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0x00,0x2c,xRegisterMMX,xRegisterSSE,u64> xCVTTPS2PI;
|
2009-04-20 15:22:02 +00:00
|
|
|
|
2009-04-21 01:40:45 +00:00
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf2,0x2c,xRegister32, xRegisterSSE,u64> xCVTTSD2SI;
|
|
|
|
extern const Internal::SimdImpl_DestRegStrict<0xf3,0x2c,xRegister32, xRegisterSSE,u32> xCVTTSS2SI;
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-04-20 19:25:35 +00:00
|
|
|
// ------------------------------------------------------------------------
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-10-24 19:06:11 +00:00
|
|
|
extern const xImplSimd_AndNot xANDN;
|
|
|
|
extern const xImplSimd_rSqrt xRCP;
|
|
|
|
extern const xImplSimd_rSqrt xRSQRT;
|
|
|
|
extern const xImplSimd_Sqrt xSQRT;
|
|
|
|
|
|
|
|
extern const xImplSimd_Shift xPSLL;
|
|
|
|
extern const xImplSimd_Shift xPSRL;
|
|
|
|
extern const xImplSimd_ShiftWithoutQ xPSRA;
|
|
|
|
extern const xImplSimd_AddSub xPADD;
|
|
|
|
extern const xImplSimd_AddSub xPSUB;
|
|
|
|
extern const xImplSimd_PMul xPMUL;
|
|
|
|
extern const xImplSimd_PAbsolute xPABS;
|
|
|
|
extern const xImplSimd_PSign xPSIGN;
|
|
|
|
extern const xImplSimd_PMultAdd xPMADD;
|
|
|
|
extern const xImplSimd_HorizAdd xHADD;
|
|
|
|
extern const xImplSimd_DotProduct xDP;
|
|
|
|
extern const xImplSimd_Round xROUND;
|
|
|
|
|
2009-04-21 01:40:45 +00:00
|
|
|
|
2009-05-19 23:37:20 +00:00
|
|
|
extern const Internal::SimdImpl_PMinMax<0xde,0x3c> xPMAX;
|
|
|
|
extern const Internal::SimdImpl_PMinMax<0xda,0x38> xPMIN;
|
|
|
|
|
|
|
|
extern const Internal::SimdImpl_PCompare xPCMP;
|
|
|
|
extern const Internal::SimdImpl_PShuffle xPSHUF;
|
|
|
|
extern const Internal::SimdImpl_PUnpack xPUNPCK;
|
|
|
|
extern const Internal::SimdImpl_Unpack xUNPCK;
|
|
|
|
extern const Internal::SimdImpl_Pack xPACK;
|
|
|
|
extern const Internal::SimdImpl_PInsert xPINSR;
|
|
|
|
extern const Internal::SimdImpl_PExtract xPEXTR;
|
|
|
|
extern const Internal::SimdImpl_Blend xBLEND;
|
2009-10-18 19:26:07 +00:00
|
|
|
|
2009-05-19 23:37:20 +00:00
|
|
|
extern const Internal::SimdImpl_PMove<true> xPMOVSX;
|
|
|
|
extern const Internal::SimdImpl_PMove<false> xPMOVZX;
|
2009-04-23 12:39:59 +00:00
|
|
|
|
2009-04-14 01:26:57 +00:00
|
|
|
}
|
|
|
|
|