From c19de231f6ed98121745d38aa79e09592ff68e60 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Sun, 19 Apr 2009 05:24:20 +0000 Subject: [PATCH] Emitter: Implemented MOVAPS/MOVDQA, and renamed some vars/classes. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1015 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/x86/iVUmicroLower.cpp | 2 +- pcsx2/x86/ix86-32/recVTLB.cpp | 4 +- pcsx2/x86/ix86/implement/xmm/movqss.h | 117 ++++++++------- pcsx2/x86/ix86/ix86.cpp | 202 ++++++++++++++++---------- pcsx2/x86/ix86/ix86_inlines.inl | 88 +---------- pcsx2/x86/ix86/ix86_instructions.h | 75 ++++++++-- pcsx2/x86/ix86/ix86_legacy.cpp | 30 ++-- pcsx2/x86/ix86/ix86_legacy_mmx.cpp | 8 +- pcsx2/x86/ix86/ix86_legacy_sse.cpp | 44 +++--- pcsx2/x86/ix86/ix86_types.h | 66 +++++---- 10 files changed, 344 insertions(+), 292 deletions(-) diff --git a/pcsx2/x86/iVUmicroLower.cpp b/pcsx2/x86/iVUmicroLower.cpp index a54cefe86a..0a7a73117a 100644 --- a/pcsx2/x86/iVUmicroLower.cpp +++ b/pcsx2/x86/iVUmicroLower.cpp @@ -802,7 +802,7 @@ void _saveEAX(VURegs *VU, int x86reg, uptr offset, int info) // (this is one of my test cases for the new emitter --air) using namespace x86Emitter; - x86IndexReg thisreg( x86reg ); + iAddressReg thisreg( x86reg ); if ( _X ) iMOV(ptr32[thisreg+offset], 0x00000000); if ( _Y ) iMOV(ptr32[thisreg+offset+4], 0x00000000); diff --git a/pcsx2/x86/ix86-32/recVTLB.cpp b/pcsx2/x86/ix86-32/recVTLB.cpp index 99ac820221..a518b04388 100644 --- a/pcsx2/x86/ix86-32/recVTLB.cpp +++ b/pcsx2/x86/ix86-32/recVTLB.cpp @@ -34,8 +34,8 @@ void MOV128_MtoM( x86IntRegType destRm, x86IntRegType srcRm ) { // (this is one of my test cases for the new emitter --air) - x86IndexReg src( srcRm ); - x86IndexReg dest( destRm ); + iAddressReg src( srcRm ); + iAddressReg dest( destRm ); iMOV( eax, ptr[src] ); iMOV( ptr[dest], eax ); diff --git a/pcsx2/x86/ix86/implement/xmm/movqss.h b/pcsx2/x86/ix86/implement/xmm/movqss.h index 22855aa80f..7fe6d23a29 100644 --- a/pcsx2/x86/ix86/implement/xmm/movqss.h +++ b/pcsx2/x86/ix86/implement/xmm/movqss.h @@ -18,22 +18,13 @@ #pragma once -// This helper function is used for instructions which enter XMM form when the 0x66 prefix -// is specified (indicating alternate operand type selection). -template< typename OperandType > -static __forceinline void preXMM( u8 opcode ) -{ - if( sizeof( OperandType ) == 16 ) - iWrite( 0x0f66 ); - else - iWrite( 0x0f ); - iWrite( opcode ); -} +////////////////////////////////////////////////////////////////////////////////////////// +// MMX / SSE Helper Functions! -// prefix - 0 indicates MMX, anything assumes XMM. -static __forceinline void SimdPrefix( u8 opcode, u8 prefix=0 ) +template< typename T > +__emitinline void SimdPrefix( u8 opcode, u8 prefix ) { - if( prefix != 0 ) + if( sizeof( T ) == 16 && prefix != 0 ) { iWrite( 0x0f00 | prefix ); iWrite( opcode ); @@ -43,67 +34,81 @@ static __forceinline void SimdPrefix( u8 opcode, u8 prefix=0 ) } template< u8 prefix, typename T, typename T2 > -static __forceinline void writeXMMop( const iRegister& to, const iRegister& from, u8 opcode ) +__emitinline void writeXMMop( u8 opcode, const iRegister& to, const iRegister& from ) { - SimdPrefix( opcode, prefix ); + SimdPrefix( opcode, prefix ); ModRM_Direct( to.Id, from.Id ); } template< u8 prefix, typename T > -static __noinline void writeXMMop( const iRegister& reg, const ModSibBase& sib, u8 opcode ) +void writeXMMop( u8 opcode, const iRegister& reg, const ModSibBase& sib ) { - SimdPrefix( opcode, prefix ); + SimdPrefix( opcode, prefix ); EmitSibMagic( reg.Id, sib ); } template< u8 prefix, typename T > -static __forceinline void writeXMMop( const iRegister& reg, const void* data, u8 opcode ) +__emitinline void writeXMMop( u8 opcode, const iRegister& reg, const void* data ) { - SimdPrefix( opcode, prefix ); + SimdPrefix( opcode, prefix ); iWriteDisp( reg.Id, data ); } -// ------------------------------------------------------------------------ -// MOVD has valid forms for MMX and XMM registers. +////////////////////////////////////////////////////////////////////////////////////////// // -template< typename T > -static __forceinline void iMOVDZX( const iRegisterSIMD& to, const iRegister32& from ) +template< u8 Prefix, typename OperandType > +class MovapsImpl { - preXMM( 0x6e ); - ModRM_Direct( to.Id, from.Id ); -} +public: + // ------------------------------------------------------------------------ + static __emitinline void Emit( u8 opcode, const iRegisterSIMD& to, const iRegisterSIMD from ) + { + if( to != from ) + writeXMMop( opcode, to, from ); + } -template< typename T> -static __forceinline void iMOVDZX( const iRegisterSIMD& to, const void* src ) -{ - preXMM( 0x6e ); - iWriteDisp( to.Id, src ); -} + // ------------------------------------------------------------------------ + static __emitinline void Emit( u8 opcode, const iRegisterSIMD& to, const void* from ) + { + writeXMMop( opcode, to, from ); + } -template< typename T> -static __forceinline void iMOVDZX( const iRegisterSIMD& to, const ModSibBase& src ) -{ - preXMM( 0x6e ); - EmitSibMagic( to.Id, src ); -} + // ------------------------------------------------------------------------ + static __emitinline void Emit( u8 opcode, const iRegisterSIMD& to, const ModSibBase& from ) + { + writeXMMop( opcode, to, from ); + } -template< typename T> -static __emitinline void iMOVD( const iRegister32& to, const iRegisterSIMD& from ) -{ - preXMM( 0x7e ); - ModRM_Direct( from.Id, to.Id ); -} + // ------------------------------------------------------------------------ + // 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& from ) + { + writeXMMop( opcode, from, to ); + } -template< typename T> -static __forceinline void iMOVD( void* dest, const iRegisterSIMD& from ) -{ - preXMM( 0x7e ); - iWriteDisp( from.Id, dest ); -} + // ------------------------------------------------------------------------ + // 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& from ) + { + writeXMMop( opcode, from, to ); + } -template< typename T> -static __noinline void iMOVD( const ModSibBase& dest, const iRegisterSIMD& from ) +}; + +// ------------------------------------------------------------------------ +template< u8 Prefix, u8 Opcode, u8 OpcodeAlt > +class MovapsImplAll { - preXMM( 0x7e ); - EmitSibMagic( from.Id, dest ); -} +protected: + typedef MovapsImpl m_128; + +public: + __forceinline void operator()( const iRegisterSSE& to, const iRegisterSSE& from ) const { m_128::Emit( Opcode, to, from ); } + __forceinline void operator()( const iRegisterSSE& to, const void* from ) const { m_128::Emit( Opcode, to, from ); } + __forceinline void operator()( const void* to, const iRegisterSSE& from ) const { m_128::Emit( OpcodeAlt, to, from ); } + __noinline void operator()( const iRegisterSSE& to, const ModSibBase& from ) const { m_128::Emit( Opcode, to, from ); } + __noinline void operator()( const ModSibBase& to, const iRegisterSSE& from ) const { m_128::Emit( OpcodeAlt, to, from ); } +}; + diff --git a/pcsx2/x86/ix86/ix86.cpp b/pcsx2/x86/ix86/ix86.cpp index 31f414d50c..aa85482572 100644 --- a/pcsx2/x86/ix86/ix86.cpp +++ b/pcsx2/x86/ix86/ix86.cpp @@ -67,6 +67,8 @@ __threadlocal XMMSSEType g_xmmtypes[iREGCNT_XMM] = { XMMT_INT }; namespace x86Emitter { const iAddressIndexerBase ptr; +const iAddressIndexer ptr128; +const iAddressIndexer ptr64; const iAddressIndexer ptr32; const iAddressIndexer ptr16; const iAddressIndexer ptr8; @@ -74,7 +76,19 @@ const iAddressIndexer ptr8; // ------------------------------------------------------------------------ template< typename OperandType > const iRegister iRegister::Empty; -const x86IndexReg x86IndexReg::Empty; +const iAddressReg iAddressReg::Empty; + +const iRegisterSSE + xmm0( 0 ), xmm1( 1 ), + xmm2( 2 ), xmm3( 3 ), + xmm4( 4 ), xmm5( 5 ), + xmm6( 6 ), xmm7( 7 ); + +const iRegisterMMX + mm0( 0 ), mm1( 1 ), + mm2( 2 ), mm3( 3 ), + mm4( 4 ), mm5( 5 ), + mm6( 6 ), mm7( 7 ); const iRegister32 eax( 0 ), ebx( 3 ), @@ -378,6 +392,86 @@ __emitinline void iAdvancePtr( uint bytes ) x86Ptr += bytes; } +// ------------------------------------------------------------------------ +// Generates a 'reduced' ModSib form, which has valid Base, Index, and Scale values. +// Necessary because by default ModSib compounds registers into Index when possible. +// +// If the ModSib is in illegal form ([Base + Index*5] for example) then an assertion +// followed by an InvalidParameter Exception will be tossed around in haphazard +// fashion. +// +// Optimization Note: Currently VC does a piss poor job of inlining this, even though +// constant propagation *should* resove it to little or no code (VC's constprop fails +// on C++ class initializers). There is a work around [using array initializers instead] +// but it's too much trouble for code that isn't performance critical anyway. +// And, with luck, maybe VC10 will optimize it better and make it a non-issue. :D +// +void ModSibBase::Reduce() +{ + if( Index.IsStackPointer() ) + { + // esp cannot be encoded as the index, so move it to the Base, if possible. + // note: intentionally leave index assigned to esp also (generates correct + // encoding later, since ESP cannot be encoded 'alone') + + jASSUME( Scale == 0 ); // esp can't have an index modifier! + jASSUME( Base.IsEmpty() ); // base must be empty or else! + + Base = Index; + return; + } + + // If no index reg, then load the base register into the index slot. + if( Index.IsEmpty() ) + { + Index = Base; + Scale = 0; + if( !Base.IsStackPointer() ) // prevent ESP from being encoded 'alone' + Base = iAddressReg::Empty; + return; + } + + + // The Scale has a series of valid forms, all shown here: + + switch( Scale ) + { + case 0: break; + case 1: Scale = 0; break; + case 2: Scale = 1; break; + + case 3: // becomes [reg*2+reg] + jASSUME( Base.IsEmpty() ); + Base = Index; + Scale = 1; + break; + + case 4: Scale = 2; break; + + case 5: // becomes [reg*4+reg] + jASSUME( Base.IsEmpty() ); + Base = Index; + Scale = 2; + break; + + case 6: // invalid! + assert( false ); + break; + + case 7: // so invalid! + assert( false ); + break; + + case 8: Scale = 3; break; + case 9: // becomes [reg*8+reg] + jASSUME( Base.IsEmpty() ); + Base = Index; + Scale = 3; + break; + } +} + + // ------------------------------------------------------------------------ // Internal implementation of EmitSibMagic which has been custom tailored // to optimize special forms of the Lea instructions accordingly, such @@ -641,99 +735,57 @@ __emitinline void iBSWAP( const iRegister32& to ) // MMX / XMM Instructions // (these will get put in their own file later) -__emitinline void iMOVQ( const iRegisterMMX& to, const iRegisterMMX& from ) -{ - writeXMMop<0>( to, from, 0x6f ); -} +const MovapsImplAll< 0, 0x28, 0x29 > iMOVAPS; +const MovapsImplAll< 0, 0x10, 0x11 > iMOVUPS; +const MovapsImplAll< 0x66, 0x28, 0x29 > iMOVAPD; +const MovapsImplAll< 0x66, 0x10, 0x11 > iMOVUPD; -__noinline void iMOVQ( const iRegisterMMX& to, const ModSibBase& src ) -{ - writeXMMop<0>( to, src, 0x6f ); -} - -__emitinline void iMOVQ( const iRegisterMMX& to, const void* src ) -{ - writeXMMop<0>( to, src, 0x6f ); -} +const MovapsImplAll< 0x66, 0x6f, 0x7f > iMOVDQA; +const MovapsImplAll< 0xf3, 0x6f, 0x7f > iMOVDQU; // Moves from XMM to XMM, with the *upper 64 bits* of the destination register // being cleared to zero. -__emitinline void iMOVQZX( const iRegisterXMM& to, const iRegisterXMM& from ) -{ - writeXMMop<0xf3>( to, from, 0x7e ); -} +__emitinline 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 // being cleared to zero. -__noinline void iMOVQZX( const iRegisterXMM& to, const ModSibBase& src ) -{ - writeXMMop<0xf3>( to, src, 0x7e ); -} +__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 // being cleared to zero. -__emitinline void iMOVQZX( const iRegisterXMM& to, const void* src ) -{ - writeXMMop<0xf3>( to, src, 0x7e ); -} +__emitinline void iMOVQZX( const iRegisterSSE& to, const void* src ) { writeXMMop<0xf3>( 0x7e, to, src ); } -__forceinline void iMOVQ( const ModSibBase& dest, const iRegisterMMX& from ) +__emitinline void iMOVQ( const iRegisterMMX& to, const iRegisterMMX& from ) { if( to != from ) writeXMMop<0>( 0x6f, to, from ); } +__noinline void iMOVQ( const iRegisterMMX& to, const ModSibBase& src ) { writeXMMop<0>( 0x6f, to, src ); } +__emitinline void iMOVQ( const iRegisterMMX& to, const void* src ) { writeXMMop<0>( 0x6f, to, src ); } +__forceinline void iMOVQ( const ModSibBase& dest, const iRegisterMMX& from ) { writeXMMop<0>( 0x7f, from, dest ); } +__forceinline void iMOVQ( void* dest, const iRegisterMMX& from ) { writeXMMop<0>( 0x7f, 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( const iRegisterSSE& to, const iRegisterMMX& from ) { writeXMMop<0xf3>( 0xd6, to, from ); } +__forceinline void iMOVQ( const iRegisterMMX& to, const iRegisterSSE& from ) { - writeXMMop<0>( from, dest, 0x7f ); -} + // Manual implementation of this form of MOVQ, since its parameters are unique in a way + // that breaks the template inference of writeXMMop(); -__forceinline void iMOVQ( void* dest, const iRegisterMMX& from ) -{ - writeXMMop<0>( from, dest, 0x7f ); -} - -__forceinline void iMOVQ( const ModSibBase& dest, const iRegisterXMM& from ) -{ - writeXMMop<0xf3>( from, dest, 0x7e ); -} - -__forceinline void iMOVQ( void* dest, const iRegisterXMM& from ) -{ - writeXMMop<0xf3>( from, dest, 0x7e ); -} - -__forceinline void iMOVQ( const iRegisterXMM& to, const iRegisterMMX& from ) -{ - writeXMMop<0xf3>( to, from, 0xd6 ); -} - -__forceinline void iMOVQ( const iRegisterMMX& to, const iRegisterXMM& from ) -{ - writeXMMop<0xf2>( to, from, 0xd6 ); + SimdPrefix( 0xd6, 0xf2 ); + ModRM_Direct( to.Id, from.Id ); } ////////////////////////////////////////////////////////////////////////////////////////// // -__forceinline void iMOVSS( const iRegisterXMM& to, const iRegisterXMM& from ) -{ - if( to != from ) - writeXMMop<0xf3>( to, from, 0x10 ); -} +#define IMPLEMENT_iMOVS( ssd, prefix ) \ + __forceinline void iMOV##ssd( const iRegisterSSE& to, const iRegisterSSE& from ) { if( to != from ) writeXMMop( 0x10, to, from ); } \ + __forceinline void iMOV##ssd##ZX( const iRegisterSSE& to, const void* from ) { writeXMMop( 0x10, to, from ); } \ + __forceinline void iMOV##ssd##ZX( const iRegisterSSE& to, const ModSibBase& from ) { writeXMMop( 0x10, to, from ); } \ + __forceinline void iMOV##ssd( const void* to, const iRegisterSSE& from ) { writeXMMop( 0x11, from, to ); } \ + __forceinline void iMOV##ssd( const ModSibBase& to, const iRegisterSSE& from ) { writeXMMop( 0x11, from, to ); } -__forceinline void iMOVSSZX( const iRegisterXMM& to, const void* from ) -{ - writeXMMop<0xf3>( to, from, 0x10 ); -} +IMPLEMENT_iMOVS( SS, 0xf3 ) +IMPLEMENT_iMOVS( SD, 0xf2 ) -__forceinline void iMOVSSZX( const iRegisterXMM& to, const ModSibBase& from ) -{ - writeXMMop<0xf3>( to, from, 0x10 ); -} - -__forceinline void iMOVSS( const void* to, const iRegisterXMM& from ) -{ - writeXMMop<0xf3>( from, to, 0x11 ); -} - -__forceinline void iMOVSS( const ModSibBase& to, const iRegisterXMM& from ) -{ - writeXMMop<0xf3>( from, to, 0x11 ); -} +////////////////////////////////////////////////////////////////////////////////////////// +// } diff --git a/pcsx2/x86/ix86/ix86_inlines.inl b/pcsx2/x86/ix86/ix86_inlines.inl index ebe2341c21..c9af4a8e04 100644 --- a/pcsx2/x86/ix86/ix86_inlines.inl +++ b/pcsx2/x86/ix86/ix86_inlines.inl @@ -53,27 +53,27 @@ namespace x86Emitter ////////////////////////////////////////////////////////////////////////////////////////// // x86Register Method Implementations // - __forceinline iAddressInfo x86IndexReg::operator+( const x86IndexReg& right ) const + __forceinline iAddressInfo iAddressReg::operator+( const iAddressReg& right ) const { return iAddressInfo( *this, right ); } - __forceinline iAddressInfo x86IndexReg::operator+( const iAddressInfo& right ) const + __forceinline iAddressInfo iAddressReg::operator+( const iAddressInfo& right ) const { return right + *this; } - __forceinline iAddressInfo x86IndexReg::operator+( s32 right ) const + __forceinline iAddressInfo iAddressReg::operator+( s32 right ) const { return iAddressInfo( *this, right ); } - __forceinline iAddressInfo x86IndexReg::operator*( u32 right ) const + __forceinline iAddressInfo iAddressReg::operator*( u32 right ) const { return iAddressInfo( Empty, *this, right ); } - __forceinline iAddressInfo x86IndexReg::operator<<( u32 shift ) const + __forceinline iAddressInfo iAddressReg::operator<<( u32 shift ) const { return iAddressInfo( Empty, *this, 1< + __emitinline void iMOVDZX( const iRegisterSIMD& to, const iRegister32& from ) + { + Internal::writeXMMop<0x66>( 0x6e, to, from ); + } + template< typename T > + __emitinline void iMOVDZX( const iRegisterSIMD& to, const void* src ) + { + Internal::writeXMMop<0x66>( 0x6e, to, src ); + } + + template< typename T > + void iMOVDZX( const iRegisterSIMD& to, const ModSibBase& src ) + { + Internal::writeXMMop<0x66>( 0x6e, to, src ); + } + + template< typename T > + __emitinline void iMOVD( const iRegister32& to, const iRegisterSIMD& from ) + { + Internal::writeXMMop<0x66>( 0x7e, from, to ); + } + + template< typename T > + __emitinline void iMOVD( void* dest, const iRegisterSIMD& from ) + { + Internal::writeXMMop<0x66>( 0x7e, from, dest ); + } + + template< typename T > + void iMOVD( const ModSibBase& dest, const iRegisterSIMD& from ) + { + Internal::writeXMMop<0x66>( 0x7e, from, dest ); + } + + // ------------------------------------------------------------------------ + + + + // ------------------------------------------------------------------------ + extern void iMOVQ( const iRegisterMMX& to, const iRegisterMMX& from ); - extern void iMOVQ( const iRegisterMMX& to, const iRegisterXMM& from ); - extern void iMOVQ( const iRegisterXMM& to, const iRegisterMMX& from ); + extern void iMOVQ( const iRegisterMMX& to, const iRegisterSSE& from ); + extern void iMOVQ( const iRegisterSSE& to, const iRegisterMMX& from ); - extern void iMOVQ( void* dest, const iRegisterXMM& from ); - extern void iMOVQ( const ModSibBase& dest, const iRegisterXMM& from ); + extern void iMOVQ( void* dest, const iRegisterSSE& from ); + extern void iMOVQ( const ModSibBase& dest, const iRegisterSSE& from ); extern void iMOVQ( void* dest, const iRegisterMMX& from ); extern void iMOVQ( const ModSibBase& dest, const iRegisterMMX& from ); extern void iMOVQ( const iRegisterMMX& to, const void* src ); extern void iMOVQ( const iRegisterMMX& to, const ModSibBase& src ); - extern void iMOVQZX( const iRegisterXMM& to, const void* src ); - extern void iMOVQZX( const iRegisterXMM& to, const ModSibBase& src ); - extern void iMOVQZX( const iRegisterXMM& to, const iRegisterXMM& from ); + extern void iMOVQZX( const iRegisterSSE& to, const void* src ); + extern void iMOVQZX( const iRegisterSSE& to, const ModSibBase& src ); + extern void iMOVQZX( const iRegisterSSE& to, const iRegisterSSE& from ); - extern void iMOVSS( const iRegisterXMM& to, const iRegisterXMM& from ); - extern void iMOVSS( const void* to, const iRegisterXMM& from ); - extern void iMOVSS( const ModSibBase& to, const iRegisterXMM& from ); + extern void iMOVSS( const iRegisterSSE& to, const iRegisterSSE& from ); + extern void iMOVSS( const void* to, const iRegisterSSE& from ); + extern void iMOVSS( const ModSibBase& to, const iRegisterSSE& from ); + extern void iMOVSD( const iRegisterSSE& to, const iRegisterSSE& from ); + extern void iMOVSD( const void* to, const iRegisterSSE& from ); + extern void iMOVSD( const ModSibBase& to, const iRegisterSSE& from ); - extern void iMOVSSZX( const iRegisterXMM& to, const void* from ); - extern void iMOVSSZX( const iRegisterXMM& to, const ModSibBase& from ); + extern void iMOVSSZX( const iRegisterSSE& to, const void* from ); + extern void iMOVSSZX( const iRegisterSSE& to, const ModSibBase& from ); + extern void iMOVSDZX( const iRegisterSSE& to, const void* from ); + extern void iMOVSDZX( const iRegisterSSE& to, const ModSibBase& from ); } diff --git a/pcsx2/x86/ix86/ix86_legacy.cpp b/pcsx2/x86/ix86/ix86_legacy.cpp index d227d47ef2..e3daec9b59 100644 --- a/pcsx2/x86/ix86/ix86_legacy.cpp +++ b/pcsx2/x86/ix86/ix86_legacy.cpp @@ -48,13 +48,13 @@ static __forceinline ModSibBase _mrmhlp( x86IntRegType src ) template< typename ImmType > static __forceinline ModSibStrict _mhlp( x86IntRegType src ) { - return ModSibStrict( x86IndexReg::Empty, x86IndexReg(src) ); + return ModSibStrict( iAddressReg::Empty, iAddressReg(src) ); } template< typename ImmType > static __forceinline ModSibStrict _mhlp2( x86IntRegType src1, x86IntRegType src2 ) { - return ModSibStrict( x86IndexReg(src2), x86IndexReg(src1) ); + return ModSibStrict( iAddressReg(src2), iAddressReg(src1) ); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -134,7 +134,7 @@ DEFINE_OPCODE_ONEREG_LEGACY( NEG ) // ------------------------------------------------------------------------ #define DEFINE_LEGACY_MOVEXTEND( form, destbits, srcbits ) \ emitterT void MOV##form##destbits##R##srcbits##toR( x86IntRegType to, x86IntRegType from ) { iMOV##form( iRegister##destbits( to ), iRegister##srcbits( from ) ); } \ - emitterT void MOV##form##destbits##Rm##srcbits##toR( x86IntRegType to, x86IntRegType from, int offset ) { iMOV##form( iRegister##destbits( to ), ptr##srcbits[x86IndexReg( from ) + offset] ); } \ + emitterT void MOV##form##destbits##Rm##srcbits##toR( x86IntRegType to, x86IntRegType from, int offset ) { iMOV##form( iRegister##destbits( to ), ptr##srcbits[iAddressReg( from ) + offset] ); } \ emitterT void MOV##form##destbits##M##srcbits##toR( x86IntRegType to, u32 from ) { iMOV##form( iRegister##destbits( to ), ptr##srcbits[from] ); } DEFINE_LEGACY_MOVEXTEND( SX, 32, 16 ) @@ -148,32 +148,32 @@ DEFINE_LEGACY_MOVEXTEND( ZX, 16, 8 ) emitterT void TEST32ItoR( x86IntRegType to, u32 from ) { iTEST( iRegister32(to), from ); } emitterT void TEST32ItoM( uptr to, u32 from ) { iTEST( ptr32[to], from ); } emitterT void TEST32RtoR( x86IntRegType to, x86IntRegType from ) { iTEST( iRegister32(to), iRegister32(from) ); } -emitterT void TEST32ItoRm( x86IntRegType to, u32 from ) { iTEST( ptr32[x86IndexReg(to)], from ); } +emitterT void TEST32ItoRm( x86IntRegType to, u32 from ) { iTEST( ptr32[iAddressReg(to)], from ); } emitterT void TEST16ItoR( x86IntRegType to, u16 from ) { iTEST( iRegister16(to), from ); } emitterT void TEST16ItoM( uptr to, u16 from ) { iTEST( ptr16[to], from ); } emitterT void TEST16RtoR( x86IntRegType to, x86IntRegType from ) { iTEST( iRegister16(to), iRegister16(from) ); } -emitterT void TEST16ItoRm( x86IntRegType to, u16 from ) { iTEST( ptr16[x86IndexReg(to)], from ); } +emitterT void TEST16ItoRm( x86IntRegType to, u16 from ) { iTEST( ptr16[iAddressReg(to)], from ); } emitterT void TEST8ItoR( x86IntRegType to, u8 from ) { iTEST( iRegister8(to), from ); } emitterT void TEST8ItoM( uptr to, u8 from ) { iTEST( ptr8[to], from ); } emitterT void TEST8RtoR( x86IntRegType to, x86IntRegType from ) { iTEST( iRegister8(to), iRegister8(from) ); } -emitterT void TEST8ItoRm( x86IntRegType to, u8 from ) { iTEST( ptr8[x86IndexReg(to)], from ); } +emitterT void TEST8ItoRm( x86IntRegType to, u8 from ) { iTEST( ptr8[iAddressReg(to)], from ); } // mov r32 to [r32<_< // - typedef iRegisterSIMD iRegisterXMM; + typedef iRegisterSIMD iRegisterSSE; typedef iRegisterSIMD iRegisterMMX; typedef iRegister iRegister32; typedef iRegister iRegister16; @@ -278,7 +278,7 @@ namespace x86Emitter iRegisterCL(): iRegister8( 1 ) {} }; - extern const iRegisterXMM + extern const iRegisterSSE xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7; @@ -302,30 +302,30 @@ namespace x86Emitter ////////////////////////////////////////////////////////////////////////////////////////// // Use 32 bit registers as out index register (for ModSib memory address calculations) - // Only x86IndexReg provides operators for constructing iAddressInfo types. + // Only iAddressReg provides operators for constructing iAddressInfo types. // - class x86IndexReg : public iRegister32 + class iAddressReg : public iRegister32 { public: - static const x86IndexReg Empty; // defined as an empty/unused value (-1) + static const iAddressReg Empty; // defined as an empty/unused value (-1) public: - x86IndexReg(): iRegister32() {} - x86IndexReg( const x86IndexReg& src ) : iRegister32( src.Id ) {} - x86IndexReg( const iRegister32& src ) : iRegister32( src ) {} - explicit x86IndexReg( int regId ) : iRegister32( regId ) {} + iAddressReg(): iRegister32() {} + iAddressReg( const iAddressReg& src ) : iRegister32( src.Id ) {} + iAddressReg( const iRegister32& src ) : iRegister32( src ) {} + explicit iAddressReg( int regId ) : iRegister32( regId ) {} // Returns true if the register is the stack pointer: ESP. bool IsStackPointer() const { return Id == 4; } - iAddressInfo operator+( const x86IndexReg& right ) const; + iAddressInfo operator+( const iAddressReg& right ) const; iAddressInfo operator+( const iAddressInfo& right ) const; iAddressInfo operator+( s32 right ) const; iAddressInfo operator*( u32 factor ) const; iAddressInfo operator<<( u32 shift ) const; - x86IndexReg& operator=( const iRegister32& src ) + iAddressReg& operator=( const iRegister32& src ) { Id = src.Id; return *this; @@ -337,13 +337,13 @@ namespace x86Emitter class iAddressInfo { public: - x86IndexReg Base; // base register (no scale) - x86IndexReg Index; // index reg gets multiplied by the scale + iAddressReg Base; // base register (no scale) + iAddressReg Index; // index reg gets multiplied by the scale int Factor; // scale applied to the index register, in factor form (not a shift!) s32 Displacement; // address displacement public: - __forceinline iAddressInfo( const x86IndexReg& base, const x86IndexReg& index, int factor=1, s32 displacement=0 ) : + __forceinline iAddressInfo( const iAddressReg& base, const iAddressReg& index, int factor=1, s32 displacement=0 ) : Base( base ), Index( index ), Factor( factor ), @@ -351,7 +351,7 @@ namespace x86Emitter { } - __forceinline explicit iAddressInfo( const x86IndexReg& index, int displacement=0 ) : + __forceinline explicit iAddressInfo( const iAddressReg& index, int displacement=0 ) : Base(), Index( index ), Factor(0), @@ -367,7 +367,7 @@ namespace x86Emitter { } - static iAddressInfo FromIndexReg( const x86IndexReg& index, int scale=0, s32 displacement=0 ); + static iAddressInfo FromIndexReg( const iAddressReg& index, int scale=0, s32 displacement=0 ); public: bool IsByteSizeDisp() const { return is_s8( Displacement ); } @@ -378,10 +378,10 @@ namespace x86Emitter return *this; } - __forceinline iAddressInfo& Add( const x86IndexReg& src ); + __forceinline iAddressInfo& Add( const iAddressReg& src ); __forceinline iAddressInfo& Add( const iAddressInfo& src ); - __forceinline iAddressInfo operator+( const x86IndexReg& right ) const { return iAddressInfo( *this ).Add( right ); } + __forceinline iAddressInfo operator+( const iAddressReg& right ) const { return iAddressInfo( *this ).Add( right ); } __forceinline iAddressInfo operator+( const iAddressInfo& right ) const { return iAddressInfo( *this ).Add( right ); } __forceinline iAddressInfo operator+( s32 imm ) const { return iAddressInfo( *this ).Add( imm ); } __forceinline iAddressInfo operator-( s32 imm ) const { return iAddressInfo( *this ).Add( -imm ); } @@ -402,15 +402,15 @@ namespace x86Emitter class ModSibBase { public: - x86IndexReg Base; // base register (no scale) - x86IndexReg Index; // index reg gets multiplied by the scale + iAddressReg Base; // base register (no scale) + iAddressReg Index; // index reg gets multiplied by the scale uint Scale; // scale applied to the index register, in scale/shift form s32 Displacement; // offset applied to the Base/Index registers. public: explicit ModSibBase( const iAddressInfo& src ); explicit ModSibBase( s32 disp ); - ModSibBase( x86IndexReg base, x86IndexReg index, int scale=0, s32 displacement=0 ); + ModSibBase( iAddressReg base, iAddressReg index, int scale=0, s32 displacement=0 ); bool IsByteSizeDisp() const { return is_s8( Displacement ); } @@ -424,7 +424,7 @@ namespace x86Emitter __forceinline ModSibBase operator-( const s32 imm ) const { return ModSibBase( *this ).Add( -imm ); } protected: - __forceinline void Reduce(); + void Reduce(); }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -439,7 +439,7 @@ namespace x86Emitter __forceinline explicit ModSibStrict( const iAddressInfo& src ) : ModSibBase( src ) {} __forceinline explicit ModSibStrict( s32 disp ) : ModSibBase( disp ) {} - __forceinline ModSibStrict( x86IndexReg base, x86IndexReg index, int scale=0, s32 displacement=0 ) : + __forceinline ModSibStrict( iAddressReg base, iAddressReg index, int scale=0, s32 displacement=0 ) : ModSibBase( base, index, scale, displacement ) {} __forceinline ModSibStrict& Add( s32 imm ) @@ -461,9 +461,9 @@ namespace x86Emitter // without doing anything and without compiler error. const ModSibBase& operator[]( const ModSibBase& src ) const { return src; } - __forceinline ModSibBase operator[]( x86IndexReg src ) const + __forceinline ModSibBase operator[]( iAddressReg src ) const { - return ModSibBase( src, x86IndexReg::Empty ); + return ModSibBase( src, iAddressReg::Empty ); } __forceinline ModSibBase operator[]( const iAddressInfo& src ) const @@ -497,9 +497,9 @@ namespace x86Emitter // without doing anything and without compiler error. const ModSibStrict& operator[]( const ModSibStrict& src ) const { return src; } - __forceinline ModSibStrict operator[]( x86IndexReg src ) const + __forceinline ModSibStrict operator[]( iAddressReg src ) const { - return ModSibStrict( src, x86IndexReg::Empty ); + return ModSibStrict( src, iAddressReg::Empty ); } __forceinline ModSibStrict operator[]( const iAddressInfo& src ) const @@ -523,6 +523,8 @@ namespace x86Emitter // ptr[] - use this form for instructions which can resolve the address operand size from // the other register operand sizes. extern const iAddressIndexerBase ptr; + extern const iAddressIndexer ptr128; + extern const iAddressIndexer ptr64; extern const iAddressIndexer ptr32; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms extern const iAddressIndexer ptr16; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms extern const iAddressIndexer ptr8; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms @@ -674,6 +676,16 @@ namespace x86Emitter ////////////////////////////////////////////////////////////////////////////////////////// // + + extern const Internal::MovapsImplAll< 0, 0x28, 0x29 > iMOVAPS; + extern const Internal::MovapsImplAll< 0, 0x10, 0x11 > iMOVUPS; + + extern const Internal::MovapsImplAll< 0x66, 0x28, 0x29 > iMOVAPD; + extern const Internal::MovapsImplAll< 0x66, 0x10, 0x11 > iMOVUPD; + + extern const Internal::MovapsImplAll< 0x66, 0x6f, 0x7f > iMOVDQA; + extern const Internal::MovapsImplAll< 0xf3, 0x6f, 0x7f > iMOVDQU; + } #include "ix86_inlines.inl"