From d91eb6d1c86eaec656e91a6af84248e5331d1ebb Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Sun, 19 Apr 2009 16:34:29 +0000 Subject: [PATCH] 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 --- pcsx2/x86/ix86/implement/bittest.h | 5 +- pcsx2/x86/ix86/implement/xmm/movqss.h | 106 ++++----- pcsx2/x86/ix86/ix86.cpp | 79 +++++-- pcsx2/x86/ix86/ix86_instructions.h | 47 +++- pcsx2/x86/ix86/ix86_legacy_instructions.h | 10 +- pcsx2/x86/ix86/ix86_legacy_mmx.cpp | 111 ++------- pcsx2/x86/ix86/ix86_legacy_sse.cpp | 272 +++------------------- pcsx2/x86/ix86/ix86_types.h | 25 +- 8 files changed, 236 insertions(+), 419 deletions(-) diff --git a/pcsx2/x86/ix86/implement/bittest.h b/pcsx2/x86/ix86/implement/bittest.h index b4dc648b9c..dd3d8fcc73 100644 --- a/pcsx2/x86/ix86/implement/bittest.h +++ b/pcsx2/x86/ix86/implement/bittest.h @@ -56,15 +56,14 @@ public: } // ------------------------------------------------------------------------ -#ifndef __LINUX__ static __emitinline void Emit( void* bitbase, const iRegister& bitoffset ) { prefix16(); iWrite( 0x0f ); iWrite( 0xa3 | (InstType << 2) ); - iWriteDisp( bitoffset.Id, bitbase.Id ); + iWriteDisp( bitoffset.Id, bitbase ); } -#endif + // ------------------------------------------------------------------------ static __emitinline void Emit( const ModSibBase& bitbase, const iRegister& bitoffset ) { diff --git a/pcsx2/x86/ix86/implement/xmm/movqss.h b/pcsx2/x86/ix86/implement/xmm/movqss.h index f2c29c187f..0a955b053b 100644 --- a/pcsx2/x86/ix86/implement/xmm/movqss.h +++ b/pcsx2/x86/ix86/implement/xmm/movqss.h @@ -22,7 +22,7 @@ // MMX / SSE Helper Functions! template< typename T > -__emitinline void SimdPrefix( u8 opcode, u8 prefix ) +__emitinline void SimdPrefix( u8 opcode, u8 prefix=0 ) { if( sizeof( T ) == 16 && prefix != 0 ) { @@ -33,84 +33,84 @@ __emitinline void SimdPrefix( u8 opcode, u8 prefix ) iWrite( (opcode<<8) | 0x0f ); } -template< u8 prefix, typename T, typename T2 > -__emitinline void writeXMMop( u8 opcode, const iRegister& to, const iRegister& 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& to, const iRegister& from ) { SimdPrefix( opcode, prefix ); ModRM_Direct( to.Id, from.Id ); } -template< u8 prefix, typename T > -void writeXMMop( u8 opcode, const iRegister& reg, const ModSibBase& sib ) +template< typename T > +void writeXMMop( u8 prefix, u8 opcode, const iRegister& reg, const ModSibBase& sib ) { SimdPrefix( opcode, prefix ); EmitSibMagic( reg.Id, sib ); } -template< u8 prefix, typename T > -__emitinline void writeXMMop( u8 opcode, const iRegister& reg, const void* data ) +template< typename T > +__emitinline void writeXMMop( u8 prefix, u8 opcode, const iRegister& reg, const void* data ) { SimdPrefix( opcode, prefix ); 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& to, const iRegister& from ) +{ + SimdPrefix( opcode ); + ModRM_Direct( to.Id, from.Id ); +} + +template< typename T > +void writeXMMop( u8 opcode, const iRegister& reg, const ModSibBase& sib ) +{ + SimdPrefix( opcode ); + EmitSibMagic( reg.Id, sib ); +} + +template< typename T > +__emitinline void writeXMMop( u8 opcode, const iRegister& reg, const void* data ) +{ + SimdPrefix( opcode ); + iWriteDisp( reg.Id, data ); +} + ////////////////////////////////////////////////////////////////////////////////////////// // -template< u8 Prefix, typename OperandType > -class MovapsImpl +// Moves to/from high/low portions of an xmm register. +// These instructions cannot be used in reg/reg form. +template< u8 Prefix, u8 Opcode > +class MovhlImplAll { public: - // ------------------------------------------------------------------------ - static __emitinline void Emit( u8 opcode, const iRegisterSIMD& to, const iRegisterSIMD from ) - { - if( to != from ) - writeXMMop( opcode, to, from ); - } - - // ------------------------------------------------------------------------ - static __emitinline void Emit( u8 opcode, const iRegisterSIMD& to, const void* from ) - { - writeXMMop( opcode, to, from ); - } - - // ------------------------------------------------------------------------ - static __emitinline void Emit( u8 opcode, const iRegisterSIMD& to, const ModSibBase& from ) - { - writeXMMop( 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& from ) - { - writeXMMop( 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& from ) - { - writeXMMop( opcode, from, to ); - } + __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 { writeXMMop( Prefix, Opcode+1, from, to ); } + __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 { writeXMMop( Prefix, Opcode+1, from, to ); } + MovhlImplAll() {} //GCC. }; -// ------------------------------------------------------------------------ template< u8 Prefix, u8 Opcode, u8 OpcodeAlt > class MovapsImplAll { -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 ); } + __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 { writeXMMop( Prefix, Opcode, 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 { writeXMMop( Prefix, Opcode, to, from ); } + __noinline void operator()( const ModSibBase& to, const iRegisterSSE& from ) const { writeXMMop( Prefix, OpcodeAlt, from, to ); } MovapsImplAll() {} //GCC. }; - diff --git a/pcsx2/x86/ix86/ix86.cpp b/pcsx2/x86/ix86/ix86.cpp index aa85482572..2557ba8f30 100644 --- a/pcsx2/x86/ix86/ix86.cpp +++ b/pcsx2/x86/ix86/ix86.cpp @@ -740,29 +740,40 @@ const MovapsImplAll< 0, 0x10, 0x11 > iMOVUPS; const MovapsImplAll< 0x66, 0x28, 0x29 > iMOVAPD; const MovapsImplAll< 0x66, 0x10, 0x11 > iMOVUPD; +#ifdef ALWAYS_USE_MOVAPS const MovapsImplAll< 0x66, 0x6f, 0x7f > iMOVDQA; 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 // 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 // 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 // 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 ); } -__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 iRegisterMMX& from ) { if( to != from ) writeXMMop( 0x6f, to, from ); } +__noinline void iMOVQ( const iRegisterMMX& to, const ModSibBase& src ) { writeXMMop( 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( 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( 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 ) { // 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 ) \ - __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 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 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 ModSibBase& to, const iRegisterSSE& from ) { writeXMMop( prefix, 0x11, from, to ); } IMPLEMENT_iMOVS( SS, 0xf3 ) 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( 0x2A380f66 ); + iWriteDisp( to.Id, from ); +} + +__noinline void iMOVNTDQA( const iRegisterSSE& to, const ModSibBase& from ) +{ + iWrite( 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 ); } + + } diff --git a/pcsx2/x86/ix86/ix86_instructions.h b/pcsx2/x86/ix86/ix86_instructions.h index 64fee9d85b..5b776567ad 100644 --- a/pcsx2/x86/ix86/ix86_instructions.h +++ b/pcsx2/x86/ix86/ix86_instructions.h @@ -331,42 +331,60 @@ namespace x86Emitter template< typename T > __emitinline void iMOVDZX( const iRegisterSIMD& to, const iRegister32& from ) { - Internal::writeXMMop<0x66>( 0x6e, to, 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 ); + Internal::writeXMMop( 0x66, 0x6e, to, src ); } template< typename T > void iMOVDZX( const iRegisterSIMD& to, const ModSibBase& src ) { - Internal::writeXMMop<0x66>( 0x6e, to, 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 ); + Internal::writeXMMop( 0x66, 0x7e, from, to ); } template< typename T > __emitinline void iMOVD( void* dest, const iRegisterSIMD& from ) { - Internal::writeXMMop<0x66>( 0x7e, from, dest ); + Internal::writeXMMop( 0x66, 0x7e, from, dest ); } template< typename T > void iMOVD( const ModSibBase& dest, const iRegisterSIMD& 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& to, const iRegisterSIMD& 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& 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 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 ); + } diff --git a/pcsx2/x86/ix86/ix86_legacy_instructions.h b/pcsx2/x86/ix86/ix86_legacy_instructions.h index e58e7f8d7a..f36522852f 100644 --- a/pcsx2/x86/ix86/ix86_legacy_instructions.h +++ b/pcsx2/x86/ix86/ix86_legacy_instructions.h @@ -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_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_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from ); 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_MOVAPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 ); -extern void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 ); -extern void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 ); -extern void SSE_MOVUPSRtoRm( x86IntRegType to, x86IntRegType from ); -extern void SSE_MOVUPSRmtoR( x86IntRegType to, x86IntRegType from ); +extern void SSE_MOVUPSRtoRm( x86IntRegType to, x86SSERegType from ); +extern void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from ); extern void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 ); extern void SSE_MOVUPSRtoRm( x86SSERegType to, x86IntRegType from, int offset=0 ); diff --git a/pcsx2/x86/ix86/ix86_legacy_mmx.cpp b/pcsx2/x86/ix86/ix86_legacy_mmx.cpp index 40e2170bf2..cf06a37777 100644 --- a/pcsx2/x86/ix86/ix86_legacy_mmx.cpp +++ b/pcsx2/x86/ix86/ix86_legacy_mmx.cpp @@ -27,23 +27,27 @@ using namespace x86Emitter; -/* movq m64 to r64 */ -emitterT void MOVQMtoR( x86MMXRegType to, uptr from ) +emitterT void MOVQMtoR( x86MMXRegType to, uptr from ) { iMOVQ( iRegisterMMX(to), (void*)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 ); - //write16( 0x6F0F ); - //ModRM( 0, to, DISP32 ); - //write32( MEMADDR(from, 4) ); + iPMOVMSKB( iRegister32(to), iRegisterMMX(from) ); } -/* 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 */ emitterT void PANDRtoR( x86MMXRegType to, x86MMXRegType from ) @@ -474,73 +478,6 @@ emitterT void PUNPCKLDQMtoR( x86MMXRegType to, uptr from ) 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 emitterT void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from) { @@ -554,12 +491,6 @@ emitterT void PACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType 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 ) { 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); } -emitterT void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from) -{ - write16(0xf70f); - ModRM( 3, to, from ); -} +emitterT void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from) { iMASKMOV( iRegisterMMX(to), iRegisterMMX(from) ); } diff --git a/pcsx2/x86/ix86/ix86_legacy_sse.cpp b/pcsx2/x86/ix86/ix86_legacy_sse.cpp index b604919e22..365b168902 100644 --- a/pcsx2/x86/ix86/ix86_legacy_sse.cpp +++ b/pcsx2/x86/ix86/ix86_legacy_sse.cpp @@ -22,17 +22,6 @@ 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 @@ -147,164 +136,28 @@ static const bool AlwaysUseMovaps = true; SSE_SD_RtoR( 0xc20f ), \ write8( op ) -/* movups [r32][r32*scale] to xmm1 */ -emitterT void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) -{ - RexRXB(0, to, from2, from); - write16( 0x100f ); - ModRM( 0, to, 0x4 ); - SibSB( scale, from2, from ); -} +#define DEFINE_LEGACY_MOV_OPCODE( mod, sse ) \ + 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) ); } \ + emitterT void sse##_MOV##mod##RmtoR( x86SSERegType to, x86IntRegType from, int offset ) { iMOV##mod( iRegisterSSE(to), ptr[iAddressReg(from)+offset] ); } \ + emitterT void sse##_MOV##mod##RtoRm( x86IntRegType to, x86SSERegType from, int offset ) { iMOV##mod( ptr[iAddressReg(to)+offset], iRegisterSSE(from) ); } \ + emitterT void sse##_MOV##mod##RmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) \ + { 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] */ -emitterT void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale ) -{ - RexRXB(1, to, from2, from); - write16( 0x110f ); - ModRM( 0, to, 0x4 ); - SibSB( scale, from2, from ); -} - -/* movups [r32] to r32 */ -emitterT void 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); -} +DEFINE_LEGACY_MOV_OPCODE( UPS, SSE ) +DEFINE_LEGACY_MOV_OPCODE( APS, SSE ) +DEFINE_LEGACY_MOV_OPCODE( LPS, SSE ) +DEFINE_LEGACY_MOV_OPCODE( HPS, SSE ) +DEFINE_LEGACY_MOV_OPCODE( DQA, SSE2 ) +DEFINE_LEGACY_MOV_OPCODE( DQU, SSE2 ) //**********************************************************************************/ //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_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_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_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_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 ); } +emitterT void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { iMASKMOV( iRegisterSSE(to), iRegisterSSE(from) ); } //**********************************************************************************/ //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_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x130f, 0 ); } - -emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) -{ - 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); -} +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 ) { 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_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { iMOVLPS( ptr[iAddressReg(to)+offset], iRegisterSSE(from) ); } ///////////////////////////////////////////////////////////////////////////////////// //**********************************************************************************/ //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_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x170f, 0 ); } - -emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset ) -{ - 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); -} +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 ) { 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_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset ) { iMOVHPS( ptr[iAddressReg(to)+offset], iRegisterSSE(from) ); } ///////////////////////////////////////////////////////////////////////////////////// //**********************************************************************************/ //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 * //********************************************************************************** -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_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_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 @@ -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_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 SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0x500F); } diff --git a/pcsx2/x86/ix86/ix86_types.h b/pcsx2/x86/ix86/ix86_types.h index 2bed0871d6..1ef7f33e0a 100644 --- a/pcsx2/x86/ix86/ix86_types.h +++ b/pcsx2/x86/ix86/ix86_types.h @@ -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< 0x66, 0x28, 0x29 > iMOVAPD; extern const Internal::MovapsImplAll< 0x66, 0x10, 0x11 > iMOVUPD; + #ifdef ALWAYS_USE_MOVAPS extern const Internal::MovapsImplAll< 0x66, 0x6f, 0x7f > iMOVDQA; 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; }