mirror of https://github.com/PCSX2/pcsx2.git
Emitter: Fixed a GCC compilation error; Implemented MOVNT/MOVLH/MOVHL/PMOVMSKB, and tied in all old emitter references to MOVAPS/MOVDQA to the new versions.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1020 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
bb7dc87819
commit
d91eb6d1c8
|
@ -56,15 +56,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
#ifndef __LINUX__
|
|
||||||
static __emitinline void Emit( void* bitbase, const iRegister<ImmType>& bitoffset )
|
static __emitinline void Emit( void* bitbase, const iRegister<ImmType>& bitoffset )
|
||||||
{
|
{
|
||||||
prefix16();
|
prefix16();
|
||||||
iWrite<u8>( 0x0f );
|
iWrite<u8>( 0x0f );
|
||||||
iWrite<u8>( 0xa3 | (InstType << 2) );
|
iWrite<u8>( 0xa3 | (InstType << 2) );
|
||||||
iWriteDisp( bitoffset.Id, bitbase.Id );
|
iWriteDisp( bitoffset.Id, bitbase );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
static __emitinline void Emit( const ModSibBase& bitbase, const iRegister<ImmType>& bitoffset )
|
static __emitinline void Emit( const ModSibBase& bitbase, const iRegister<ImmType>& bitoffset )
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
// MMX / SSE Helper Functions!
|
// MMX / SSE Helper Functions!
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
__emitinline void SimdPrefix( u8 opcode, u8 prefix )
|
__emitinline void SimdPrefix( u8 opcode, u8 prefix=0 )
|
||||||
{
|
{
|
||||||
if( sizeof( T ) == 16 && prefix != 0 )
|
if( sizeof( T ) == 16 && prefix != 0 )
|
||||||
{
|
{
|
||||||
|
@ -33,84 +33,84 @@ __emitinline void SimdPrefix( u8 opcode, u8 prefix )
|
||||||
iWrite<u16>( (opcode<<8) | 0x0f );
|
iWrite<u16>( (opcode<<8) | 0x0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< u8 prefix, typename T, typename T2 >
|
// ------------------------------------------------------------------------
|
||||||
__emitinline void writeXMMop( u8 opcode, const iRegister<T>& to, const iRegister<T2>& from )
|
// xmm emitter helpers for xmm instruction with prefixes.
|
||||||
|
// These functions also support deducing the use of the prefix from the template parameters,
|
||||||
|
// since most xmm instructions use a prefix and most mmx instructions do not. (some mov
|
||||||
|
// instructions violate this "guideline.")
|
||||||
|
//
|
||||||
|
template< typename T, typename T2 >
|
||||||
|
__emitinline void writeXMMop( u8 prefix, u8 opcode, const iRegister<T>& to, const iRegister<T2>& from )
|
||||||
{
|
{
|
||||||
SimdPrefix<T>( opcode, prefix );
|
SimdPrefix<T>( opcode, prefix );
|
||||||
ModRM_Direct( to.Id, from.Id );
|
ModRM_Direct( to.Id, from.Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< u8 prefix, typename T >
|
template< typename T >
|
||||||
void writeXMMop( u8 opcode, const iRegister<T>& reg, const ModSibBase& sib )
|
void writeXMMop( u8 prefix, u8 opcode, const iRegister<T>& reg, const ModSibBase& sib )
|
||||||
{
|
{
|
||||||
SimdPrefix<T>( opcode, prefix );
|
SimdPrefix<T>( opcode, prefix );
|
||||||
EmitSibMagic( reg.Id, sib );
|
EmitSibMagic( reg.Id, sib );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< u8 prefix, typename T >
|
template< typename T >
|
||||||
__emitinline void writeXMMop( u8 opcode, const iRegister<T>& reg, const void* data )
|
__emitinline void writeXMMop( u8 prefix, u8 opcode, const iRegister<T>& reg, const void* data )
|
||||||
{
|
{
|
||||||
SimdPrefix<T>( opcode, prefix );
|
SimdPrefix<T>( opcode, prefix );
|
||||||
iWriteDisp( reg.Id, data );
|
iWriteDisp( reg.Id, data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// xmm emitter helpers for xmm instructions *without* prefixes.
|
||||||
|
// These are normally used for special instructions that have MMX forms only (non-SSE), however
|
||||||
|
// some special forms of sse/xmm mov instructions also use them due to prefixing inconsistencies.
|
||||||
|
//
|
||||||
|
template< typename T, typename T2 >
|
||||||
|
__emitinline void writeXMMop( u8 opcode, const iRegister<T>& to, const iRegister<T2>& from )
|
||||||
|
{
|
||||||
|
SimdPrefix<T>( opcode );
|
||||||
|
ModRM_Direct( to.Id, from.Id );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
void writeXMMop( u8 opcode, const iRegister<T>& reg, const ModSibBase& sib )
|
||||||
|
{
|
||||||
|
SimdPrefix<T>( opcode );
|
||||||
|
EmitSibMagic( reg.Id, sib );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
__emitinline void writeXMMop( u8 opcode, const iRegister<T>& reg, const void* data )
|
||||||
|
{
|
||||||
|
SimdPrefix<T>( opcode );
|
||||||
|
iWriteDisp( reg.Id, data );
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
template< u8 Prefix, typename OperandType >
|
// Moves to/from high/low portions of an xmm register.
|
||||||
class MovapsImpl
|
// These instructions cannot be used in reg/reg form.
|
||||||
|
template< u8 Prefix, u8 Opcode >
|
||||||
|
class MovhlImplAll
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// ------------------------------------------------------------------------
|
__forceinline void operator()( const iRegisterSSE& to, const void* from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||||
static __emitinline void Emit( u8 opcode, const iRegisterSIMD<OperandType>& to, const iRegisterSIMD<OperandType> from )
|
__forceinline void operator()( const void* to, const iRegisterSSE& from ) const { writeXMMop( Prefix, Opcode+1, from, to ); }
|
||||||
{
|
__noinline void operator()( const iRegisterSSE& to, const ModSibBase& from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||||
if( to != from )
|
__noinline void operator()( const ModSibBase& to, const iRegisterSSE& from ) const { writeXMMop( Prefix, Opcode+1, from, to ); }
|
||||||
writeXMMop<Prefix,OperandType>( opcode, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
static __emitinline void Emit( u8 opcode, const iRegisterSIMD<OperandType>& to, const void* from )
|
|
||||||
{
|
|
||||||
writeXMMop<Prefix,OperandType>( opcode, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
static __emitinline void Emit( u8 opcode, const iRegisterSIMD<OperandType>& to, const ModSibBase& from )
|
|
||||||
{
|
|
||||||
writeXMMop<Prefix,OperandType>( opcode, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// Generally a Movaps/dqa instruction form only.
|
|
||||||
// Most SSE/MMX instructions don't have this form.
|
|
||||||
static __emitinline void Emit( u8 opcode, const void* to, const iRegisterSIMD<OperandType>& from )
|
|
||||||
{
|
|
||||||
writeXMMop<Prefix,OperandType>( opcode, from, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// Generally a Movaps/dqa instruction form only.
|
|
||||||
// Most SSE/MMX instructions don't have this form.
|
|
||||||
static __emitinline void Emit( u8 opcode, const ModSibBase& to, const iRegisterSIMD<OperandType>& from )
|
|
||||||
{
|
|
||||||
writeXMMop<Prefix,OperandType>( opcode, from, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
MovhlImplAll() {} //GCC.
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
template< u8 Prefix, u8 Opcode, u8 OpcodeAlt >
|
template< u8 Prefix, u8 Opcode, u8 OpcodeAlt >
|
||||||
class MovapsImplAll
|
class MovapsImplAll
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
typedef MovapsImpl<Prefix, u128> m_128;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
__forceinline void operator()( const iRegisterSSE& to, const iRegisterSSE& from ) const { m_128::Emit( Opcode, to, from ); }
|
__forceinline void operator()( const iRegisterSSE& to, const iRegisterSSE& from ) const { if( to != from ) writeXMMop( Prefix, Opcode, to, from ); }
|
||||||
__forceinline void operator()( const iRegisterSSE& to, const void* from ) const { m_128::Emit( Opcode, to, from ); }
|
__forceinline void operator()( const iRegisterSSE& to, const void* from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||||
__forceinline void operator()( const void* to, const iRegisterSSE& from ) const { m_128::Emit( OpcodeAlt, to, from ); }
|
__forceinline void operator()( const void* to, const iRegisterSSE& from ) const { writeXMMop( Prefix, OpcodeAlt, from, to ); }
|
||||||
__noinline void operator()( const iRegisterSSE& to, const ModSibBase& from ) const { m_128::Emit( Opcode, to, from ); }
|
__noinline void operator()( const iRegisterSSE& to, const ModSibBase& from ) const { writeXMMop( Prefix, Opcode, to, from ); }
|
||||||
__noinline void operator()( const ModSibBase& to, const iRegisterSSE& from ) const { m_128::Emit( OpcodeAlt, to, from ); }
|
__noinline void operator()( const ModSibBase& to, const iRegisterSSE& from ) const { writeXMMop( Prefix, OpcodeAlt, from, to ); }
|
||||||
|
|
||||||
MovapsImplAll() {} //GCC.
|
MovapsImplAll() {} //GCC.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -740,29 +740,40 @@ const MovapsImplAll< 0, 0x10, 0x11 > iMOVUPS;
|
||||||
const MovapsImplAll< 0x66, 0x28, 0x29 > iMOVAPD;
|
const MovapsImplAll< 0x66, 0x28, 0x29 > iMOVAPD;
|
||||||
const MovapsImplAll< 0x66, 0x10, 0x11 > iMOVUPD;
|
const MovapsImplAll< 0x66, 0x10, 0x11 > iMOVUPD;
|
||||||
|
|
||||||
|
#ifdef ALWAYS_USE_MOVAPS
|
||||||
const MovapsImplAll< 0x66, 0x6f, 0x7f > iMOVDQA;
|
const MovapsImplAll< 0x66, 0x6f, 0x7f > iMOVDQA;
|
||||||
const MovapsImplAll< 0xf3, 0x6f, 0x7f > iMOVDQU;
|
const MovapsImplAll< 0xf3, 0x6f, 0x7f > iMOVDQU;
|
||||||
|
#else
|
||||||
|
const MovapsImplAll< 0, 0x28, 0x29 > iMOVDQA;
|
||||||
|
const MovapsImplAll< 0, 0x10, 0x11 > iMOVDQU;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const MovhlImplAll< 0, 0x16 > iMOVHPS;
|
||||||
|
const MovhlImplAll< 0, 0x12 > iMOVLPS;
|
||||||
|
const MovhlImplAll< 0x66, 0x16 > iMOVHPD;
|
||||||
|
const MovhlImplAll< 0x66, 0x12 > iMOVLPD;
|
||||||
|
|
||||||
|
|
||||||
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
||||||
// being cleared to zero.
|
// being cleared to zero.
|
||||||
__emitinline void iMOVQZX( const iRegisterSSE& to, const iRegisterSSE& from ) { writeXMMop<0xf3>( 0x7e, to, from ); }
|
__forceinline void iMOVQZX( const iRegisterSSE& to, const iRegisterSSE& from ) { writeXMMop( 0xf3, 0x7e, to, from ); }
|
||||||
|
|
||||||
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
||||||
// being cleared to zero.
|
// being cleared to zero.
|
||||||
__noinline void iMOVQZX( const iRegisterSSE& to, const ModSibBase& src ) { writeXMMop<0xf3>( 0x7e, to, src ); }
|
__noinline void iMOVQZX( const iRegisterSSE& to, const ModSibBase& src ) { writeXMMop( 0xf3, 0x7e, to, src ); }
|
||||||
|
|
||||||
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
||||||
// being cleared to zero.
|
// being cleared to zero.
|
||||||
__emitinline void iMOVQZX( const iRegisterSSE& to, const void* src ) { writeXMMop<0xf3>( 0x7e, to, src ); }
|
__forceinline void iMOVQZX( const iRegisterSSE& to, const void* src ) { writeXMMop( 0xf3, 0x7e, to, src ); }
|
||||||
|
|
||||||
__emitinline void iMOVQ( const iRegisterMMX& to, const iRegisterMMX& from ) { if( to != from ) writeXMMop<0>( 0x6f, to, from ); }
|
__forceinline void iMOVQ( const iRegisterMMX& to, const iRegisterMMX& from ) { if( to != from ) writeXMMop( 0x6f, to, from ); }
|
||||||
__noinline void iMOVQ( const iRegisterMMX& to, const ModSibBase& src ) { writeXMMop<0>( 0x6f, to, src ); }
|
__noinline void iMOVQ( const iRegisterMMX& to, const ModSibBase& src ) { writeXMMop( 0x6f, to, src ); }
|
||||||
__emitinline void iMOVQ( const iRegisterMMX& to, const void* src ) { writeXMMop<0>( 0x6f, to, src ); }
|
__forceinline void iMOVQ( const iRegisterMMX& to, const void* src ) { writeXMMop( 0x6f, to, src ); }
|
||||||
__forceinline void iMOVQ( const ModSibBase& dest, const iRegisterMMX& from ) { writeXMMop<0>( 0x7f, from, dest ); }
|
__forceinline void iMOVQ( const ModSibBase& dest, const iRegisterMMX& from ) { writeXMMop( 0x7f, from, dest ); }
|
||||||
__forceinline void iMOVQ( void* dest, const iRegisterMMX& from ) { writeXMMop<0>( 0x7f, from, dest ); }
|
__forceinline void iMOVQ( void* dest, const iRegisterMMX& from ) { writeXMMop( 0x7f, from, dest ); }
|
||||||
__forceinline void iMOVQ( const ModSibBase& dest, const iRegisterSSE& from ) { writeXMMop<0xf3>( 0x7e, from, dest ); }
|
__forceinline void iMOVQ( const ModSibBase& dest, const iRegisterSSE& from ) { writeXMMop( 0xf3, 0x7e, from, dest ); }
|
||||||
__forceinline void iMOVQ( void* dest, const iRegisterSSE& from ) { writeXMMop<0xf3>( 0x7e, from, dest ); }
|
__forceinline void iMOVQ( void* dest, const iRegisterSSE& from ) { writeXMMop( 0xf3, 0x7e, from, dest ); }
|
||||||
__forceinline void iMOVQ( const iRegisterSSE& to, const iRegisterMMX& from ) { writeXMMop<0xf3>( 0xd6, to, from ); }
|
__forceinline void iMOVQ( const iRegisterSSE& to, const iRegisterMMX& from ) { writeXMMop( 0xf3, 0xd6, to, from ); }
|
||||||
__forceinline void iMOVQ( const iRegisterMMX& to, const iRegisterSSE& from )
|
__forceinline void iMOVQ( const iRegisterMMX& to, const iRegisterSSE& from )
|
||||||
{
|
{
|
||||||
// Manual implementation of this form of MOVQ, since its parameters are unique in a way
|
// Manual implementation of this form of MOVQ, since its parameters are unique in a way
|
||||||
|
@ -776,16 +787,52 @@ __forceinline void iMOVQ( const iRegisterMMX& to, const iRegisterSSE& from )
|
||||||
//
|
//
|
||||||
|
|
||||||
#define IMPLEMENT_iMOVS( ssd, prefix ) \
|
#define IMPLEMENT_iMOVS( ssd, prefix ) \
|
||||||
__forceinline void iMOV##ssd( const iRegisterSSE& to, const iRegisterSSE& from ) { if( to != from ) writeXMMop<prefix>( 0x10, to, from ); } \
|
__forceinline void iMOV##ssd( const iRegisterSSE& to, const iRegisterSSE& from ) { if( to != from ) writeXMMop( prefix, 0x10, to, from ); } \
|
||||||
__forceinline void iMOV##ssd##ZX( const iRegisterSSE& to, const void* from ) { writeXMMop<prefix>( 0x10, to, from ); } \
|
__forceinline void iMOV##ssd##ZX( const iRegisterSSE& to, const void* from ) { writeXMMop( prefix, 0x10, to, from ); } \
|
||||||
__forceinline void iMOV##ssd##ZX( const iRegisterSSE& to, const ModSibBase& from ) { writeXMMop<prefix>( 0x10, to, from ); } \
|
__forceinline void iMOV##ssd##ZX( const iRegisterSSE& to, const ModSibBase& from ) { writeXMMop( prefix, 0x10, to, from ); } \
|
||||||
__forceinline void iMOV##ssd( const void* to, const iRegisterSSE& from ) { writeXMMop<prefix>( 0x11, from, to ); } \
|
__forceinline void iMOV##ssd( const void* to, const iRegisterSSE& from ) { writeXMMop( prefix, 0x11, from, to ); } \
|
||||||
__forceinline void iMOV##ssd( const ModSibBase& to, const iRegisterSSE& from ) { writeXMMop<prefix>( 0x11, from, to ); }
|
__forceinline void iMOV##ssd( const ModSibBase& to, const iRegisterSSE& from ) { writeXMMop( prefix, 0x11, from, to ); }
|
||||||
|
|
||||||
IMPLEMENT_iMOVS( SS, 0xf3 )
|
IMPLEMENT_iMOVS( SS, 0xf3 )
|
||||||
IMPLEMENT_iMOVS( SD, 0xf2 )
|
IMPLEMENT_iMOVS( SD, 0xf2 )
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Non-temporal movs only support a register as a target (ie, load form only, no stores)
|
||||||
//
|
//
|
||||||
|
|
||||||
|
__forceinline void iMOVNTDQA( const iRegisterSSE& to, const void* from )
|
||||||
|
{
|
||||||
|
iWrite<u32>( 0x2A380f66 );
|
||||||
|
iWriteDisp( to.Id, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
__noinline void iMOVNTDQA( const iRegisterSSE& to, const ModSibBase& from )
|
||||||
|
{
|
||||||
|
iWrite<u32>( 0x2A380f66 );
|
||||||
|
EmitSibMagic( to.Id, from );
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline void iMOVNTDQ( void* to, const iRegisterSSE& from ) { writeXMMop( 0x66, 0xe7, from, to ); }
|
||||||
|
__noinline void iMOVNTDQA( const ModSibBase& to, const iRegisterSSE& from ) { writeXMMop( 0x66, 0xe7, from, to ); }
|
||||||
|
|
||||||
|
__forceinline void iMOVNTPD( void* to, const iRegisterSSE& from ) { writeXMMop( 0x66, 0x2b, from, to ); }
|
||||||
|
__noinline void iMOVNTPD( const ModSibBase& to, const iRegisterSSE& from ) { writeXMMop( 0x66, 0x2b, from, to ); }
|
||||||
|
__forceinline void iMOVNTPS( void* to, const iRegisterSSE& from ) { writeXMMop( 0x2b, from, to ); }
|
||||||
|
__noinline void iMOVNTPS( const ModSibBase& to, const iRegisterSSE& from ) { writeXMMop( 0x2b, from, to ); }
|
||||||
|
|
||||||
|
__forceinline void iMOVNTQ( void* to, const iRegisterMMX& from ) { writeXMMop( 0xe7, from, to ); }
|
||||||
|
__noinline void iMOVNTQ( const ModSibBase& to, const iRegisterMMX& from ) { writeXMMop( 0xe7, from, to ); }
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Mov Low to High / High to Low
|
||||||
|
//
|
||||||
|
// These instructions come in xmmreg,xmmreg forms only!
|
||||||
|
//
|
||||||
|
|
||||||
|
__forceinline void iMOVLHPS( const iRegisterSSE& to, const iRegisterSSE& from ) { writeXMMop( 0x16, to, from ); }
|
||||||
|
__forceinline void iMOVHLPS( const iRegisterSSE& to, const iRegisterSSE& from ) { writeXMMop( 0x12, to, from ); }
|
||||||
|
__forceinline void iMOVLHPD( const iRegisterSSE& to, const iRegisterSSE& from ) { writeXMMop( 0x66, 0x16, to, from ); }
|
||||||
|
__forceinline void iMOVHLPD( const iRegisterSSE& to, const iRegisterSSE& from ) { writeXMMop( 0x66, 0x12, to, from ); }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,42 +331,60 @@ namespace x86Emitter
|
||||||
template< typename T >
|
template< typename T >
|
||||||
__emitinline void iMOVDZX( const iRegisterSIMD<T>& to, const iRegister32& from )
|
__emitinline void iMOVDZX( const iRegisterSIMD<T>& to, const iRegister32& from )
|
||||||
{
|
{
|
||||||
Internal::writeXMMop<0x66>( 0x6e, to, from );
|
Internal::writeXMMop( 0x66, 0x6e, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
__emitinline void iMOVDZX( const iRegisterSIMD<T>& to, const void* src )
|
__emitinline void iMOVDZX( const iRegisterSIMD<T>& to, const void* src )
|
||||||
{
|
{
|
||||||
Internal::writeXMMop<0x66>( 0x6e, to, src );
|
Internal::writeXMMop( 0x66, 0x6e, to, src );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
void iMOVDZX( const iRegisterSIMD<T>& to, const ModSibBase& src )
|
void iMOVDZX( const iRegisterSIMD<T>& to, const ModSibBase& src )
|
||||||
{
|
{
|
||||||
Internal::writeXMMop<0x66>( 0x6e, to, src );
|
Internal::writeXMMop( 0x66, 0x6e, to, src );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
__emitinline void iMOVD( const iRegister32& to, const iRegisterSIMD<T>& from )
|
__emitinline void iMOVD( const iRegister32& to, const iRegisterSIMD<T>& from )
|
||||||
{
|
{
|
||||||
Internal::writeXMMop<0x66>( 0x7e, from, to );
|
Internal::writeXMMop( 0x66, 0x7e, from, to );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
__emitinline void iMOVD( void* dest, const iRegisterSIMD<T>& from )
|
__emitinline void iMOVD( void* dest, const iRegisterSIMD<T>& from )
|
||||||
{
|
{
|
||||||
Internal::writeXMMop<0x66>( 0x7e, from, dest );
|
Internal::writeXMMop( 0x66, 0x7e, from, dest );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
void iMOVD( const ModSibBase& dest, const iRegisterSIMD<T>& from )
|
void iMOVD( const ModSibBase& dest, const iRegisterSIMD<T>& from )
|
||||||
{
|
{
|
||||||
Internal::writeXMMop<0x66>( 0x7e, from, dest );
|
Internal::writeXMMop( 0x66, 0x7e, from, dest );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// iMASKMOV:
|
||||||
|
// Selectively write bytes from mm1/xmm1 to memory location using the byte mask in mm2/xmm2.
|
||||||
|
// The default memory location is specified by DS:EDI. The most significant bit in each byte
|
||||||
|
// of the mask operand determines whether the corresponding byte in the source operand is
|
||||||
|
// written to the corresponding byte location in memory.
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
static __forceinline void iMASKMOV( const iRegisterSIMD<T>& to, const iRegisterSIMD<T>& from ) { Internal::writeXMMop( 0x66, 0xf7, to, from ); }
|
||||||
|
|
||||||
|
// iPMOVMSKB:
|
||||||
|
// Creates a mask made up of the most significant bit of each byte of the source
|
||||||
|
// operand and stores the result in the low byte or word of the destination operand.
|
||||||
|
// Upper bits of the destination are cleared to zero.
|
||||||
|
//
|
||||||
|
// When operating on a 64-bit (MMX) source, the byte mask is 8 bits; when operating on
|
||||||
|
// 128-bit (SSE) source, the byte mask is 16-bits.
|
||||||
|
//
|
||||||
|
template< typename T >
|
||||||
|
static __forceinline void iPMOVMSKB( const iRegister32& to, const iRegisterSIMD<T>& from ) { Internal::writeXMMop( 0x66, 0xd7, to, from ); }
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -397,5 +415,22 @@ namespace x86Emitter
|
||||||
extern void iMOVSDZX( const iRegisterSSE& to, const void* from );
|
extern void iMOVSDZX( const iRegisterSSE& to, const void* from );
|
||||||
extern void iMOVSDZX( const iRegisterSSE& to, const ModSibBase& from );
|
extern void iMOVSDZX( const iRegisterSSE& to, const ModSibBase& from );
|
||||||
|
|
||||||
|
extern void iMOVNTDQA( const iRegisterSSE& to, const void* from );
|
||||||
|
extern void iMOVNTDQA( const iRegisterSSE& to, const ModSibBase& from );
|
||||||
|
extern void iMOVNTDQ( void* to, const iRegisterSSE& from );
|
||||||
|
extern void iMOVNTDQA( const ModSibBase& to, const iRegisterSSE& from );
|
||||||
|
|
||||||
|
extern void iMOVNTPD( void* to, const iRegisterSSE& from );
|
||||||
|
extern void iMOVNTPD( const ModSibBase& to, const iRegisterSSE& from );
|
||||||
|
extern void iMOVNTPS( void* to, const iRegisterSSE& from );
|
||||||
|
extern void iMOVNTPS( const ModSibBase& to, const iRegisterSSE& from );
|
||||||
|
extern void iMOVNTQ( void* to, const iRegisterMMX& from );
|
||||||
|
extern void iMOVNTQ( const ModSibBase& to, const iRegisterMMX& from );
|
||||||
|
|
||||||
|
extern void iMOVLHPS( const iRegisterSSE& to, const iRegisterSSE& from );
|
||||||
|
extern void iMOVHLPS( const iRegisterSSE& to, const iRegisterSSE& from );
|
||||||
|
extern void iMOVLHPD( const iRegisterSSE& to, const iRegisterSSE& from );
|
||||||
|
extern void iMOVHLPD( const iRegisterSSE& to, const iRegisterSSE& from );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -977,19 +977,13 @@ extern void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offs
|
||||||
|
|
||||||
extern void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
extern void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
||||||
extern void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
extern void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
||||||
extern void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from );
|
|
||||||
extern void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 );
|
extern void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 );
|
||||||
extern void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from );
|
|
||||||
extern void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from, int offset=0 );
|
extern void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from, int offset=0 );
|
||||||
|
|
||||||
extern void SSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 );
|
|
||||||
extern void SSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 );
|
|
||||||
extern void SSE_MOVAPSRtoRm( x86IntRegType to, x86SSERegType from, int offset=0 );
|
extern void SSE_MOVAPSRtoRm( x86IntRegType to, x86SSERegType from, int offset=0 );
|
||||||
extern void SSE_MOVAPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 );
|
extern void SSE_MOVAPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 );
|
||||||
extern void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 );
|
extern void SSE_MOVUPSRtoRm( x86IntRegType to, x86SSERegType from );
|
||||||
extern void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 );
|
extern void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from );
|
||||||
extern void SSE_MOVUPSRtoRm( x86IntRegType to, x86IntRegType from );
|
|
||||||
extern void SSE_MOVUPSRmtoR( x86IntRegType to, x86IntRegType from );
|
|
||||||
|
|
||||||
extern void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 );
|
extern void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 );
|
||||||
extern void SSE_MOVUPSRtoRm( x86SSERegType to, x86IntRegType from, int offset=0 );
|
extern void SSE_MOVUPSRtoRm( x86SSERegType to, x86IntRegType from, int offset=0 );
|
||||||
|
|
|
@ -27,23 +27,27 @@
|
||||||
|
|
||||||
using namespace x86Emitter;
|
using namespace x86Emitter;
|
||||||
|
|
||||||
/* movq m64 to r64 */
|
emitterT void MOVQMtoR( x86MMXRegType to, uptr from ) { iMOVQ( iRegisterMMX(to), (void*)from ); }
|
||||||
emitterT void MOVQMtoR( x86MMXRegType to, uptr from )
|
emitterT void MOVQRtoM( uptr to, x86MMXRegType from ) { iMOVQ( (void*)to, iRegisterMMX(from) ); }
|
||||||
|
emitterT void MOVQRtoR( x86MMXRegType to, x86MMXRegType from ) { iMOVQ( iRegisterMMX(to), iRegisterMMX(from) ); }
|
||||||
|
emitterT void MOVQRmtoR( x86MMXRegType to, x86IntRegType from, int offset ) { iMOVQ( iRegisterMMX(to), ptr[iAddressReg(from)+offset] ); }
|
||||||
|
emitterT void MOVQRtoRm( x86IntRegType to, x86MMXRegType from, int offset ) { iMOVQ( ptr[iAddressReg(to)+offset], iRegisterMMX(from) ); }
|
||||||
|
|
||||||
|
emitterT void MOVDMtoMMX( x86MMXRegType to, uptr from ) { iMOVDZX( iRegisterMMX(to), (void*)from ); }
|
||||||
|
emitterT void MOVDMMXtoM( uptr to, x86MMXRegType from ) { iMOVD( (void*)to, iRegisterMMX(from) ); }
|
||||||
|
emitterT void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from ) { iMOVDZX( iRegisterMMX(to), iRegister32(from) ); }
|
||||||
|
emitterT void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from, int offset ) { iMOVDZX( iRegisterMMX(to), ptr[iAddressReg(from)+offset] ); }
|
||||||
|
emitterT void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from ) { iMOVD( iRegister32(to), iRegisterMMX(from) ); }
|
||||||
|
emitterT void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from, int offset ) { iMOVD( ptr[iAddressReg(to)+offset], iRegisterMMX(from) ); }
|
||||||
|
|
||||||
|
emitterT void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from)
|
||||||
{
|
{
|
||||||
iMOVQ( iRegisterMMX(to), (void*)from );
|
iPMOVMSKB( iRegister32(to), iRegisterMMX(from) );
|
||||||
//write16( 0x6F0F );
|
|
||||||
//ModRM( 0, to, DISP32 );
|
|
||||||
//write32( MEMADDR(from, 4) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* movq r64 to m64 */
|
|
||||||
emitterT void MOVQRtoM( uptr to, x86MMXRegType from )
|
|
||||||
{
|
|
||||||
iMOVQ( (void*)to, iRegisterMMX(from) );
|
|
||||||
//write16( 0x7F0F );
|
|
||||||
//ModRM( 0, from, DISP32 );
|
|
||||||
//write32(MEMADDR(to, 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pand r64 to r64 */
|
/* pand r64 to r64 */
|
||||||
emitterT void PANDRtoR( x86MMXRegType to, x86MMXRegType from )
|
emitterT void PANDRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
|
@ -474,73 +478,6 @@ emitterT void PUNPCKLDQMtoR( x86MMXRegType to, uptr from )
|
||||||
write32( MEMADDR(from, 4) );
|
write32( MEMADDR(from, 4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVQRtoR( x86MMXRegType to, x86MMXRegType from )
|
|
||||||
{
|
|
||||||
iMOVQ( iRegisterMMX(to), iRegisterMMX(from) );
|
|
||||||
//write16( 0x6F0F );
|
|
||||||
//ModRM( 3, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void MOVQRmtoR( x86MMXRegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
|
||||||
iMOVQ( iRegisterMMX(to), ptr[iAddressReg(from)+offset] );
|
|
||||||
//write16( 0x6F0F );
|
|
||||||
//WriteRmOffsetFrom( to, from, offset );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void MOVQRtoRm( x86IntRegType to, x86MMXRegType from, int offset )
|
|
||||||
{
|
|
||||||
iMOVQ( ptr[iAddressReg(to)+offset], iRegisterMMX(from) );
|
|
||||||
//write16( 0x7F0F );
|
|
||||||
//WriteRmOffsetFrom( from, to, offset );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* movd m32 to r64 */
|
|
||||||
emitterT void MOVDMtoMMX( x86MMXRegType to, uptr from )
|
|
||||||
{
|
|
||||||
iMOVDZX( iRegisterMMX(to), (void*)from );
|
|
||||||
//write16( 0x6E0F );
|
|
||||||
//ModRM( 0, to, DISP32 );
|
|
||||||
//write32( MEMADDR(from, 4) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* movd r64 to m32 */
|
|
||||||
emitterT void MOVDMMXtoM( uptr to, x86MMXRegType from )
|
|
||||||
{
|
|
||||||
iMOVD( (void*)to, iRegisterMMX(from) );
|
|
||||||
//write16( 0x7E0F );
|
|
||||||
//ModRM( 0, from, DISP32 );
|
|
||||||
//write32( MEMADDR(to, 4) );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from )
|
|
||||||
{
|
|
||||||
iMOVDZX( iRegisterMMX(to), iRegister32(from) );
|
|
||||||
//write16( 0x6E0F );
|
|
||||||
//ModRM( 3, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
|
||||||
iMOVDZX( iRegisterMMX(to), ptr[iAddressReg(from)+offset] );
|
|
||||||
//write16( 0x6E0F );
|
|
||||||
//WriteRmOffsetFrom( to, from, offset );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from )
|
|
||||||
{
|
|
||||||
iMOVD( iRegister32(to), iRegisterMMX(from) );
|
|
||||||
//write16( 0x7E0F );
|
|
||||||
//ModRM( 3, from, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from, int offset )
|
|
||||||
{
|
|
||||||
iMOVD( ptr[iAddressReg(to)+offset], iRegisterMMX(from) );
|
|
||||||
//write16( 0x7E0F );
|
|
||||||
//WriteRmOffsetFrom( from, to, offset );
|
|
||||||
}
|
|
||||||
|
|
||||||
// untested
|
// untested
|
||||||
emitterT void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
|
emitterT void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
|
||||||
{
|
{
|
||||||
|
@ -554,12 +491,6 @@ emitterT void PACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
|
||||||
ModRM( 3, to, from );
|
ModRM( 3, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from)
|
|
||||||
{
|
|
||||||
write16( 0xD70F );
|
|
||||||
ModRM( 3, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 )
|
emitterT void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 )
|
||||||
{
|
{
|
||||||
if (to > 7 || from > 7) Rex(1, to >> 3, 0, from >> 3);
|
if (to > 7 || from > 7) Rex(1, to >> 3, 0, from >> 3);
|
||||||
|
@ -583,8 +514,4 @@ emitterT void PSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8)
|
||||||
write8(imm8);
|
write8(imm8);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from)
|
emitterT void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from) { iMASKMOV( iRegisterMMX(to), iRegisterMMX(from) ); }
|
||||||
{
|
|
||||||
write16(0xf70f);
|
|
||||||
ModRM( 3, to, from );
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,17 +22,6 @@
|
||||||
|
|
||||||
using namespace x86Emitter;
|
using namespace x86Emitter;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// AlwaysUseMovaps [const]
|
|
||||||
//
|
|
||||||
// This tells the recompiler's emitter to always use movaps instead of movdqa. Both instructions
|
|
||||||
// do the exact same thing, but movaps is 1 byte shorter, and thus results in a cleaner L1 cache
|
|
||||||
// and some marginal speed gains as a result. (it's possible someday in the future the per-
|
|
||||||
// formance of the two instructions could change, so this constant is provided to restore MOVDQA
|
|
||||||
// use easily at a later time, if needed).
|
|
||||||
//
|
|
||||||
static const bool AlwaysUseMovaps = true;
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// SSE instructions
|
// SSE instructions
|
||||||
|
@ -147,164 +136,28 @@ static const bool AlwaysUseMovaps = true;
|
||||||
SSE_SD_RtoR( 0xc20f ), \
|
SSE_SD_RtoR( 0xc20f ), \
|
||||||
write8( op )
|
write8( op )
|
||||||
|
|
||||||
/* movups [r32][r32*scale] to xmm1 */
|
#define DEFINE_LEGACY_MOV_OPCODE( mod, sse ) \
|
||||||
emitterT void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
emitterT void sse##_MOV##mod##_M128_to_XMM( x86SSERegType to, uptr from ) { iMOV##mod( iRegisterSSE(to), (void*)from ); } \
|
||||||
{
|
emitterT void sse##_MOV##mod##_XMM_to_M128( uptr to, x86SSERegType from ) { iMOV##mod( (void*)to, iRegisterSSE(from) ); } \
|
||||||
RexRXB(0, to, from2, from);
|
emitterT void sse##_MOV##mod##RmtoR( x86SSERegType to, x86IntRegType from, int offset ) { iMOV##mod( iRegisterSSE(to), ptr[iAddressReg(from)+offset] ); } \
|
||||||
write16( 0x100f );
|
emitterT void sse##_MOV##mod##RtoRm( x86IntRegType to, x86SSERegType from, int offset ) { iMOV##mod( ptr[iAddressReg(to)+offset], iRegisterSSE(from) ); } \
|
||||||
ModRM( 0, to, 0x4 );
|
emitterT void sse##_MOV##mod##RmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) \
|
||||||
SibSB( scale, from2, from );
|
{ iMOV##mod( iRegisterSSE(to), ptr[iAddressReg(from)+iAddressReg(from2)] ); } \
|
||||||
}
|
emitterT void sse##_MOV##mod##RtoRmS( x86IntRegType to, x86SSERegType from, x86IntRegType from2, int scale ) \
|
||||||
|
{ iMOV##mod( ptr[iAddressReg(to)+iAddressReg(from2)], iRegisterSSE(from) ); }
|
||||||
|
|
||||||
/* movups xmm1 to [r32][r32*scale] */
|
DEFINE_LEGACY_MOV_OPCODE( UPS, SSE )
|
||||||
emitterT void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
DEFINE_LEGACY_MOV_OPCODE( APS, SSE )
|
||||||
{
|
DEFINE_LEGACY_MOV_OPCODE( LPS, SSE )
|
||||||
RexRXB(1, to, from2, from);
|
DEFINE_LEGACY_MOV_OPCODE( HPS, SSE )
|
||||||
write16( 0x110f );
|
DEFINE_LEGACY_MOV_OPCODE( DQA, SSE2 )
|
||||||
ModRM( 0, to, 0x4 );
|
DEFINE_LEGACY_MOV_OPCODE( DQU, SSE2 )
|
||||||
SibSB( scale, from2, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* movups [r32] to r32 */
|
|
||||||
emitterT void SSE_MOVUPSRmtoR( x86IntRegType to, x86IntRegType from )
|
|
||||||
{
|
|
||||||
RexRB(0, to, from);
|
|
||||||
write16( 0x100f );
|
|
||||||
ModRM( 0, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* movups r32 to [r32] */
|
|
||||||
emitterT void SSE_MOVUPSRtoRm( x86IntRegType to, x86IntRegType from )
|
|
||||||
{
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16( 0x110f );
|
|
||||||
ModRM( 0, from, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* movlps [r32] to r32 */
|
|
||||||
emitterT void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from )
|
|
||||||
{
|
|
||||||
RexRB(1, to, from);
|
|
||||||
write16( 0x120f );
|
|
||||||
ModRM( 0, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
|
||||||
RexRB(0, to, from);
|
|
||||||
write16( 0x120f );
|
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* movaps r32 to [r32] */
|
|
||||||
emitterT void SSE_MOVLPSRtoRm( x86IntRegType to, x86IntRegType from )
|
|
||||||
{
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16( 0x130f );
|
|
||||||
ModRM( 0, from, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16( 0x130f );
|
|
||||||
WriteRmOffsetFrom(from, to, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* movaps [r32][r32*scale] to xmm1 */
|
|
||||||
emitterT void SSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
|
||||||
{
|
|
||||||
assert( from != EBP );
|
|
||||||
RexRXB(0, to, from2, from);
|
|
||||||
write16( 0x280f );
|
|
||||||
ModRM( 0, to, 0x4 );
|
|
||||||
SibSB( scale, from2, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* movaps xmm1 to [r32][r32*scale] */
|
|
||||||
emitterT void SSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
|
||||||
{
|
|
||||||
assert( from != EBP );
|
|
||||||
RexRXB(0, to, from2, from);
|
|
||||||
write16( 0x290f );
|
|
||||||
ModRM( 0, to, 0x4 );
|
|
||||||
SibSB( scale, from2, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
// movaps [r32+offset] to r32
|
|
||||||
emitterT void SSE_MOVAPSRmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
|
||||||
RexRB(0, to, from);
|
|
||||||
write16( 0x280f );
|
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// movaps r32 to [r32+offset]
|
|
||||||
emitterT void SSE_MOVAPSRtoRm( x86IntRegType to, x86SSERegType from, int offset )
|
|
||||||
{
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16( 0x290f );
|
|
||||||
WriteRmOffsetFrom(from, to, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// movdqa [r32+offset] to r32
|
|
||||||
emitterT void SSE2_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
|
||||||
if( AlwaysUseMovaps )
|
|
||||||
SSE_MOVAPSRmtoR( to, from, offset );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write8(0x66);
|
|
||||||
RexRB(0, to, from);
|
|
||||||
write16( 0x6f0f );
|
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// movdqa r32 to [r32+offset]
|
|
||||||
emitterT void SSE2_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset )
|
|
||||||
{
|
|
||||||
if( AlwaysUseMovaps )
|
|
||||||
SSE_MOVAPSRtoRm( to, from, offset );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write8(0x66);
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16( 0x7f0f );
|
|
||||||
WriteRmOffsetFrom(from, to, offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// movups [r32+offset] to r32
|
|
||||||
emitterT void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
|
||||||
RexRB(0, to, from);
|
|
||||||
write16( 0x100f );
|
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// movups r32 to [r32+offset]
|
|
||||||
emitterT void SSE_MOVUPSRtoRm( x86IntRegType to, x86SSERegType from, int offset )
|
|
||||||
{
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16( 0x110f );
|
|
||||||
WriteRmOffsetFrom(from, to, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
//**********************************************************************************/
|
//**********************************************************************************/
|
||||||
//MOVAPS: Move aligned Packed Single Precision FP values *
|
//MOVAPS: Move aligned Packed Single Precision FP values *
|
||||||
//**********************************************************************************
|
//**********************************************************************************
|
||||||
//emitterT void SSE_MOVAPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x280f, 0 ); }
|
|
||||||
//emitterT void SSE_MOVAPS_XMM_to_M128( uptr to, x86SSERegType from ) { SSERtoM( 0x290f, 0 ); }
|
|
||||||
//emitterT void SSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { if (to != from) { SSERtoR( 0x280f ); } }
|
|
||||||
//emitterT void SSE_MOVUPS_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x100f, 0 ); }
|
|
||||||
//emitterT void SSE_MOVUPS_XMM_to_M128( uptr to, x86SSERegType from ) { SSERtoM( 0x110f, 0 ); }
|
|
||||||
|
|
||||||
emitterT void SSE_MOVAPS_M128_to_XMM( x86SSERegType to, uptr from ) { iMOVAPS( iRegisterSSE(to), (void*)from ); }
|
|
||||||
emitterT void SSE_MOVAPS_XMM_to_M128( uptr to, x86SSERegType from ) { iMOVAPS( (void*)to, iRegisterSSE(from) ); }
|
|
||||||
emitterT void SSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { iMOVAPS( iRegisterSSE(to), iRegisterSSE(from) ); }
|
emitterT void SSE_MOVAPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { iMOVAPS( iRegisterSSE(to), iRegisterSSE(from) ); }
|
||||||
emitterT void SSE_MOVUPS_M128_to_XMM( x86SSERegType to, uptr from ) { iMOVUPS( iRegisterSSE(to), (void*)from ); }
|
|
||||||
emitterT void SSE_MOVUPS_XMM_to_M128( uptr to, x86SSERegType from ) { iMOVUPS( (void*)to, iRegisterSSE(from) ); }
|
|
||||||
|
|
||||||
emitterT void SSE2_MOVQ_M64_to_XMM( x86SSERegType to, uptr from ) { iMOVQZX( iRegisterSSE(to), (void*)from ); }
|
emitterT void SSE2_MOVQ_M64_to_XMM( x86SSERegType to, uptr from ) { iMOVQZX( iRegisterSSE(to), (void*)from ); }
|
||||||
emitterT void SSE2_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { iMOVQZX( iRegisterSSE(to), iRegisterSSE(from) ); }
|
emitterT void SSE2_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { iMOVQZX( iRegisterSSE(to), iRegisterSSE(from) ); }
|
||||||
|
@ -328,78 +181,41 @@ emitterT void SSE2_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) {
|
||||||
emitterT void SSE2_MOVSD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { iMOVSDZX( iRegisterSSE(to), ptr[iAddressReg(from)+offset] ); }
|
emitterT void SSE2_MOVSD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { iMOVSDZX( iRegisterSSE(to), ptr[iAddressReg(from)+offset] ); }
|
||||||
emitterT void SSE2_MOVSD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { iMOVSD( ptr[iAddressReg(to)+offset], iRegisterSSE(from) ); }
|
emitterT void SSE2_MOVSD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { iMOVSD( ptr[iAddressReg(to)+offset], iRegisterSSE(from) ); }
|
||||||
|
|
||||||
/*emitterT void SSE_MOVSS_M32_to_XMM( x86SSERegType to, uptr from ) { SSE_SS_MtoR( 0x100f, 0 ); }
|
emitterT void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { iMASKMOV( iRegisterSSE(to), iRegisterSSE(from) ); }
|
||||||
emitterT void SSE_MOVSS_XMM_to_M32( u32 to, x86SSERegType from ) { SSE_SS_RtoM( 0x110f, 0 ); }
|
|
||||||
emitterT void SSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { if (to != from) { SSE_SS_RtoR( 0x100f ); } }
|
|
||||||
emitterT void SSE_MOVSS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
|
||||||
write8(0xf3);
|
|
||||||
RexRB(0, to, from);
|
|
||||||
write16( 0x100f );
|
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void SSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset )
|
|
||||||
{
|
|
||||||
write8(0xf3);
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16(0x110f);
|
|
||||||
WriteRmOffsetFrom(from, to, offset);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
emitterT void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR66( 0xf70f ); }
|
|
||||||
//**********************************************************************************/
|
//**********************************************************************************/
|
||||||
//MOVLPS: Move low Packed Single-Precision FP *
|
//MOVLPS: Move low Packed Single-Precision FP *
|
||||||
//**********************************************************************************
|
//**********************************************************************************
|
||||||
emitterT void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x120f, 0 ); }
|
emitterT void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { iMOVLPS( iRegisterSSE(to), (void*)from ); }
|
||||||
emitterT void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x130f, 0 ); }
|
emitterT void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { iMOVLPS( (void*)to, iRegisterSSE(from) ); }
|
||||||
|
emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { iMOVLPS( iRegisterSSE(to), ptr[iAddressReg(from)+offset] ); }
|
||||||
emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
|
emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { iMOVLPS( ptr[iAddressReg(to)+offset], iRegisterSSE(from) ); }
|
||||||
{
|
|
||||||
RexRB(0, to, from);
|
|
||||||
write16( 0x120f );
|
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset )
|
|
||||||
{
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16(0x130f);
|
|
||||||
WriteRmOffsetFrom(from, to, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
//**********************************************************************************/
|
//**********************************************************************************/
|
||||||
//MOVHPS: Move High Packed Single-Precision FP *
|
//MOVHPS: Move High Packed Single-Precision FP *
|
||||||
//**********************************************************************************
|
//**********************************************************************************
|
||||||
emitterT void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x160f, 0 ); }
|
emitterT void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { iMOVHPS( iRegisterSSE(to), (void*)from ); }
|
||||||
emitterT void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x170f, 0 ); }
|
emitterT void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { iMOVHPS( (void*)to, iRegisterSSE(from) ); }
|
||||||
|
emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) { iMOVHPS( iRegisterSSE(to), ptr[iAddressReg(from)+offset] ); }
|
||||||
emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
|
emitterT void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { iMOVHPS( ptr[iAddressReg(to)+offset], iRegisterSSE(from) ); }
|
||||||
{
|
|
||||||
RexRB(0, to, from);
|
|
||||||
write16( 0x160f );
|
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset )
|
|
||||||
{
|
|
||||||
RexRB(0, from, to);
|
|
||||||
write16(0x170f);
|
|
||||||
WriteRmOffsetFrom(from, to, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
//**********************************************************************************/
|
//**********************************************************************************/
|
||||||
//MOVLHPS: Moved packed Single-Precision FP low to high *
|
//MOVLHPS: Moved packed Single-Precision FP low to high *
|
||||||
//**********************************************************************************
|
//**********************************************************************************
|
||||||
emitterT void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x160f ); }
|
emitterT void SSE_MOVLHPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { iMOVLHPS( iRegisterSSE(to), iRegisterSSE(from) ); }
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
//**********************************************************************************/
|
//**********************************************************************************/
|
||||||
//MOVHLPS: Moved packed Single-Precision FP High to Low *
|
//MOVHLPS: Moved packed Single-Precision FP High to Low *
|
||||||
//**********************************************************************************
|
//**********************************************************************************
|
||||||
emitterT void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSERtoR( 0x120f ); }
|
emitterT void SSE_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { iMOVHLPS( iRegisterSSE(to), iRegisterSSE(from) ); }
|
||||||
|
|
||||||
|
|
||||||
|
emitterT void SSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from) { iPMOVMSKB( iRegister32(to), iRegisterSSE(from) ); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
//**********************************************************************************/
|
//**********************************************************************************/
|
||||||
|
@ -938,30 +754,8 @@ emitterT void SSE2_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SS
|
||||||
emitterT void SSE2_PXOR_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEF0F ); }
|
emitterT void SSE2_PXOR_M128_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR66( 0xEF0F ); }
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
emitterT void SSE2_MOVDQA_M128_to_XMM(x86SSERegType to, uptr from) { if( AlwaysUseMovaps ) SSE_MOVAPS_M128_to_XMM( to, from ); else SSEMtoR66(0x6F0F); }
|
|
||||||
emitterT void SSE2_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from ) { if( AlwaysUseMovaps ) SSE_MOVAPS_XMM_to_M128( to, from ); else SSERtoM66(0x7F0F); }
|
|
||||||
emitterT void SSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { if( AlwaysUseMovaps ) SSE_MOVAPS_XMM_to_XMM( to, from ); else if( to != from ) SSERtoR66(0x6F0F); }
|
emitterT void SSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { if( AlwaysUseMovaps ) SSE_MOVAPS_XMM_to_XMM( to, from ); else if( to != from ) SSERtoR66(0x6F0F); }
|
||||||
|
|
||||||
emitterT void SSE2_MOVDQU_M128_to_XMM(x86SSERegType to, uptr from)
|
|
||||||
{
|
|
||||||
if( AlwaysUseMovaps )
|
|
||||||
SSE_MOVUPS_M128_to_XMM( to, from );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write8(0xF3);
|
|
||||||
SSEMtoR(0x6F0F, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emitterT void SSE2_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from)
|
|
||||||
{
|
|
||||||
if( AlwaysUseMovaps )
|
|
||||||
SSE_MOVUPS_XMM_to_M128( to, from );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write8(0xF3);
|
|
||||||
SSERtoM(0x7F0F, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// shift right logical
|
// shift right logical
|
||||||
|
|
||||||
|
@ -1153,8 +947,6 @@ emitterT void SSE2_PMULHW_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR6
|
||||||
emitterT void SSE2_PMULUDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0xF40F ); }
|
emitterT void SSE2_PMULUDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSERtoR66( 0xF40F ); }
|
||||||
emitterT void SSE2_PMULUDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0xF40F ); }
|
emitterT void SSE2_PMULUDQ_M128_to_XMM(x86SSERegType to, uptr from) { SSEMtoR66( 0xF40F ); }
|
||||||
|
|
||||||
emitterT void SSE2_PMOVMSKB_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0xD70F); }
|
|
||||||
|
|
||||||
emitterT void SSE_MOVMSKPS_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR(0x500F); }
|
emitterT void SSE_MOVMSKPS_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR(0x500F); }
|
||||||
emitterT void SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0x500F); }
|
emitterT void SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0x500F); }
|
||||||
|
|
||||||
|
|
|
@ -675,16 +675,39 @@ namespace x86Emitter
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ALWAYS_USE_MOVAPS [define] / AlwaysUseMovaps [const]
|
||||||
//
|
//
|
||||||
|
// This tells the recompiler's emitter to always use movaps instead of movdqa. Both instructions
|
||||||
|
// do the exact same thing, but movaps is 1 byte shorter, and thus results in a cleaner L1 cache
|
||||||
|
// and some marginal speed gains as a result. (it's possible someday in the future the per-
|
||||||
|
// formance of the two instructions could change, so this constant is provided to restore MOVDQA
|
||||||
|
// use easily at a later time, if needed).
|
||||||
|
#define ALWAYS_USE_MOVAPS
|
||||||
|
|
||||||
extern const Internal::MovapsImplAll< 0, 0x28, 0x29 > iMOVAPS;
|
#ifdef ALWAYS_USE_MOVAPS
|
||||||
|
static const bool AlwaysUseMovaps = true;
|
||||||
|
#else
|
||||||
|
static const bool AlwaysUseMovaps = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const Internal::MovapsImplAll< 0, 0x28, 0x29 > iMOVAPS;
|
||||||
extern const Internal::MovapsImplAll< 0, 0x10, 0x11 > iMOVUPS;
|
extern const Internal::MovapsImplAll< 0, 0x10, 0x11 > iMOVUPS;
|
||||||
|
|
||||||
extern const Internal::MovapsImplAll< 0x66, 0x28, 0x29 > iMOVAPD;
|
extern const Internal::MovapsImplAll< 0x66, 0x28, 0x29 > iMOVAPD;
|
||||||
extern const Internal::MovapsImplAll< 0x66, 0x10, 0x11 > iMOVUPD;
|
extern const Internal::MovapsImplAll< 0x66, 0x10, 0x11 > iMOVUPD;
|
||||||
|
|
||||||
|
#ifdef ALWAYS_USE_MOVAPS
|
||||||
extern const Internal::MovapsImplAll< 0x66, 0x6f, 0x7f > iMOVDQA;
|
extern const Internal::MovapsImplAll< 0x66, 0x6f, 0x7f > iMOVDQA;
|
||||||
extern const Internal::MovapsImplAll< 0xf3, 0x6f, 0x7f > iMOVDQU;
|
extern const Internal::MovapsImplAll< 0xf3, 0x6f, 0x7f > iMOVDQU;
|
||||||
|
#else
|
||||||
|
extern const Internal::MovapsImplAll< 0, 0x28, 0x29 > iMOVDQA;
|
||||||
|
extern const Internal::MovapsImplAll< 0, 0x10, 0x11 > iMOVDQU;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const Internal::MovhlImplAll< 0, 0x16 > iMOVHPS;
|
||||||
|
extern const Internal::MovhlImplAll< 0, 0x12 > iMOVLPS;
|
||||||
|
extern const Internal::MovhlImplAll< 0x66, 0x16 > iMOVHPD;
|
||||||
|
extern const Internal::MovhlImplAll< 0x66, 0x12 > iMOVLPD;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue