mirror of https://github.com/PCSX2/pcsx2.git
Emitter: Yay! More instructions! All forms of PADD/PSUB/PSRL/PSLL. I'm getting closer!
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1032 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
cc48702b17
commit
73e50f49ea
|
@ -34,57 +34,81 @@ enum G1Type
|
|||
};
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
template< typename ImmType >
|
||||
class Group1Impl
|
||||
//
|
||||
template< G1Type InstType >
|
||||
class xImpl_Group1
|
||||
{
|
||||
protected:
|
||||
static const uint OperandSize = sizeof(ImmType);
|
||||
|
||||
static bool Is8BitOperand() { return OperandSize == 1; }
|
||||
static void prefix16() { if( OperandSize == 2 ) xWrite<u8>( 0x66 ); }
|
||||
|
||||
public:
|
||||
Group1Impl() {} // because GCC doesn't like static classes
|
||||
|
||||
static __emitinline void Emit( G1Type InstType, const xRegister<ImmType>& to, const xRegister<ImmType>& from )
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __forceinline void operator()( const xRegister<T>& to, const xRegister<T>& from ) const
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( (Is8BitOperand() ? 0 : 1) | (InstType<<3) );
|
||||
prefix16<T>();
|
||||
xWrite<u8>( (Is8BitOp<T>() ? 0 : 1) | (InstType<<3) );
|
||||
ModRM_Direct( from.Id, to.Id );
|
||||
}
|
||||
|
||||
static __emitinline void Emit( G1Type InstType, const ModSibBase& sibdest, const xRegister<ImmType>& from )
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __forceinline void operator()( const xRegister<T>& to, const void* src ) const
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( (Is8BitOperand() ? 0 : 1) | (InstType<<3) );
|
||||
EmitSibMagic( from.Id, sibdest );
|
||||
prefix16<T>();
|
||||
xWrite<u8>( (Is8BitOp<T>() ? 2 : 3) | (InstType<<3) );
|
||||
xWriteDisp( to.Id, src );
|
||||
}
|
||||
|
||||
static __emitinline void Emit( G1Type InstType, const xRegister<ImmType>& to, const ModSibBase& sibsrc )
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __forceinline void operator()( void* dest, const xRegister<T>& from ) const
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( (Is8BitOperand() ? 2 : 3) | (InstType<<3) );
|
||||
EmitSibMagic( to.Id, sibsrc );
|
||||
}
|
||||
|
||||
static __emitinline void Emit( G1Type InstType, void* dest, const xRegister<ImmType>& from )
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( (Is8BitOperand() ? 0 : 1) | (InstType<<3) );
|
||||
prefix16<T>();
|
||||
xWrite<u8>( (Is8BitOp<T>() ? 0 : 1) | (InstType<<3) );
|
||||
xWriteDisp( from.Id, dest );
|
||||
}
|
||||
|
||||
static __emitinline void Emit( G1Type InstType, const xRegister<ImmType>& to, const void* src )
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const ModSibBase& sibdest, const xRegister<T>& from ) const
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( (Is8BitOperand() ? 2 : 3) | (InstType<<3) );
|
||||
xWriteDisp( to.Id, src );
|
||||
prefix16<T>();
|
||||
xWrite<u8>( (Is8BitOp<T>() ? 0 : 1) | (InstType<<3) );
|
||||
EmitSibMagic( from.Id, sibdest );
|
||||
}
|
||||
|
||||
static __emitinline void Emit( G1Type InstType, const xRegister<ImmType>& to, int imm )
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const xRegister<T>& to, const ModSibBase& sibsrc ) const
|
||||
{
|
||||
prefix16();
|
||||
if( !Is8BitOperand() && is_s8( imm ) )
|
||||
prefix16<T>();
|
||||
xWrite<u8>( (Is8BitOp<T>() ? 2 : 3) | (InstType<<3) );
|
||||
EmitSibMagic( to.Id, sibsrc );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Note on Imm forms : use int as the source operand since it's "reasonably inert" from a compiler
|
||||
// perspective. (using uint tends to make the compiler try and fail to match signed immediates with
|
||||
// one of the other overloads).
|
||||
|
||||
template< typename T > __noinline void operator()( const ModSibStrict<T>& sibdest, int imm ) const
|
||||
{
|
||||
if( Is8BitOp<T>() )
|
||||
{
|
||||
xWrite<u8>( 0x80 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
xWrite<s8>( imm );
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix16<T>();
|
||||
xWrite<u8>( is_s8( imm ) ? 0x83 : 0x81 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
if( is_s8( imm ) )
|
||||
xWrite<s8>( imm );
|
||||
else
|
||||
xWrite<T>( imm );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __forceinline void operator()( const xRegister<T>& to, int imm ) const
|
||||
{
|
||||
prefix16<T>();
|
||||
if( !Is8BitOp<T>() && is_s8( imm ) )
|
||||
{
|
||||
xWrite<u8>( 0x83 );
|
||||
ModRM_Direct( InstType, to.Id );
|
||||
|
@ -93,65 +117,17 @@ public:
|
|||
else
|
||||
{
|
||||
if( to.IsAccumulator() )
|
||||
xWrite<u8>( (Is8BitOperand() ? 4 : 5) | (InstType<<3) );
|
||||
xWrite<u8>( (Is8BitOp<T>() ? 4 : 5) | (InstType<<3) );
|
||||
else
|
||||
{
|
||||
xWrite<u8>( Is8BitOperand() ? 0x80 : 0x81 );
|
||||
xWrite<u8>( Is8BitOp<T>() ? 0x80 : 0x81 );
|
||||
ModRM_Direct( InstType, to.Id );
|
||||
}
|
||||
xWrite<ImmType>( imm );
|
||||
xWrite<T>( imm );
|
||||
}
|
||||
}
|
||||
|
||||
static __emitinline void Emit( G1Type InstType, const ModSibStrict<ImmType>& sibdest, int imm )
|
||||
{
|
||||
if( Is8BitOperand() )
|
||||
{
|
||||
xWrite<u8>( 0x80 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
xWrite<ImmType>( imm );
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( is_s8( imm ) ? 0x83 : 0x81 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
if( is_s8( imm ) )
|
||||
xWrite<s8>( imm );
|
||||
else
|
||||
xWrite<ImmType>( imm );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
template< G1Type InstType >
|
||||
class Group1ImplAll
|
||||
{
|
||||
public:
|
||||
template< typename T >
|
||||
__forceinline void operator()( const xRegister<T>& to, const xRegister<T>& from ) const { Group1Impl<T>::Emit( InstType, to, from ); }
|
||||
template< typename T >
|
||||
__forceinline void operator()( const xRegister<T>& to, const void* src ) const { Group1Impl<T>::Emit( InstType, to, src ); }
|
||||
template< typename T >
|
||||
__forceinline void operator()( void* dest, const xRegister<T>& from ) const { Group1Impl<T>::Emit( InstType, dest, from ); }
|
||||
template< typename T >
|
||||
__noinline void operator()( const ModSibBase& sibdest, const xRegister<T>& from ) const { Group1Impl<T>::Emit( InstType, sibdest, from ); }
|
||||
template< typename T >
|
||||
__noinline void operator()( const xRegister<T>& to, const ModSibBase& sibsrc ) const { Group1Impl<T>::Emit( InstType, to, sibsrc ); }
|
||||
|
||||
// Note on Imm forms : use int as the source operand since it's "reasonably inert" from a compiler
|
||||
// perspective. (using uint tends to make the compiler try and fail to match signed immediates with
|
||||
// one of the other overloads).
|
||||
|
||||
template< typename T >
|
||||
__noinline void operator()( const ModSibStrict<T>& sibdest, int imm ) const { Group1Impl<T>::Emit( InstType, sibdest, imm ); }
|
||||
template< typename T >
|
||||
__forceinline void operator()( const xRegister<T>& to, int imm ) const { Group1Impl<T>::Emit( InstType, to, imm ); }
|
||||
|
||||
Group1ImplAll() {} // Why does GCC need these?
|
||||
xImpl_Group1() {} // Why does GCC need these?
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -159,34 +135,34 @@ public:
|
|||
// Note: ANDN [AndNot] is handled below separately.
|
||||
//
|
||||
template< G1Type InstType, u8 OpcodeSSE >
|
||||
class G1LogicImpl_PlusSSE : public Group1ImplAll<InstType>
|
||||
class xImpl_G1Logic : public xImpl_Group1<InstType>
|
||||
{
|
||||
public:
|
||||
using Group1ImplAll<InstType>::operator();
|
||||
using xImpl_Group1<InstType>::operator();
|
||||
|
||||
const SSELogicImpl<0x00,OpcodeSSE> PS; // packed single precision
|
||||
const SSELogicImpl<0x66,OpcodeSSE> PD; // packed double precision
|
||||
const SimdImpl_DestRegSSE<0x00,OpcodeSSE> PS; // packed single precision
|
||||
const SimdImpl_DestRegSSE<0x66,OpcodeSSE> PD; // packed double precision
|
||||
|
||||
G1LogicImpl_PlusSSE() {}
|
||||
xImpl_G1Logic() {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// This calss combines x86 with SSE/SSE2 arithmetic operations (ADD/SUB).
|
||||
// This class combines x86 with SSE/SSE2 arithmetic operations (ADD/SUB).
|
||||
//
|
||||
template< G1Type InstType, u8 OpcodeSSE >
|
||||
class G1ArithmeticImpl_PlusSSE : public G1LogicImpl_PlusSSE<InstType, OpcodeSSE >
|
||||
class xImpl_G1Arith : public xImpl_G1Logic<InstType, OpcodeSSE >
|
||||
{
|
||||
public:
|
||||
using Group1ImplAll<InstType>::operator();
|
||||
using xImpl_Group1<InstType>::operator();
|
||||
|
||||
const SSELogicImpl<0xf3,OpcodeSSE> SS; // scalar single precision
|
||||
const SSELogicImpl<0xf2,OpcodeSSE> SD; // scalar double precision
|
||||
const SimdImpl_DestRegSSE<0xf3,OpcodeSSE> SS; // scalar single precision
|
||||
const SimdImpl_DestRegSSE<0xf2,OpcodeSSE> SD; // scalar double precision
|
||||
|
||||
G1ArithmeticImpl_PlusSSE() {}
|
||||
xImpl_G1Arith() {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class G1CompareImpl_PlusSSE : Group1ImplAll< G1Type_CMP >
|
||||
class xImpl_G1Compare : xImpl_Group1< G1Type_CMP >
|
||||
{
|
||||
protected:
|
||||
template< u8 Prefix > struct Woot
|
||||
|
@ -198,12 +174,12 @@ protected:
|
|||
};
|
||||
|
||||
public:
|
||||
using Group1ImplAll< G1Type_CMP >::operator();
|
||||
using xImpl_Group1< G1Type_CMP >::operator();
|
||||
|
||||
const Woot<0x00> PS;
|
||||
const Woot<0x66> PD;
|
||||
const Woot<0xf3> SS;
|
||||
const Woot<0xf2> SD;
|
||||
|
||||
G1CompareImpl_PlusSSE() {} //GCWhat?
|
||||
xImpl_G1Compare() {} //GCWhat?
|
||||
};
|
||||
|
|
|
@ -38,92 +38,61 @@ enum G2Type
|
|||
// 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.
|
||||
//
|
||||
template< G2Type InstType, typename ImmType >
|
||||
class Group2Impl
|
||||
{
|
||||
protected:
|
||||
static const uint OperandSize = sizeof(ImmType);
|
||||
|
||||
static bool Is8BitOperand() { return OperandSize == 1; }
|
||||
static void prefix16() { if( OperandSize == 2 ) xWrite<u8>( 0x66 ); }
|
||||
|
||||
public:
|
||||
Group2Impl() {} // For the love of GCC.
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
static __emitinline void Emit( const xRegister<ImmType>& to )
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( Is8BitOperand() ? 0xd2 : 0xd3 );
|
||||
ModRM_Direct( InstType, to.Id );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
static __emitinline void Emit( const xRegister<ImmType>& to, u8 imm )
|
||||
{
|
||||
if( imm == 0 ) return;
|
||||
|
||||
prefix16();
|
||||
if( imm == 1 )
|
||||
{
|
||||
// special encoding of 1's
|
||||
xWrite<u8>( Is8BitOperand() ? 0xd0 : 0xd1 );
|
||||
ModRM_Direct( InstType, to.Id );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite<u8>( Is8BitOperand() ? 0xc0 : 0xc1 );
|
||||
ModRM_Direct( InstType, to.Id );
|
||||
xWrite<u8>( imm );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
static __emitinline void Emit( const ModSibStrict<ImmType>& sibdest )
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( Is8BitOperand() ? 0xd2 : 0xd3 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
static __emitinline void Emit( const ModSibStrict<ImmType>& sibdest, u8 imm )
|
||||
{
|
||||
if( imm == 0 ) return;
|
||||
|
||||
prefix16();
|
||||
if( imm == 1 )
|
||||
{
|
||||
// special encoding of 1's
|
||||
xWrite<u8>( Is8BitOperand() ? 0xd0 : 0xd1 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite<u8>( Is8BitOperand() ? 0xc0 : 0xc1 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
xWrite<u8>( imm );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
template< G2Type InstType >
|
||||
class Group2ImplAll
|
||||
{
|
||||
public:
|
||||
template< typename T > __forceinline void operator()( const xRegister<T>& to, __unused const xRegisterCL& from ) const
|
||||
{ Group2Impl<InstType,T>::Emit( to ); }
|
||||
{
|
||||
prefix16<T>();
|
||||
xWrite<u8>( Is8BitOp<T>() ? 0xd2 : 0xd3 );
|
||||
ModRM_Direct( InstType, to.Id );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const ModSibStrict<T>& sibdest, __unused const xRegisterCL& from ) const
|
||||
{ Group2Impl<InstType,T>::Emit( sibdest ); }
|
||||
{
|
||||
prefix16<T>();
|
||||
xWrite<u8>( Is8BitOp<T>() ? 0xd2 : 0xd3 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const ModSibStrict<T>& sibdest, u8 imm ) const
|
||||
{ Group2Impl<InstType,T>::Emit( sibdest, imm ); }
|
||||
{
|
||||
if( imm == 0 ) return;
|
||||
|
||||
prefix16<T>();
|
||||
if( imm == 1 )
|
||||
{
|
||||
// special encoding of 1's
|
||||
xWrite<u8>( Is8BitOp<T>() ? 0xd0 : 0xd1 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite<u8>( Is8BitOp<T>() ? 0xc0 : 0xc1 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
xWrite<u8>( imm );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename T > __forceinline void operator()( const xRegister<T>& to, u8 imm ) const
|
||||
{ Group2Impl<InstType,T>::Emit( to, imm ); }
|
||||
{
|
||||
if( imm == 0 ) return;
|
||||
|
||||
prefix16<T>();
|
||||
if( imm == 1 )
|
||||
{
|
||||
// special encoding of 1's
|
||||
xWrite<u8>( Is8BitOp<T>() ? 0xd0 : 0xd1 );
|
||||
ModRM_Direct( InstType, to.Id );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite<u8>( Is8BitOp<T>() ? 0xc0 : 0xc1 );
|
||||
ModRM_Direct( InstType, to.Id );
|
||||
xWrite<u8>( imm );
|
||||
}
|
||||
}
|
||||
|
||||
Group2ImplAll() {} // I am a class with no members, so I need an explicit constructor! Sense abounds.
|
||||
};
|
||||
|
|
|
@ -31,45 +31,27 @@ enum G3Type
|
|||
G3Type_iDIV = 7
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename ImmType >
|
||||
class Group3Impl
|
||||
{
|
||||
protected:
|
||||
static const uint OperandSize = sizeof(ImmType);
|
||||
|
||||
static bool Is8BitOperand() { return OperandSize == 1; }
|
||||
static void prefix16() { if( OperandSize == 2 ) xWrite<u8>( 0x66 ); }
|
||||
|
||||
public:
|
||||
Group3Impl() {} // For the love of GCC.
|
||||
|
||||
static __emitinline void Emit( G3Type InstType, const xRegister<ImmType>& from )
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>(Is8BitOperand() ? 0xf6 : 0xf7 );
|
||||
ModRM_Direct( InstType, from.Id );
|
||||
}
|
||||
|
||||
static __emitinline void Emit( G3Type InstType, const ModSibStrict<ImmType>& sibsrc )
|
||||
{
|
||||
prefix16();
|
||||
xWrite<u8>( Is8BitOperand() ? 0xf6 : 0xf7 );
|
||||
EmitSibMagic( InstType, sibsrc );
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template< G3Type InstType >
|
||||
class Group3ImplAll
|
||||
{
|
||||
public:
|
||||
template< typename T >
|
||||
__forceinline void operator()( const xRegister<T>& from ) const { Group3Impl<T>::Emit( InstType, from ); }
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __forceinline void operator()( const xRegister<T>& from ) const
|
||||
{
|
||||
prefix16<T>();
|
||||
xWrite<u8>(Is8BitOp<T>() ? 0xf6 : 0xf7 );
|
||||
ModRM_Direct( InstType, from.Id );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
__noinline void operator()( const ModSibStrict<T>& from ) const { Group3Impl<T>::Emit( InstType, from ); }
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const ModSibStrict<T>& from ) const
|
||||
{
|
||||
prefix16<T>();
|
||||
xWrite<u8>( Is8BitOp<T>() ? 0xf6 : 0xf7 );
|
||||
EmitSibMagic( InstType, from );
|
||||
}
|
||||
|
||||
Group3ImplAll() {}
|
||||
};
|
||||
|
@ -78,15 +60,15 @@ public:
|
|||
// This class combines x86 and SSE/SSE2 instructions for iMUL and iDIV.
|
||||
//
|
||||
template< G3Type InstType, u8 OpcodeSSE >
|
||||
class G3Impl_PlusSSE : public Group3ImplAll<InstType>
|
||||
class xImpl_Group3 : public Group3ImplAll<InstType>
|
||||
{
|
||||
public:
|
||||
const SSELogicImpl<0x00,OpcodeSSE> PS;
|
||||
const SSELogicImpl<0x66,OpcodeSSE> PD;
|
||||
const SSELogicImpl<0xf3,OpcodeSSE> SS;
|
||||
const SSELogicImpl<0xf2,OpcodeSSE> SD;
|
||||
const SimdImpl_DestRegSSE<0x00,OpcodeSSE> PS;
|
||||
const SimdImpl_DestRegSSE<0x66,OpcodeSSE> PD;
|
||||
const SimdImpl_DestRegSSE<0xf3,OpcodeSSE> SS;
|
||||
const SimdImpl_DestRegSSE<0xf2,OpcodeSSE> SD;
|
||||
|
||||
G3Impl_PlusSSE() {}
|
||||
xImpl_Group3() {}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -162,14 +144,14 @@ public:
|
|||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class iMul_PlusSSE : public G3Impl_PlusSSE<G3Type_iMUL,0x59>
|
||||
class xImpl_iMul : public xImpl_Group3<G3Type_iMUL,0x59>
|
||||
{
|
||||
protected:
|
||||
typedef iMulImpl<u32> iMUL32;
|
||||
typedef iMulImpl<u16> iMUL16;
|
||||
|
||||
public:
|
||||
using G3Impl_PlusSSE<G3Type_iMUL,0x59>::operator();
|
||||
using xImpl_Group3<G3Type_iMUL,0x59>::operator();
|
||||
|
||||
__forceinline void operator()( const xRegister32& to, const xRegister32& from ) const { iMUL32::Emit( to, from ); }
|
||||
__forceinline void operator()( const xRegister32& to, const void* src ) const { iMUL32::Emit( to, src ); }
|
||||
|
@ -183,5 +165,5 @@ public:
|
|||
__noinline void operator()( const xRegister16& to, const ModSibBase& src ) const { iMUL16::Emit( to, src ); }
|
||||
__noinline void operator()( const xRegister16& to, const ModSibBase& from, s16 imm ) const { iMUL16::Emit( to, from, imm ); }
|
||||
|
||||
iMul_PlusSSE() {}
|
||||
xImpl_iMul() {}
|
||||
};
|
||||
|
|
|
@ -129,11 +129,11 @@ public:
|
|||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PLogicImplAll - Implements logic forms for MMX/SSE instructions, and can be used for
|
||||
// SimdImpl_PackedLogic - Implements logic forms for MMX/SSE instructions, and can be used for
|
||||
// a few other various instruction too (anything which comes in simdreg,simdreg/ModRM forms).
|
||||
//
|
||||
template< u8 Opcode >
|
||||
class PLogicImplAll
|
||||
class SimdImpl_PackedLogic
|
||||
{
|
||||
public:
|
||||
template< typename T >
|
||||
|
@ -143,21 +143,40 @@ public:
|
|||
template< typename T >
|
||||
__noinline void operator()( const xRegisterSIMD<T>& to, const ModSibBase& from ) const { writeXMMop( 0x66, Opcode, to, from ); }
|
||||
|
||||
PLogicImplAll() {} //GCWho?
|
||||
SimdImpl_PackedLogic() {} //GCWho?
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// For implementing SSE-only logic operations, like ANDPS/ANDPD
|
||||
// For implementing SSE-only logic operations that have reg,reg/rm forms only,
|
||||
// like ANDPS/ANDPD
|
||||
//
|
||||
template< u8 Prefix, u8 Opcode >
|
||||
class SSELogicImpl
|
||||
class SimdImpl_DestRegSSE
|
||||
{
|
||||
public:
|
||||
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||
__noinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||
|
||||
SSELogicImpl() {} //GCWho?
|
||||
SimdImpl_DestRegSSE() {} //GCWho?
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// For implementing MMX/SSE operations that have reg,reg/rm forms only,
|
||||
// but accept either MM or XMM destinations (most PADD/PSUB and other P srithmetic ops).
|
||||
//
|
||||
template< u8 Prefix, u8 Opcode >
|
||||
class SimdImpl_DestRegEither
|
||||
{
|
||||
public:
|
||||
template< typename DestOperandType >
|
||||
__forceinline void operator()( const xRegisterSIMD<DestOperandType>& to, const xRegisterSIMD<DestOperandType>& from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||
template< typename DestOperandType >
|
||||
__forceinline void operator()( const xRegisterSIMD<DestOperandType>& to, const void* from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||
template< typename DestOperandType >
|
||||
__noinline void operator()( const xRegisterSIMD<DestOperandType>& to, const ModSibBase& from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||
|
||||
SimdImpl_DestRegEither() {} //GCWho?
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -165,76 +184,76 @@ public:
|
|||
// can be regDirect or ModRM (indirect).
|
||||
//
|
||||
template< u8 Prefix, u8 Opcode, typename DestRegType, typename SrcRegType, typename SrcOperandType >
|
||||
class SSEImpl_DestRegForm
|
||||
class SimdImpl_DestRegStrict
|
||||
{
|
||||
public:
|
||||
__forceinline void operator()( const DestRegType& to, const SrcRegType& from ) const { writeXMMop( Prefix, Opcode, to, from, true ); }
|
||||
__forceinline void operator()( const DestRegType& to, const SrcOperandType* from ) const { writeXMMop( Prefix, Opcode, to, from, true ); }
|
||||
__noinline void operator()( const DestRegType& to, const ModSibStrict<SrcOperandType>& from ) const { writeXMMop( Prefix, Opcode, to, from, true ); }
|
||||
|
||||
SSEImpl_DestRegForm() {} //GCWho?
|
||||
SimdImpl_DestRegStrict() {} //GCWho?
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< u8 OpcodeSSE >
|
||||
class SSEImpl_PSPD_SSSD
|
||||
class SimdImpl_PSPD_SSSD
|
||||
{
|
||||
public:
|
||||
const SSELogicImpl<0x00,OpcodeSSE> PS; // packed single precision
|
||||
const SSELogicImpl<0x66,OpcodeSSE> PD; // packed double precision
|
||||
const SSELogicImpl<0xf3,OpcodeSSE> SS; // scalar single precision
|
||||
const SSELogicImpl<0xf2,OpcodeSSE> SD; // scalar double precision
|
||||
const SimdImpl_DestRegSSE<0x00,OpcodeSSE> PS; // packed single precision
|
||||
const SimdImpl_DestRegSSE<0x66,OpcodeSSE> PD; // packed double precision
|
||||
const SimdImpl_DestRegSSE<0xf3,OpcodeSSE> SS; // scalar single precision
|
||||
const SimdImpl_DestRegSSE<0xf2,OpcodeSSE> SD; // scalar double precision
|
||||
|
||||
SSEImpl_PSPD_SSSD() {} //GChow?
|
||||
SimdImpl_PSPD_SSSD() {} //GChow?
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
template< u8 OpcodeSSE >
|
||||
class SSEAndNotImpl
|
||||
class SimdImpl_AndNot
|
||||
{
|
||||
public:
|
||||
const SSELogicImpl<0x00,OpcodeSSE> PS;
|
||||
const SSELogicImpl<0x66,OpcodeSSE> PD;
|
||||
SSEAndNotImpl() {}
|
||||
const SimdImpl_DestRegSSE<0x00,OpcodeSSE> PS;
|
||||
const SimdImpl_DestRegSSE<0x66,OpcodeSSE> PD;
|
||||
SimdImpl_AndNot() {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// For instructions that have SS/SD form only (UCOMI, etc)
|
||||
// AltPrefix - prefixed used for doubles (SD form).
|
||||
template< u8 AltPrefix, u8 OpcodeSSE >
|
||||
class SSEImpl_SS_SD
|
||||
class SimdImpl_SS_SD
|
||||
{
|
||||
public:
|
||||
const SSELogicImpl<0x00,OpcodeSSE> SS;
|
||||
const SSELogicImpl<AltPrefix,OpcodeSSE> SD;
|
||||
SSEImpl_SS_SD() {}
|
||||
const SimdImpl_DestRegSSE<0x00,OpcodeSSE> SS;
|
||||
const SimdImpl_DestRegSSE<AltPrefix,OpcodeSSE> SD;
|
||||
SimdImpl_SS_SD() {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// For instructions that have PS/SS form only (most commonly reciprocal Sqrt functions)
|
||||
template< u8 OpcodeSSE >
|
||||
class SSE_rSqrtImpl
|
||||
class SimdImpl_rSqrt
|
||||
{
|
||||
public:
|
||||
const SSELogicImpl<0x00,OpcodeSSE> PS;
|
||||
const SSELogicImpl<0xf3,OpcodeSSE> SS;
|
||||
SSE_rSqrtImpl() {}
|
||||
const SimdImpl_DestRegSSE<0x00,OpcodeSSE> PS;
|
||||
const SimdImpl_DestRegSSE<0xf3,OpcodeSSE> SS;
|
||||
SimdImpl_rSqrt() {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// For instructions that have PS/SS/SD form only (most commonly Sqrt functions)
|
||||
template< u8 OpcodeSSE >
|
||||
class SSE_SqrtImpl : public SSE_rSqrtImpl<OpcodeSSE>
|
||||
class SimdImpl_Sqrt : public SimdImpl_rSqrt<OpcodeSSE>
|
||||
{
|
||||
public:
|
||||
const SSELogicImpl<0xf2,OpcodeSSE> SD;
|
||||
SSE_SqrtImpl() {}
|
||||
const SimdImpl_DestRegSSE<0xf2,OpcodeSSE> SD;
|
||||
SimdImpl_Sqrt() {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< u8 OpcodeSSE >
|
||||
class SSEImpl_Shuffle
|
||||
class SimdImpl_Shuffle
|
||||
{
|
||||
protected:
|
||||
template< u8 Prefix > struct Woot
|
||||
|
@ -249,12 +268,12 @@ public:
|
|||
const Woot<0x00> PS;
|
||||
const Woot<0x66> PD;
|
||||
|
||||
SSEImpl_Shuffle() {} //GCWhat?
|
||||
SimdImpl_Shuffle() {} //GCWhat?
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< SSE2_ComparisonType CType >
|
||||
class SSECompareImpl
|
||||
class SimdImpl_Compare
|
||||
{
|
||||
protected:
|
||||
template< u8 Prefix > struct Woot
|
||||
|
@ -270,5 +289,87 @@ public:
|
|||
const Woot<0x66> PD;
|
||||
const Woot<0xf3> SS;
|
||||
const Woot<0xf2> SD;
|
||||
SSECompareImpl() {} //GCWhat?
|
||||
SimdImpl_Compare() {} //GCWhat?
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
template< u8 Opcode1, u8 OpcodeImm, u8 Modcode >
|
||||
class SimdImpl_Shift
|
||||
{
|
||||
public:
|
||||
SimdImpl_Shift() {}
|
||||
|
||||
template< typename OperandType >
|
||||
__forceinline void operator()( const xRegisterSIMD<OperandType>& to, const xRegisterSIMD<OperandType>& from ) const
|
||||
{
|
||||
writeXMMop( 0x66, Opcode1, to, from );
|
||||
}
|
||||
|
||||
template< typename OperandType >
|
||||
__forceinline void operator()( const xRegisterSIMD<OperandType>& to, const void* from ) const
|
||||
{
|
||||
writeXMMop( 0x66, Opcode1, to, from );
|
||||
}
|
||||
|
||||
template< typename OperandType >
|
||||
__noinline void operator()( const xRegisterSIMD<OperandType>& to, const ModSibBase& from ) const
|
||||
{
|
||||
writeXMMop( 0x66, Opcode1, to, from );
|
||||
}
|
||||
|
||||
template< typename OperandType >
|
||||
__emitinline void operator()( const xRegisterSIMD<OperandType>& to, u8 imm ) const
|
||||
{
|
||||
SimdPrefix( (sizeof( OperandType ) == 16) ? 0x66 : 0, OpcodeImm );
|
||||
ModRM( 3, (int)Modcode, to.Id );
|
||||
xWrite<u8>( imm );
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< u8 OpcodeBase1, u8 OpcodeBaseImm, u8 Modcode >
|
||||
class SimdImpl_ShiftAll
|
||||
{
|
||||
public:
|
||||
const SimdImpl_Shift<OpcodeBase1+1,OpcodeBaseImm+1,Modcode> W;
|
||||
const SimdImpl_Shift<OpcodeBase1+2,OpcodeBaseImm+2,Modcode> D;
|
||||
const SimdImpl_Shift<OpcodeBase1+3,OpcodeBaseImm+3,Modcode> Q;
|
||||
|
||||
void DQ( const xRegisterSSE& to, u8 imm ) const
|
||||
{
|
||||
SimdPrefix( 0x66, OpcodeBaseImm+3 );
|
||||
ModRM( 3, (int)Modcode+1, to.Id );
|
||||
xWrite<u8>( imm );
|
||||
}
|
||||
|
||||
SimdImpl_ShiftAll() {}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template< u8 OpcodeB, u8 OpcodeS, u8 OpcodeUS, u8 OpcodeQ >
|
||||
class SimdImpl_AddSub
|
||||
{
|
||||
public:
|
||||
const SimdImpl_DestRegEither<0x66,OpcodeB> B;
|
||||
const SimdImpl_DestRegEither<0x66,OpcodeB+1> W;
|
||||
const SimdImpl_DestRegEither<0x66,OpcodeB+2> D;
|
||||
const SimdImpl_DestRegEither<0x66,OpcodeQ> Q;
|
||||
|
||||
// Add/Sub packed signed byte [8bit] integers from src into dest, and saturate the results.
|
||||
const SimdImpl_DestRegEither<0x66,OpcodeS> SB;
|
||||
|
||||
// Add/Sub packed signed word [16bit] integers from src into dest, and saturate the results.
|
||||
const SimdImpl_DestRegEither<0x66,OpcodeS+1> SW;
|
||||
|
||||
// Add/Sub packed unsigned byte [8bit] integers from src into dest, and saturate the results.
|
||||
const SimdImpl_DestRegEither<0x66,OpcodeUS> USB;
|
||||
|
||||
// Add/Sub packed unsigned word [16bit] integers from src into dest, and saturate the results.
|
||||
const SimdImpl_DestRegEither<0x66,OpcodeUS+1> USW;
|
||||
|
||||
SimdImpl_AddSub() {}
|
||||
};
|
|
@ -253,16 +253,16 @@ using namespace Internal;
|
|||
const MovImplAll xMOV;
|
||||
const TestImplAll xTEST;
|
||||
|
||||
const G1LogicImpl_PlusSSE<G1Type_AND,0x54> xAND;
|
||||
const G1LogicImpl_PlusSSE<G1Type_OR,0x56> xOR;
|
||||
const G1LogicImpl_PlusSSE<G1Type_XOR,0x57> xXOR;
|
||||
const xImpl_G1Logic<G1Type_AND,0x54> xAND;
|
||||
const xImpl_G1Logic<G1Type_OR,0x56> xOR;
|
||||
const xImpl_G1Logic<G1Type_XOR,0x57> xXOR;
|
||||
|
||||
const G1ArithmeticImpl_PlusSSE<G1Type_ADD,0x58> xADD;
|
||||
const G1ArithmeticImpl_PlusSSE<G1Type_SUB,0x5c> xSUB;
|
||||
const xImpl_G1Arith<G1Type_ADD,0x58> xADD;
|
||||
const xImpl_G1Arith<G1Type_SUB,0x5c> xSUB;
|
||||
|
||||
const Group1ImplAll<G1Type_ADC> xADC;
|
||||
const Group1ImplAll<G1Type_SBB> xSBB;
|
||||
const G1CompareImpl_PlusSSE xCMP;
|
||||
const xImpl_Group1<G1Type_ADC> xADC;
|
||||
const xImpl_Group1<G1Type_SBB> xSBB;
|
||||
const xImpl_G1Compare xCMP;
|
||||
|
||||
const Group2ImplAll<G2Type_ROL> xROL;
|
||||
const Group2ImplAll<G2Type_ROR> xROR;
|
||||
|
@ -276,8 +276,8 @@ const Group3ImplAll<G3Type_NOT> xNOT;
|
|||
const Group3ImplAll<G3Type_NEG> xNEG;
|
||||
const Group3ImplAll<G3Type_MUL> xUMUL;
|
||||
const Group3ImplAll<G3Type_DIV> xUDIV;
|
||||
const G3Impl_PlusSSE<G3Type_iDIV,0x5e> xDIV;
|
||||
const iMul_PlusSSE xMUL;
|
||||
const xImpl_Group3<G3Type_iDIV,0x5e> xDIV;
|
||||
const xImpl_iMul xMUL;
|
||||
|
||||
const IncDecImplAll<false> xINC;
|
||||
const IncDecImplAll<true> xDEC;
|
||||
|
@ -670,21 +670,32 @@ const MovhlImplAll<0x12> xMOVL;
|
|||
const MovhlImpl_RtoR<0x16> xMOVLH;
|
||||
const MovhlImpl_RtoR<0x12> xMOVHL;
|
||||
|
||||
const PLogicImplAll<0xdb> xPAND;
|
||||
const PLogicImplAll<0xdf> xPANDN;
|
||||
const PLogicImplAll<0xeb> xPOR;
|
||||
const PLogicImplAll<0xef> xPXOR;
|
||||
const SimdImpl_PackedLogic<0xdb> xPAND;
|
||||
const SimdImpl_PackedLogic<0xdf> xPANDN;
|
||||
const SimdImpl_PackedLogic<0xeb> xPOR;
|
||||
const SimdImpl_PackedLogic<0xef> xPXOR;
|
||||
|
||||
const SSEAndNotImpl<0x55> xANDN;
|
||||
const SimdImpl_AndNot<0x55> xANDN;
|
||||
|
||||
const SSEImpl_SS_SD<0x66,0x2e> xUCOMI;
|
||||
const SSE_rSqrtImpl<0x53> xRCP;
|
||||
const SSE_rSqrtImpl<0x52> xRSQRT;
|
||||
const SSE_SqrtImpl<0x51> xSQRT;
|
||||
const SimdImpl_SS_SD<0x66,0x2e> xUCOMI;
|
||||
const SimdImpl_rSqrt<0x53> xRCP;
|
||||
const SimdImpl_rSqrt<0x52> xRSQRT;
|
||||
const SimdImpl_Sqrt<0x51> xSQRT;
|
||||
|
||||
const SSEImpl_PSPD_SSSD<0x5f> xMAX;
|
||||
const SSEImpl_PSPD_SSSD<0x5d> xMIN;
|
||||
const SSEImpl_Shuffle<0xc6> xSHUF;
|
||||
const SimdImpl_PSPD_SSSD<0x5f> xMAX;
|
||||
const SimdImpl_PSPD_SSSD<0x5d> xMIN;
|
||||
const SimdImpl_Shuffle<0xc6> xSHUF;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const SimdImpl_Compare<SSE2_Equal> xCMPEQ;
|
||||
const SimdImpl_Compare<SSE2_Less> xCMPLT;
|
||||
const SimdImpl_Compare<SSE2_LessOrEqual> xCMPLE;
|
||||
const SimdImpl_Compare<SSE2_Unordered> xCMPUNORD;
|
||||
const SimdImpl_Compare<SSE2_NotEqual> xCMPNE;
|
||||
const SimdImpl_Compare<SSE2_NotLess> xCMPNLT;
|
||||
const SimdImpl_Compare<SSE2_NotLessOrEqual> xCMPNLE;
|
||||
const SimdImpl_Compare<SSE2_Ordered> xCMPORD;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// SSE Conversion Operations, as looney as they are.
|
||||
|
@ -692,46 +703,43 @@ const SSEImpl_Shuffle<0xc6> xSHUF;
|
|||
// These enforce pointer strictness for Indirect forms, due to the otherwise completely confusing
|
||||
// nature of the functions. (so if a function expects an m32, you must use (u32*) or ptr32[]).
|
||||
//
|
||||
const SSEImpl_DestRegForm<0xf3,0xe6,xRegisterSSE,xRegisterSSE,u64> xCVTDQ2PD;
|
||||
const SSEImpl_DestRegForm<0x00,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTDQ2PS;
|
||||
const SimdImpl_DestRegStrict<0xf3,0xe6,xRegisterSSE,xRegisterSSE,u64> xCVTDQ2PD;
|
||||
const SimdImpl_DestRegStrict<0x00,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTDQ2PS;
|
||||
|
||||
const SSEImpl_DestRegForm<0xf2,0xe6,xRegisterSSE,xRegisterSSE,u128> xCVTPD2DQ;
|
||||
const SSEImpl_DestRegForm<0x66,0x2d,xRegisterMMX,xRegisterSSE,u128> xCVTPD2PI;
|
||||
const SSEImpl_DestRegForm<0x66,0x5a,xRegisterSSE,xRegisterSSE,u128> xCVTPD2PS;
|
||||
const SimdImpl_DestRegStrict<0xf2,0xe6,xRegisterSSE,xRegisterSSE,u128> xCVTPD2DQ;
|
||||
const SimdImpl_DestRegStrict<0x66,0x2d,xRegisterMMX,xRegisterSSE,u128> xCVTPD2PI;
|
||||
const SimdImpl_DestRegStrict<0x66,0x5a,xRegisterSSE,xRegisterSSE,u128> xCVTPD2PS;
|
||||
|
||||
const SSEImpl_DestRegForm<0x66,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PD;
|
||||
const SSEImpl_DestRegForm<0x00,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PS;
|
||||
const SimdImpl_DestRegStrict<0x66,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PD;
|
||||
const SimdImpl_DestRegStrict<0x00,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PS;
|
||||
|
||||
const SSEImpl_DestRegForm<0x66,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTPS2DQ;
|
||||
const SSEImpl_DestRegForm<0x00,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTPS2PD;
|
||||
const SSEImpl_DestRegForm<0x00,0x2d,xRegisterMMX,xRegisterSSE,u64> xCVTPS2PI;
|
||||
const SimdImpl_DestRegStrict<0x66,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTPS2DQ;
|
||||
const SimdImpl_DestRegStrict<0x00,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTPS2PD;
|
||||
const SimdImpl_DestRegStrict<0x00,0x2d,xRegisterMMX,xRegisterSSE,u64> xCVTPS2PI;
|
||||
|
||||
const SSEImpl_DestRegForm<0xf2,0x2d,xRegister32, xRegisterSSE,u64> xCVTSD2SI;
|
||||
const SSEImpl_DestRegForm<0xf2,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTSD2SS;
|
||||
const SSEImpl_DestRegForm<0xf2,0x2a,xRegisterMMX,xRegister32, u32> xCVTSI2SD;
|
||||
const SSEImpl_DestRegForm<0xf3,0x2a,xRegisterSSE,xRegister32, u32> xCVTSI2SS;
|
||||
const SimdImpl_DestRegStrict<0xf2,0x2d,xRegister32, xRegisterSSE,u64> xCVTSD2SI;
|
||||
const SimdImpl_DestRegStrict<0xf2,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTSD2SS;
|
||||
const SimdImpl_DestRegStrict<0xf2,0x2a,xRegisterMMX,xRegister32, u32> xCVTSI2SD;
|
||||
const SimdImpl_DestRegStrict<0xf3,0x2a,xRegisterSSE,xRegister32, u32> xCVTSI2SS;
|
||||
|
||||
const SSEImpl_DestRegForm<0xf3,0x5a,xRegisterSSE,xRegisterSSE,u32> xCVTSS2SD;
|
||||
const SSEImpl_DestRegForm<0xf3,0x2d,xRegister32, xRegisterSSE,u32> xCVTSS2SI;
|
||||
const SimdImpl_DestRegStrict<0xf3,0x5a,xRegisterSSE,xRegisterSSE,u32> xCVTSS2SD;
|
||||
const SimdImpl_DestRegStrict<0xf3,0x2d,xRegister32, xRegisterSSE,u32> xCVTSS2SI;
|
||||
|
||||
const SSEImpl_DestRegForm<0x66,0xe6,xRegisterSSE,xRegisterSSE,u128> xCVTTPD2DQ;
|
||||
const SSEImpl_DestRegForm<0x66,0x2c,xRegisterMMX,xRegisterSSE,u128> xCVTTPD2PI;
|
||||
const SSEImpl_DestRegForm<0xf3,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTTPS2DQ;
|
||||
const SSEImpl_DestRegForm<0x00,0x2c,xRegisterMMX,xRegisterSSE,u64> xCVTTPS2PI;
|
||||
const SimdImpl_DestRegStrict<0x66,0xe6,xRegisterSSE,xRegisterSSE,u128> xCVTTPD2DQ;
|
||||
const SimdImpl_DestRegStrict<0x66,0x2c,xRegisterMMX,xRegisterSSE,u128> xCVTTPD2PI;
|
||||
const SimdImpl_DestRegStrict<0xf3,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTTPS2DQ;
|
||||
const SimdImpl_DestRegStrict<0x00,0x2c,xRegisterMMX,xRegisterSSE,u64> xCVTTPS2PI;
|
||||
|
||||
const SSEImpl_DestRegForm<0xf2,0x2c,xRegister32, xRegisterSSE,u64> xCVTTSD2SI;
|
||||
const SSEImpl_DestRegForm<0xf3,0x2c,xRegister32, xRegisterSSE,u32> xCVTTSS2SI;
|
||||
const SimdImpl_DestRegStrict<0xf2,0x2c,xRegister32, xRegisterSSE,u64> xCVTTSD2SI;
|
||||
const SimdImpl_DestRegStrict<0xf3,0x2c,xRegister32, xRegisterSSE,u32> xCVTTSS2SI;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const SSECompareImpl<SSE2_Equal> xCMPEQ;
|
||||
const SSECompareImpl<SSE2_Less> xCMPLT;
|
||||
const SSECompareImpl<SSE2_LessOrEqual> xCMPLE;
|
||||
const SSECompareImpl<SSE2_Unordered> xCMPUNORD;
|
||||
const SSECompareImpl<SSE2_NotEqual> xCMPNE;
|
||||
const SSECompareImpl<SSE2_NotLess> xCMPNLT;
|
||||
const SSECompareImpl<SSE2_NotLessOrEqual> xCMPNLE;
|
||||
const SSECompareImpl<SSE2_Ordered> xCMPORD;
|
||||
const SimdImpl_ShiftAll<0xd0, 0x70, 2> xPSRL;
|
||||
const SimdImpl_ShiftAll<0xf0, 0x70, 6> xPSLL;
|
||||
|
||||
const SimdImpl_AddSub<0xfc, 0xec, 0xdc, 0xd4> xPADD;
|
||||
const SimdImpl_AddSub<0xf8, 0xe8, 0xd8, 0xfb> xPSUB;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -38,16 +38,16 @@ namespace x86Emitter
|
|||
// ------------------------------------------------------------------------
|
||||
// Group 1 Instruction Class
|
||||
|
||||
extern const Internal::G1LogicImpl_PlusSSE<Internal::G1Type_AND,0x54> xAND;
|
||||
extern const Internal::G1LogicImpl_PlusSSE<Internal::G1Type_OR,0x56> xOR;
|
||||
extern const Internal::G1LogicImpl_PlusSSE<Internal::G1Type_XOR,0x57> xXOR;
|
||||
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;
|
||||
|
||||
extern const Internal::G1ArithmeticImpl_PlusSSE<Internal::G1Type_ADD,0x58> xADD;
|
||||
extern const Internal::G1ArithmeticImpl_PlusSSE<Internal::G1Type_SUB,0x5c> xSUB;
|
||||
extern const Internal::G1CompareImpl_PlusSSE xCMP;
|
||||
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;
|
||||
|
||||
extern const Internal::Group1ImplAll<Internal::G1Type_ADC> xADC;
|
||||
extern const Internal::Group1ImplAll<Internal::G1Type_SBB> xSBB;
|
||||
extern const Internal::xImpl_Group1<Internal::G1Type_ADC> xADC;
|
||||
extern const Internal::xImpl_Group1<Internal::G1Type_SBB> xSBB;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Group 2 Instruction Class
|
||||
|
@ -74,8 +74,8 @@ namespace x86Emitter
|
|||
extern const Internal::Group3ImplAll<Internal::G3Type_NEG> xNEG;
|
||||
extern const Internal::Group3ImplAll<Internal::G3Type_MUL> xUMUL;
|
||||
extern const Internal::Group3ImplAll<Internal::G3Type_DIV> xUDIV;
|
||||
extern const Internal::G3Impl_PlusSSE<Internal::G3Type_iDIV,0x5e> xDIV;
|
||||
extern const Internal::iMul_PlusSSE xMUL;
|
||||
extern const Internal::xImpl_Group3<Internal::G3Type_iDIV,0x5e> xDIV;
|
||||
extern const Internal::xImpl_iMul xMUL;
|
||||
|
||||
extern const Internal::IncDecImplAll<false> xINC;
|
||||
extern const Internal::IncDecImplAll<true> xDEC;
|
||||
|
@ -435,65 +435,73 @@ namespace x86Emitter
|
|||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
extern const Internal::PLogicImplAll<0xdb> xPAND;
|
||||
extern const Internal::PLogicImplAll<0xdf> xPANDN;
|
||||
extern const Internal::PLogicImplAll<0xeb> xPOR;
|
||||
extern const Internal::PLogicImplAll<0xef> xPXOR;
|
||||
extern const Internal::SimdImpl_PackedLogic<0xdb> xPAND;
|
||||
extern const Internal::SimdImpl_PackedLogic<0xdf> xPANDN;
|
||||
extern const Internal::SimdImpl_PackedLogic<0xeb> xPOR;
|
||||
extern const Internal::SimdImpl_PackedLogic<0xef> xPXOR;
|
||||
|
||||
extern const Internal::SSEAndNotImpl<0x55> xANDN;
|
||||
extern const Internal::SimdImpl_AndNot<0x55> xANDN;
|
||||
|
||||
extern const Internal::SSEImpl_SS_SD<0x66,0x2e> xUCOMI;
|
||||
extern const Internal::SSE_rSqrtImpl<0x53> xRCP;
|
||||
extern const Internal::SSE_rSqrtImpl<0x52> xRSQRT;
|
||||
extern const Internal::SSE_SqrtImpl<0x51> xSQRT;
|
||||
extern const Internal::SimdImpl_SS_SD<0x66,0x2e> xUCOMI;
|
||||
extern const Internal::SimdImpl_rSqrt<0x53> xRCP;
|
||||
extern const Internal::SimdImpl_rSqrt<0x52> xRSQRT;
|
||||
extern const Internal::SimdImpl_Sqrt<0x51> xSQRT;
|
||||
|
||||
extern const Internal::SSEImpl_PSPD_SSSD<0x5f> xMAX;
|
||||
extern const Internal::SSEImpl_PSPD_SSSD<0x5d> xMIN;
|
||||
extern const Internal::SSEImpl_Shuffle<0xc6> xSHUF;
|
||||
extern const Internal::SimdImpl_PSPD_SSSD<0x5f> xMAX;
|
||||
extern const Internal::SimdImpl_PSPD_SSSD<0x5d> xMIN;
|
||||
extern const Internal::SimdImpl_Shuffle<0xc6> xSHUF;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
extern const Internal::SSECompareImpl<SSE2_Equal> xCMPEQ;
|
||||
extern const Internal::SSECompareImpl<SSE2_Less> xCMPLT;
|
||||
extern const Internal::SSECompareImpl<SSE2_LessOrEqual> xCMPLE;
|
||||
extern const Internal::SSECompareImpl<SSE2_Unordered> xCMPUNORD;
|
||||
extern const Internal::SSECompareImpl<SSE2_NotEqual> xCMPNE;
|
||||
extern const Internal::SSECompareImpl<SSE2_NotLess> xCMPNLT;
|
||||
extern const Internal::SSECompareImpl<SSE2_NotLessOrEqual> xCMPNLE;
|
||||
extern const Internal::SSECompareImpl<SSE2_Ordered> xCMPORD;
|
||||
extern const Internal::SimdImpl_Compare<SSE2_Equal> xCMPEQ;
|
||||
extern const Internal::SimdImpl_Compare<SSE2_Less> xCMPLT;
|
||||
extern const Internal::SimdImpl_Compare<SSE2_LessOrEqual> xCMPLE;
|
||||
extern const Internal::SimdImpl_Compare<SSE2_Unordered> xCMPUNORD;
|
||||
extern const Internal::SimdImpl_Compare<SSE2_NotEqual> xCMPNE;
|
||||
extern const Internal::SimdImpl_Compare<SSE2_NotLess> xCMPNLT;
|
||||
extern const Internal::SimdImpl_Compare<SSE2_NotLessOrEqual> xCMPNLE;
|
||||
extern const Internal::SimdImpl_Compare<SSE2_Ordered> xCMPORD;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// OMG Evil. I went cross-eyed an hour ago doing this.
|
||||
//
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf3,0xe6,xRegisterSSE,xRegisterSSE,u64> xCVTDQ2PD;
|
||||
extern const Internal::SSEImpl_DestRegForm<0x00,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTDQ2PS;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0xf3,0xe6,xRegisterSSE,xRegisterSSE,u64> xCVTDQ2PD;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0x00,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTDQ2PS;
|
||||
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf2,0xe6,xRegisterSSE,xRegisterSSE,u128> xCVTPD2DQ;
|
||||
extern const Internal::SSEImpl_DestRegForm<0x66,0x2d,xRegisterMMX,xRegisterSSE,u128> xCVTPD2PI;
|
||||
extern const Internal::SSEImpl_DestRegForm<0x66,0x5a,xRegisterSSE,xRegisterSSE,u128> xCVTPD2PS;
|
||||
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;
|
||||
|
||||
extern const Internal::SSEImpl_DestRegForm<0x66,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PD;
|
||||
extern const Internal::SSEImpl_DestRegForm<0x00,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PS;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0x66,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PD;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0x00,0x2a,xRegisterSSE,xRegisterMMX,u64> xCVTPI2PS;
|
||||
|
||||
extern const Internal::SSEImpl_DestRegForm<0x66,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTPS2DQ;
|
||||
extern const Internal::SSEImpl_DestRegForm<0x00,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTPS2PD;
|
||||
extern const Internal::SSEImpl_DestRegForm<0x00,0x2d,xRegisterMMX,xRegisterSSE,u64> xCVTPS2PI;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0x66,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTPS2DQ;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0x00,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTPS2PD;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0x00,0x2d,xRegisterMMX,xRegisterSSE,u64> xCVTPS2PI;
|
||||
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf2,0x2d,xRegister32, xRegisterSSE,u64> xCVTSD2SI;
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf2,0x5a,xRegisterSSE,xRegisterSSE,u64> xCVTSD2SS;
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf2,0x2a,xRegisterMMX,xRegister32, u32> xCVTSI2SD;
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf3,0x2a,xRegisterSSE,xRegister32, u32> xCVTSI2SS;
|
||||
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;
|
||||
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf3,0x5a,xRegisterSSE,xRegisterSSE,u32> xCVTSS2SD;
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf3,0x2d,xRegister32, xRegisterSSE,u32> xCVTSS2SI;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0xf3,0x5a,xRegisterSSE,xRegisterSSE,u32> xCVTSS2SD;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0xf3,0x2d,xRegister32, xRegisterSSE,u32> xCVTSS2SI;
|
||||
|
||||
extern const Internal::SSEImpl_DestRegForm<0x66,0xe6,xRegisterSSE,xRegisterSSE,u128> xCVTTPD2DQ;
|
||||
extern const Internal::SSEImpl_DestRegForm<0x66,0x2c,xRegisterMMX,xRegisterSSE,u128> xCVTTPD2PI;
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf3,0x5b,xRegisterSSE,xRegisterSSE,u128> xCVTTPS2DQ;
|
||||
extern const Internal::SSEImpl_DestRegForm<0x00,0x2c,xRegisterMMX,xRegisterSSE,u64> xCVTTPS2PI;
|
||||
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;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0x00,0x2c,xRegisterMMX,xRegisterSSE,u64> xCVTTPS2PI;
|
||||
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf2,0x2c,xRegister32, xRegisterSSE,u64> xCVTTSD2SI;
|
||||
extern const Internal::SSEImpl_DestRegForm<0xf3,0x2c,xRegister32, xRegisterSSE,u32> xCVTTSS2SI;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0xf2,0x2c,xRegister32, xRegisterSSE,u64> xCVTTSD2SI;
|
||||
extern const Internal::SimdImpl_DestRegStrict<0xf3,0x2c,xRegister32, xRegisterSSE,u32> xCVTTSS2SI;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
extern const Internal::SimdImpl_ShiftAll<0xd0, 0x70, 2> xPSRL;
|
||||
extern const Internal::SimdImpl_ShiftAll<0xf0, 0x70, 6> xPSLL;
|
||||
|
||||
extern const Internal::SimdImpl_AddSub<0xfc, 0xec, 0xdc, 0xd4> xPADD;
|
||||
extern const Internal::SimdImpl_AddSub<0xf8, 0xe8, 0xd8, 0xfb> xPSUB;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -48,132 +48,51 @@ emitterT void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from) { xPMOVMSKB
|
|||
emitterT void SSE2_P##mod##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod( xRegisterSSE(to), xRegisterSSE(from) ); } \
|
||||
emitterT void SSE2_P##mod##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod( xRegisterSSE(to), (void*)from ); }
|
||||
|
||||
#define DEFINE_LEGACY_ARITHMETIC( mod, sub ) \
|
||||
emitterT void P##mod##sub##RtoR( x86MMXRegType to, x86MMXRegType from ) { xP##mod.sub( xRegisterMMX(to), xRegisterMMX(from) ); } \
|
||||
emitterT void P##mod##sub##MtoR( x86MMXRegType to, uptr from ) { xP##mod.sub( xRegisterMMX(to), (void*)from ); } \
|
||||
emitterT void SSE2_P##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod.sub( xRegisterSSE(to), xRegisterSSE(from) ); } \
|
||||
emitterT void SSE2_P##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod.sub( xRegisterSSE(to), (void*)from ); }
|
||||
|
||||
#define DEFINE_LEGACY_SHIFT_STUFF( mod, sub ) \
|
||||
emitterT void P##mod##sub##RtoR( x86MMXRegType to, x86MMXRegType from ) { xP##mod.sub( xRegisterMMX(to), xRegisterMMX(from) ); } \
|
||||
emitterT void P##mod##sub##MtoR( x86MMXRegType to, uptr from ) { xP##mod.sub( xRegisterMMX(to), (void*)from ); } \
|
||||
emitterT void P##mod##sub##ItoR( x86MMXRegType to, u8 imm ) { xP##mod.sub( xRegisterMMX(to), imm ); } \
|
||||
emitterT void SSE2_P##mod##sub##_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xP##mod.sub( xRegisterSSE(to), xRegisterSSE(from) ); } \
|
||||
emitterT void SSE2_P##mod##sub##_M128_to_XMM( x86SSERegType to, uptr from ) { xP##mod.sub( xRegisterSSE(to), (void*)from ); } \
|
||||
emitterT void SSE2_P##mod##sub##_I8_to_XMM( x86SSERegType to, u8 imm ) { xP##mod.sub( xRegisterSSE(to), imm ); }
|
||||
|
||||
#define DEFINE_LEGACY_SHIFT_OPCODE( mod ) \
|
||||
DEFINE_LEGACY_SHIFT_STUFF( mod, Q ) \
|
||||
DEFINE_LEGACY_SHIFT_STUFF( mod, D ) \
|
||||
DEFINE_LEGACY_SHIFT_STUFF( mod, W ) \
|
||||
emitterT void SSE2_P##mod##DQ_I8_to_XMM( x86MMXRegType to, u8 imm ) { xP##mod.DQ( xRegisterSSE(to), imm ); }
|
||||
|
||||
DEFINE_LEGACY_LOGIC_OPCODE( AND )
|
||||
DEFINE_LEGACY_LOGIC_OPCODE( ANDN )
|
||||
DEFINE_LEGACY_LOGIC_OPCODE( OR )
|
||||
DEFINE_LEGACY_LOGIC_OPCODE( XOR )
|
||||
|
||||
DEFINE_LEGACY_SHIFT_OPCODE( SLL )
|
||||
DEFINE_LEGACY_SHIFT_OPCODE( SRL )
|
||||
|
||||
/* psllq r64 to r64 */
|
||||
emitterT void PSLLQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xF30F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
DEFINE_LEGACY_ARITHMETIC( ADD, B )
|
||||
DEFINE_LEGACY_ARITHMETIC( ADD, W )
|
||||
DEFINE_LEGACY_ARITHMETIC( ADD, D )
|
||||
DEFINE_LEGACY_ARITHMETIC( ADD, Q )
|
||||
DEFINE_LEGACY_ARITHMETIC( ADD, SB )
|
||||
DEFINE_LEGACY_ARITHMETIC( ADD, SW )
|
||||
DEFINE_LEGACY_ARITHMETIC( ADD, USB )
|
||||
DEFINE_LEGACY_ARITHMETIC( ADD, USW )
|
||||
|
||||
/* psllq m64 to r64 */
|
||||
emitterT void PSLLQMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xF30F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* psllq imm8 to r64 */
|
||||
emitterT void PSLLQItoR( x86MMXRegType to, u8 from )
|
||||
{
|
||||
write16( 0x730F );
|
||||
ModRM( 3, 6, to);
|
||||
write8( from );
|
||||
}
|
||||
|
||||
/* psrlq r64 to r64 */
|
||||
emitterT void PSRLQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xD30F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
/* psrlq m64 to r64 */
|
||||
emitterT void PSRLQMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xD30F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* psrlq imm8 to r64 */
|
||||
emitterT void PSRLQItoR( x86MMXRegType to, u8 from )
|
||||
{
|
||||
write16( 0x730F );
|
||||
ModRM( 3, 2, to);
|
||||
write8( from );
|
||||
}
|
||||
|
||||
/* paddusb r64 to r64 */
|
||||
emitterT void PADDUSBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xDC0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
/* paddusb m64 to r64 */
|
||||
emitterT void PADDUSBMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xDC0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* paddusw r64 to r64 */
|
||||
emitterT void PADDUSWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xDD0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
/* paddusw m64 to r64 */
|
||||
emitterT void PADDUSWMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xDD0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* paddb r64 to r64 */
|
||||
emitterT void PADDBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xFC0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
/* paddb m64 to r64 */
|
||||
emitterT void PADDBMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xFC0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* paddw r64 to r64 */
|
||||
emitterT void PADDWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xFD0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
/* paddw m64 to r64 */
|
||||
emitterT void PADDWMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xFD0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* paddd r64 to r64 */
|
||||
emitterT void PADDDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xFE0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
/* paddd m64 to r64 */
|
||||
emitterT void PADDDMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xFE0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
DEFINE_LEGACY_ARITHMETIC( SUB, B )
|
||||
DEFINE_LEGACY_ARITHMETIC( SUB, W )
|
||||
DEFINE_LEGACY_ARITHMETIC( SUB, D )
|
||||
DEFINE_LEGACY_ARITHMETIC( SUB, Q )
|
||||
DEFINE_LEGACY_ARITHMETIC( SUB, SB )
|
||||
DEFINE_LEGACY_ARITHMETIC( SUB, SW )
|
||||
DEFINE_LEGACY_ARITHMETIC( SUB, USB )
|
||||
DEFINE_LEGACY_ARITHMETIC( SUB, USW )
|
||||
|
||||
/* emms */
|
||||
emitterT void EMMS()
|
||||
|
@ -181,98 +100,6 @@ emitterT void EMMS()
|
|||
write16( 0x770F );
|
||||
}
|
||||
|
||||
emitterT void PADDSBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xEC0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PADDSWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xED0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
// paddq m64 to r64 (sse2 only?)
|
||||
emitterT void PADDQMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xD40F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
// paddq r64 to r64 (sse2 only?)
|
||||
emitterT void PADDQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xD40F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PSUBSBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xE80F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PSUBSWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xE90F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
|
||||
emitterT void PSUBBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xF80F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PSUBWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xF90F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PSUBDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xFA0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PSUBDMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xFA0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
emitterT void PSUBUSBRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xD80F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PSUBUSWRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xD90F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
// psubq m64 to r64 (sse2 only?)
|
||||
emitterT void PSUBQMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
write16( 0xFB0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
// psubq r64 to r64 (sse2 only?)
|
||||
emitterT void PSUBQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xFB0F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
// pmuludq m64 to r64 (sse2 only?)
|
||||
emitterT void PMULUDQMtoR( x86MMXRegType to, uptr from )
|
||||
{
|
||||
|
@ -338,46 +165,6 @@ emitterT void PCMPGTDMtoR( x86MMXRegType to, uptr from )
|
|||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
emitterT void PSRLWItoR( x86MMXRegType to, u8 from )
|
||||
{
|
||||
write16( 0x710F );
|
||||
ModRM( 3, 2 , to );
|
||||
write8( from );
|
||||
}
|
||||
|
||||
emitterT void PSRLDItoR( x86MMXRegType to, u8 from )
|
||||
{
|
||||
write16( 0x720F );
|
||||
ModRM( 3, 2 , to );
|
||||
write8( from );
|
||||
}
|
||||
|
||||
emitterT void PSRLDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xD20F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PSLLWItoR( x86MMXRegType to, u8 from )
|
||||
{
|
||||
write16( 0x710F );
|
||||
ModRM( 3, 6 , to );
|
||||
write8( from );
|
||||
}
|
||||
|
||||
emitterT void PSLLDItoR( x86MMXRegType to, u8 from )
|
||||
{
|
||||
write16( 0x720F );
|
||||
ModRM( 3, 6 , to );
|
||||
write8( from );
|
||||
}
|
||||
|
||||
emitterT void PSLLDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||
{
|
||||
write16( 0xF20F );
|
||||
ModRM( 3, to, from );
|
||||
}
|
||||
|
||||
emitterT void PSRAWItoR( x86MMXRegType to, u8 from )
|
||||
{
|
||||
write16( 0x710F );
|
||||
|
|
|
@ -34,29 +34,6 @@ using namespace x86Emitter;
|
|||
ModRM( 0, to, DISP32 ), \
|
||||
write32( MEMADDR(from, 4 + overb) )
|
||||
|
||||
#define SSERtoM( code, overb ) \
|
||||
assert( from < iREGCNT_XMM), \
|
||||
RexR(0, from), \
|
||||
write16( code ), \
|
||||
ModRM( 0, from, DISP32 ), \
|
||||
write32( MEMADDR(to, 4 + overb) )
|
||||
|
||||
#define SSE_SS_MtoR( code, overb ) \
|
||||
assert( to < iREGCNT_XMM ), \
|
||||
write8( 0xf3 ), \
|
||||
RexR(0, to), \
|
||||
write16( code ), \
|
||||
ModRM( 0, to, DISP32 ), \
|
||||
write32( MEMADDR(from, 4 + overb) )
|
||||
|
||||
#define SSE_SS_RtoM( code, overb ) \
|
||||
assert( from < iREGCNT_XMM), \
|
||||
write8( 0xf3 ), \
|
||||
RexR(0, from), \
|
||||
write16( code ), \
|
||||
ModRM( 0, from, DISP32 ), \
|
||||
write32( MEMADDR(to, 4 + overb) )
|
||||
|
||||
#define SSERtoR( code ) \
|
||||
assert( to < iREGCNT_XMM && from < iREGCNT_XMM), \
|
||||
RexRB(0, to, from), \
|
||||
|
@ -95,14 +72,7 @@ using namespace x86Emitter;
|
|||
RexR(0, to), \
|
||||
write16( code ), \
|
||||
ModRM( 0, to, DISP32 ), \
|
||||
write32( MEMADDR(from, 4 + overb) ) \
|
||||
|
||||
#define SSE_SD_RtoR( code ) \
|
||||
assert( to < iREGCNT_XMM && from < iREGCNT_XMM) , \
|
||||
write8( 0xf2 ), \
|
||||
RexRB(0, to, from), \
|
||||
write16( code ), \
|
||||
ModRM( 3, to, from )
|
||||
write32( MEMADDR(from, 4 + overb) )
|
||||
|
||||
#define DEFINE_LEGACY_MOV_OPCODE( mod, sse ) \
|
||||
emitterT void sse##_MOV##mod##_M128_to_XMM( x86SSERegType to, uptr from ) { xMOV##mod( xRegisterSSE(to), (void*)from ); } \
|
||||
|
@ -220,21 +190,20 @@ emitterT void SSE2_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) {
|
|||
emitterT void SSE2_MOVSD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVSDZX( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); }
|
||||
emitterT void SSE2_MOVSD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVSD( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); }
|
||||
|
||||
emitterT void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMASKMOV( xRegisterSSE(to), xRegisterSSE(from) ); }
|
||||
emitterT void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVL.PS( xRegisterSSE(to), (void*)from ); }
|
||||
emitterT void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVL.PS( (void*)to, xRegisterSSE(from) ); }
|
||||
emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVL.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); }
|
||||
emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVL.PS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); }
|
||||
|
||||
emitterT void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVL.PS( xRegisterSSE(to), (void*)from ); }
|
||||
emitterT void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVL.PS( (void*)to, xRegisterSSE(from) ); }
|
||||
emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVL.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); }
|
||||
emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVL.PS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); }
|
||||
|
||||
emitterT void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVH.PS( xRegisterSSE(to), (void*)from ); }
|
||||
emitterT void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVH.PS( (void*)to, xRegisterSSE(from) ); }
|
||||
emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVH.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); }
|
||||
emitterT void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVH.PS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); }
|
||||
emitterT void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { xMOVH.PS( xRegisterSSE(to), (void*)from ); }
|
||||
emitterT void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { xMOVH.PS( (void*)to, xRegisterSSE(from) ); }
|
||||
emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { xMOVH.PS( xRegisterSSE(to), ptr[xAddressReg(from)+offset] ); }
|
||||
emitterT void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { xMOVH.PS( ptr[xAddressReg(to)+offset], xRegisterSSE(from) ); }
|
||||
|
||||
emitterT void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVLH.PS( xRegisterSSE(to), xRegisterSSE(from) ); }
|
||||
emitterT void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMOVHL.PS( xRegisterSSE(to), xRegisterSSE(from) ); }
|
||||
|
||||
emitterT void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { xMASKMOV( xRegisterSSE(to), xRegisterSSE(from) ); }
|
||||
emitterT void SSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from) { xPMOVMSKB( xRegister32(to), xRegisterSSE(from) ); }
|
||||
|
||||
emitterT void SSE_SHUFPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { xSHUF.PS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); }
|
||||
|
@ -277,47 +246,6 @@ emitterT void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
|||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//emitterT void SSE_CVTPI2PS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x2a0f, 0 ); }
|
||||
// emitterT void SSE_CVTPI2PS_MM_to_XMM( x86SSERegType to, x86MMXRegType from ) { SSERtoR( 0x2a0f ); }
|
||||
//
|
||||
// emitterT void SSE_CVTPS2PI_M64_to_MM( x86MMXRegType to, uptr from ) { SSEMtoR( 0x2d0f, 0 ); }
|
||||
// emitterT void SSE_CVTPS2PI_XMM_to_MM( x86MMXRegType to, x86SSERegType from ) { SSERtoR( 0x2d0f ); }
|
||||
|
||||
/*
|
||||
emitterT void SSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from) { write8(0xf3); SSEMtoR(0x2c0f, 0); }
|
||||
emitterT void SSE_CVTTSS2SI_XMM_to_R32(x86IntRegType to, x86SSERegType from)
|
||||
{
|
||||
write8(0xf3);
|
||||
RexRB(0, to, from);
|
||||
write16(0x2c0f);
|
||||
ModRM(3, to, from);
|
||||
}
|
||||
*/
|
||||
|
||||
/*emitterT void SSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from) { write8(0xf3); SSEMtoR(0x2a0f, 0); }
|
||||
emitterT void SSE_CVTSI2SS_R_to_XMM(x86SSERegType to, x86IntRegType from)
|
||||
{
|
||||
write8(0xf3);
|
||||
RexRB(0, to, from);
|
||||
write16(0x2a0f);
|
||||
ModRM(3, to, from);
|
||||
}
|
||||
|
||||
emitterT void SSE2_CVTSS2SD_M32_to_XMM( x86SSERegType to, uptr from) { SSE_SS_MtoR(0x5a0f, 0); }
|
||||
emitterT void SSE2_CVTSS2SD_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { SSE_SS_RtoR(0x5a0f); }
|
||||
*/
|
||||
|
||||
/*emitterT void SSE2_CVTSD2SS_M64_to_XMM( x86SSERegType to, uptr from) { SSE_SD_MtoR(0x5a0f, 0); }
|
||||
emitterT void SSE2_CVTSD2SS_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { SSE_SD_RtoR(0x5a0f); }
|
||||
|
||||
emitterT void SSE2_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x5b0f, 0 ); }
|
||||
emitterT void SSE2_CVTDQ2PS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x5b0f ); }
|
||||
|
||||
emitterT void SSE2_CVTPS2DQ_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0x5b0f ); }
|
||||
emitterT void SSE2_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0x5b0f ); }
|
||||
|
||||
emitterT void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ write8(0xf3); SSERtoR(0x5b0f); }*/
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
//**********************************************************************************/
|
||||
|
@ -389,19 +317,6 @@ emitterT void SSE_LDMXCSR( uptr from ) {
|
|||
write32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
//**********************************************************************************/
|
||||
//PADDB,PADDW,PADDD : Add Packed Integers *
|
||||
//**********************************************************************************
|
||||
emitterT void SSE2_PADDB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFC0F ); }
|
||||
emitterT void SSE2_PADDB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFC0F ); }
|
||||
emitterT void SSE2_PADDW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFD0F ); }
|
||||
emitterT void SSE2_PADDW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFD0F ); }
|
||||
emitterT void SSE2_PADDD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFE0F ); }
|
||||
emitterT void SSE2_PADDD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFE0F ); }
|
||||
emitterT void SSE2_PADDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD40F ); }
|
||||
emitterT void SSE2_PADDQ_M128_to_XMM(x86SSERegType to, uptr from ) { SSEMtoR66( 0xD40F ); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//**********************************************************************************/
|
||||
//PCMPxx: Compare Packed Integers *
|
||||
|
@ -426,65 +341,8 @@ emitterT void SSE2_PCMPEQD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66(
|
|||
emitterT void SSE_PEXTRW_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8 ){ SSERtoR66(0xC50F); write8( imm8 ); }
|
||||
emitterT void SSE_PINSRW_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8 ){ SSERtoR66(0xC40F); write8( imm8 ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//**********************************************************************************/
|
||||
//PSUBx: Subtract Packed Integers *
|
||||
//**********************************************************************************
|
||||
emitterT void SSE2_PSUBB_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xF80F ); }
|
||||
emitterT void SSE2_PSUBB_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xF80F ); }
|
||||
emitterT void SSE2_PSUBW_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xF90F ); }
|
||||
emitterT void SSE2_PSUBW_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xF90F ); }
|
||||
emitterT void SSE2_PSUBD_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFA0F ); }
|
||||
emitterT void SSE2_PSUBD_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFA0F ); }
|
||||
emitterT void SSE2_PSUBQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xFB0F ); }
|
||||
emitterT void SSE2_PSUBQ_M128_to_XMM(x86SSERegType to, uptr from ){ SSEMtoR66( 0xFB0F ); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// shift right logical
|
||||
|
||||
emitterT void SSE2_PSRLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD10F); }
|
||||
emitterT void SSE2_PSRLW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD10F); }
|
||||
emitterT void SSE2_PSRLW_I8_to_XMM(x86SSERegType to, u8 imm8)
|
||||
{
|
||||
write8( 0x66 );
|
||||
RexB(0, to);
|
||||
write16( 0x710F );
|
||||
ModRM( 3, 2 , to );
|
||||
write8( imm8 );
|
||||
}
|
||||
|
||||
emitterT void SSE2_PSRLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD20F); }
|
||||
emitterT void SSE2_PSRLD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD20F); }
|
||||
emitterT void SSE2_PSRLD_I8_to_XMM(x86SSERegType to, u8 imm8)
|
||||
{
|
||||
write8( 0x66 );
|
||||
RexB(0, to);
|
||||
write16( 0x720F );
|
||||
ModRM( 3, 2 , to );
|
||||
write8( imm8 );
|
||||
}
|
||||
|
||||
emitterT void SSE2_PSRLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xD30F); }
|
||||
emitterT void SSE2_PSRLQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xD30F); }
|
||||
emitterT void SSE2_PSRLQ_I8_to_XMM(x86SSERegType to, u8 imm8)
|
||||
{
|
||||
write8( 0x66 );
|
||||
RexB(0, to);
|
||||
write16( 0x730F );
|
||||
ModRM( 3, 2 , to );
|
||||
write8( imm8 );
|
||||
}
|
||||
|
||||
emitterT void SSE2_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 SSE2_PSRAW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xE10F); }
|
||||
|
@ -509,50 +367,6 @@ emitterT void SSE2_PSRAD_I8_to_XMM(x86SSERegType to, u8 imm8)
|
|||
write8( imm8 );
|
||||
}
|
||||
|
||||
// shift left logical
|
||||
|
||||
emitterT void SSE2_PSLLW_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF10F); }
|
||||
emitterT void SSE2_PSLLW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF10F); }
|
||||
emitterT void SSE2_PSLLW_I8_to_XMM(x86SSERegType to, u8 imm8)
|
||||
{
|
||||
write8( 0x66 );
|
||||
RexB(0, to);
|
||||
write16( 0x710F );
|
||||
ModRM( 3, 6 , to );
|
||||
write8( imm8 );
|
||||
}
|
||||
|
||||
emitterT void SSE2_PSLLD_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF20F); }
|
||||
emitterT void SSE2_PSLLD_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF20F); }
|
||||
emitterT void SSE2_PSLLD_I8_to_XMM(x86SSERegType to, u8 imm8)
|
||||
{
|
||||
write8( 0x66 );
|
||||
RexB(0, to);
|
||||
write16( 0x720F );
|
||||
ModRM( 3, 6 , to );
|
||||
write8( imm8 );
|
||||
}
|
||||
|
||||
emitterT void SSE2_PSLLQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66(0xF30F); }
|
||||
emitterT void SSE2_PSLLQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66(0xF30F); }
|
||||
emitterT void SSE2_PSLLQ_I8_to_XMM(x86SSERegType to, u8 imm8)
|
||||
{
|
||||
write8( 0x66 );
|
||||
RexB(0, to);
|
||||
write16( 0x730F );
|
||||
ModRM( 3, 6 , to );
|
||||
write8( imm8 );
|
||||
}
|
||||
|
||||
emitterT void SSE2_PSLLDQ_I8_to_XMM(x86SSERegType to, u8 imm8)
|
||||
{
|
||||
write8( 0x66 );
|
||||
RexB(0, to);
|
||||
write16( 0x730F );
|
||||
ModRM( 3, 7 , to );
|
||||
write8( imm8 );
|
||||
}
|
||||
|
||||
emitterT void SSE2_PMAXSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xEE0F ); }
|
||||
emitterT void SSE2_PMAXSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEE0F ); }
|
||||
|
||||
|
@ -565,28 +379,6 @@ emitterT void SSE2_PMINSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR
|
|||
emitterT void SSE2_PMINUB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDA0F ); }
|
||||
emitterT void SSE2_PMINUB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDA0F ); }
|
||||
|
||||
emitterT void SSE2_PADDSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xEC0F ); }
|
||||
emitterT void SSE2_PADDSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEC0F ); }
|
||||
|
||||
emitterT void SSE2_PADDSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xED0F ); }
|
||||
emitterT void SSE2_PADDSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xED0F ); }
|
||||
|
||||
emitterT void SSE2_PSUBSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xE80F ); }
|
||||
emitterT void SSE2_PSUBSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xE80F ); }
|
||||
|
||||
emitterT void SSE2_PSUBSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xE90F ); }
|
||||
emitterT void SSE2_PSUBSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xE90F ); }
|
||||
|
||||
emitterT void SSE2_PSUBUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD80F ); }
|
||||
emitterT void SSE2_PSUBUSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xD80F ); }
|
||||
emitterT void SSE2_PSUBUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xD90F ); }
|
||||
emitterT void SSE2_PSUBUSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xD90F ); }
|
||||
|
||||
emitterT void SSE2_PADDUSB_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDC0F ); }
|
||||
emitterT void SSE2_PADDUSB_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDC0F ); }
|
||||
emitterT void SSE2_PADDUSW_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xDD0F ); }
|
||||
emitterT void SSE2_PADDUSW_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xDD0F ); }
|
||||
|
||||
//**********************************************************************************/
|
||||
//PACKSSWB,PACKSSDW: Pack Saturate Signed Word
|
||||
//**********************************************************************************
|
||||
|
|
|
@ -693,6 +693,10 @@ namespace x86Emitter
|
|||
extern void EmitSibMagic( uint regfield, const ModSibBase& info );
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
template< typename T > bool Is8BitOp() { return sizeof(T) == 1; }
|
||||
template< typename T > void prefix16() { if( sizeof(T) == 2 ) xWrite<u8>( 0x66 ); }
|
||||
|
||||
#include "implement/xmm/movqss.h"
|
||||
#include "implement/group1.h"
|
||||
#include "implement/group2.h"
|
||||
|
|
Loading…
Reference in New Issue