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