mirror of https://github.com/PCSX2/pcsx2.git
Emitter: Major refactoring / renaming job. Improved type checking and usefulness of xAddress* (Void, 32, 64, etc) types.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3397 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
6e30a41931
commit
688674bed9
|
@ -34,6 +34,22 @@ extern const wxPoint wxDefaultPosition;
|
|||
// This should prove useful....
|
||||
#define wxsFormat wxString::Format
|
||||
|
||||
#ifdef PCSX2_DEBUG
|
||||
# define tryDEBUG try
|
||||
# define catchDEBUG(clause) catch(clause)
|
||||
#else
|
||||
# define tryDEBUG if(true)
|
||||
# define catchDEBUG(clause) if(false)
|
||||
#endif
|
||||
|
||||
#if defined(PCSX2_DEVBUILD) || defined(PCSX2_DEBUG)
|
||||
# define tryDEVEL try
|
||||
# define catchDEVEL catch(clause)
|
||||
#else
|
||||
# define tryDEBUG if(true)
|
||||
# define catchDEBUG(clause) if(false)
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ImplementEnumOperators (macro)
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -37,8 +37,8 @@ struct xImpl_DwordShift
|
|||
void operator()( const xRegister32& to, const xRegister32& from, u8 shiftcnt ) const;
|
||||
void operator()( const xRegister16& to, const xRegister16& from, u8 shiftcnt ) const;
|
||||
|
||||
void operator()( const ModSibBase& dest,const xRegister16or32& from, const xRegisterCL& clreg ) const;
|
||||
void operator()( const ModSibBase& dest,const xRegister16or32& from, u8 shiftcnt ) const;
|
||||
void operator()( const xIndirectVoid& dest,const xRegister16or32& from, const xRegisterCL& clreg ) const;
|
||||
void operator()( const xIndirectVoid& dest,const xRegister16or32& from, u8 shiftcnt ) const;
|
||||
};
|
||||
|
||||
} // End namespace x86Emitter
|
||||
|
|
|
@ -29,6 +29,8 @@ enum G1Type
|
|||
G1Type_CMP
|
||||
};
|
||||
|
||||
extern void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xRegisterInt& from );
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xImpl_Group1
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -40,10 +42,10 @@ struct xImpl_Group1
|
|||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
|
||||
void operator()( const ModSibBase& to, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const ModSibBase& from ) const;
|
||||
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const;
|
||||
void operator()( const xRegisterInt& to, int imm ) const;
|
||||
void operator()( const ModSib32orLess& to, int imm ) const;
|
||||
void operator()( const xIndirect32orLess& to, int imm ) const;
|
||||
|
||||
#if 0
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -93,11 +95,11 @@ struct xImpl_G1Logic
|
|||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
|
||||
void operator()( const ModSibBase& to, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const ModSibBase& from ) const;
|
||||
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const;
|
||||
void operator()( const xRegisterInt& to, int imm ) const;
|
||||
|
||||
void operator()( const ModSib32orLess& to, int imm ) const;
|
||||
void operator()( const xIndirect32orLess& to, int imm ) const;
|
||||
|
||||
xImplSimd_DestRegSSE PS; // packed single precision
|
||||
xImplSimd_DestRegSSE PD; // packed double precision
|
||||
|
@ -114,11 +116,11 @@ struct xImpl_G1Arith
|
|||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
|
||||
void operator()( const ModSibBase& to, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const ModSibBase& from ) const;
|
||||
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const;
|
||||
void operator()( const xRegisterInt& to, int imm ) const;
|
||||
|
||||
void operator()( const ModSib32orLess& to, int imm ) const;
|
||||
void operator()( const xIndirect32orLess& to, int imm ) const;
|
||||
|
||||
xImplSimd_DestRegSSE PS; // packed single precision
|
||||
xImplSimd_DestRegSSE PD; // packed double precision
|
||||
|
@ -133,11 +135,11 @@ struct xImpl_G1Compare
|
|||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
|
||||
void operator()( const ModSibBase& to, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const ModSibBase& from ) const;
|
||||
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const;
|
||||
void operator()( const xRegisterInt& to, int imm ) const;
|
||||
|
||||
void operator()( const ModSib32orLess& to, int imm ) const;
|
||||
void operator()( const xIndirect32orLess& to, int imm ) const;
|
||||
|
||||
xImplSimd_DestSSE_CmpImm PS;
|
||||
xImplSimd_DestSSE_CmpImm PD;
|
||||
|
|
|
@ -41,9 +41,9 @@ struct xImpl_Group2
|
|||
G2Type InstType;
|
||||
|
||||
void operator()( const xRegisterInt& to, const xRegisterCL& from ) const;
|
||||
void operator()( const ModSib32orLess& to, const xRegisterCL& from ) const;
|
||||
void operator()( const xIndirect32orLess& to, const xRegisterCL& from ) const;
|
||||
void operator()( const xRegisterInt& to, u8 imm ) const;
|
||||
void operator()( const ModSib32orLess& to, u8 imm ) const;
|
||||
void operator()( const xIndirect32orLess& to, u8 imm ) const;
|
||||
|
||||
#if 0
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
|
@ -35,7 +35,7 @@ struct xImpl_Group3
|
|||
G3Type InstType;
|
||||
|
||||
void operator()( const xRegisterInt& from ) const;
|
||||
void operator()( const ModSib32orLess& from ) const;
|
||||
void operator()( const xIndirect32orLess& from ) const;
|
||||
|
||||
#if 0
|
||||
template< typename T >
|
||||
|
@ -57,7 +57,7 @@ struct xImpl_MulDivBase
|
|||
u16 OpcodeSSE;
|
||||
|
||||
void operator()( const xRegisterInt& from ) const;
|
||||
void operator()( const ModSib32orLess& from ) const;
|
||||
void operator()( const xIndirect32orLess& from ) const;
|
||||
|
||||
const xImplSimd_DestRegSSE PS;
|
||||
const xImplSimd_DestRegSSE PD;
|
||||
|
@ -71,7 +71,7 @@ struct xImpl_MulDivBase
|
|||
struct xImpl_iDiv
|
||||
{
|
||||
void operator()( const xRegisterInt& from ) const;
|
||||
void operator()( const ModSib32orLess& from ) const;
|
||||
void operator()( const xIndirect32orLess& from ) const;
|
||||
|
||||
const xImplSimd_DestRegSSE PS;
|
||||
const xImplSimd_DestRegSSE PD;
|
||||
|
@ -86,19 +86,19 @@ struct xImpl_iDiv
|
|||
struct xImpl_iMul
|
||||
{
|
||||
void operator()( const xRegisterInt& from ) const;
|
||||
void operator()( const ModSib32orLess& from ) const;
|
||||
void operator()( const xIndirect32orLess& from ) const;
|
||||
|
||||
// The following iMul-specific forms are valid for 16 and 32 bit register operands only!
|
||||
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
void operator()( const xRegister32& to, const ModSibBase& src ) const;
|
||||
void operator()( const xRegister32& to, const xIndirectVoid& src ) const;
|
||||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister16& to, const ModSibBase& src ) const;
|
||||
void operator()( const xRegister16& to, const xIndirectVoid& src ) const;
|
||||
|
||||
void operator()( const xRegister32& to, const xRegister32& from, s32 imm ) const;
|
||||
void operator()( const xRegister32& to, const ModSibBase& from, s32 imm ) const;
|
||||
void operator()( const xRegister32& to, const xIndirectVoid& from, s32 imm ) const;
|
||||
void operator()( const xRegister16& to, const xRegister16& from, s16 imm ) const;
|
||||
void operator()( const xRegister16& to, const ModSibBase& from, s16 imm ) const;
|
||||
void operator()( const xRegister16& to, const xIndirectVoid& from, s16 imm ) const;
|
||||
|
||||
const xImplSimd_DestRegSSE PS;
|
||||
const xImplSimd_DestRegSSE PD;
|
||||
|
|
|
@ -28,7 +28,7 @@ struct xImpl_IncDec
|
|||
bool isDec;
|
||||
|
||||
void operator()( const xRegisterInt& to ) const;
|
||||
void operator()( const ModSib32orLess& to ) const;
|
||||
void operator()( const xIndirect32orLess& to ) const;
|
||||
};
|
||||
|
||||
} // End namespace x86Emitter
|
||||
|
|
|
@ -38,10 +38,10 @@ struct xImpl_JmpCall
|
|||
bool isJmp;
|
||||
|
||||
void operator()( const xRegister32& absreg ) const;
|
||||
void operator()( const ModSib32& src ) const;
|
||||
void operator()( const xIndirect32& src ) const;
|
||||
|
||||
void operator()( const xRegister16& absreg ) const;
|
||||
void operator()( const ModSib16& src ) const;
|
||||
void operator()( const xIndirect16& src ) const;
|
||||
|
||||
// Special form for calling functions. This form automatically resolves the
|
||||
// correct displacement based on the size of the instruction being generated.
|
||||
|
|
|
@ -33,9 +33,9 @@ struct xImpl_Mov
|
|||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
|
||||
void operator()( const ModSibBase& dest, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const ModSibBase& src ) const;
|
||||
void operator()( const ModSib32orLess& dest, int imm ) const;
|
||||
void operator()( const xIndirectVoid& dest, const xRegisterInt& from ) const;
|
||||
void operator()( const xRegisterInt& to, const xIndirectVoid& src ) const;
|
||||
void operator()( const xIndirect32orLess& dest, int imm ) const;
|
||||
void operator()( const xRegisterInt& to, int imm, bool preserve_flags=false ) const;
|
||||
|
||||
#if 0
|
||||
|
@ -90,10 +90,10 @@ struct xImpl_CMov
|
|||
JccComparisonType ccType;
|
||||
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
void operator()( const xRegister32& to, const ModSibBase& sibsrc ) const;
|
||||
void operator()( const xRegister32& to, const xIndirectVoid& sibsrc ) const;
|
||||
|
||||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister16& to, const ModSibBase& sibsrc ) const;
|
||||
void operator()( const xRegister16& to, const xIndirectVoid& sibsrc ) const;
|
||||
|
||||
//void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from );
|
||||
//void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const;
|
||||
|
@ -104,7 +104,7 @@ struct xImpl_Set
|
|||
JccComparisonType ccType;
|
||||
|
||||
void operator()( const xRegister8& to ) const;
|
||||
void operator()( const ModSib8& dest ) const;
|
||||
void operator()( const xIndirect8& dest ) const;
|
||||
|
||||
//void operator()( const xDirectOrIndirect8& dest ) const;
|
||||
};
|
||||
|
@ -120,9 +120,9 @@ struct xImpl_MovExtend
|
|||
bool SignExtend;
|
||||
|
||||
void operator()( const xRegister16or32& to, const xRegister8& from ) const;
|
||||
void operator()( const xRegister16or32& to, const ModSib8& sibsrc ) const;
|
||||
void operator()( const xRegister16or32& to, const xIndirect8& sibsrc ) const;
|
||||
void operator()( const xRegister32& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister32& to, const ModSib16& sibsrc ) const;
|
||||
void operator()( const xRegister32& to, const xIndirect16& sibsrc ) const;
|
||||
|
||||
//void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const;
|
||||
//void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const;
|
||||
|
|
|
@ -28,10 +28,10 @@ struct _SimdShiftHelper
|
|||
u8 Modcode;
|
||||
|
||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
|
||||
void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const;
|
||||
void operator()( const xRegisterMMX& to, const ModSibBase& from ) const;
|
||||
void operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const;
|
||||
|
||||
void operator()( const xRegisterSSE& to, u8 imm8 ) const;
|
||||
void operator()( const xRegisterMMX& to, u8 imm8 ) const;
|
||||
|
|
|
@ -32,16 +32,16 @@ struct xImplSimd_Compare
|
|||
SSE2_ComparisonType CType;
|
||||
|
||||
void PS( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void PS( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void PS( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
|
||||
void PD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void PD( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void PD( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
|
||||
void SS( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void SS( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void SS( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
|
||||
void SD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void SD( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void SD( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -31,7 +31,7 @@ struct xImplSimd_DestRegSSE
|
|||
u16 Opcode;
|
||||
|
||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -44,7 +44,7 @@ struct xImplSimd_DestRegImmSSE
|
|||
u16 Opcode;
|
||||
|
||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const;
|
||||
void operator()( const xRegisterSSE& to, const ModSibBase& from, u8 imm ) const;
|
||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const;
|
||||
};
|
||||
|
||||
struct xImplSimd_DestSSE_CmpImm
|
||||
|
@ -53,7 +53,7 @@ struct xImplSimd_DestSSE_CmpImm
|
|||
u16 Opcode;
|
||||
|
||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType imm ) const;
|
||||
void operator()( const xRegisterSSE& to, const ModSibBase& from, SSE2_ComparisonType imm ) const;
|
||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm ) const;
|
||||
};
|
||||
|
||||
struct xImplSimd_DestRegImmMMX
|
||||
|
@ -62,7 +62,7 @@ struct xImplSimd_DestRegImmMMX
|
|||
u16 Opcode;
|
||||
|
||||
void operator()( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm ) const;
|
||||
void operator()( const xRegisterMMX& to, const ModSibBase& from, u8 imm ) const;
|
||||
void operator()( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm ) const;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -75,10 +75,10 @@ struct xImplSimd_DestRegEither
|
|||
u16 Opcode;
|
||||
|
||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
|
||||
void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const;
|
||||
void operator()( const xRegisterMMX& to, const ModSibBase& from ) const;
|
||||
void operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const;
|
||||
};
|
||||
|
||||
} // end namespace x86Emitter
|
||||
|
|
|
@ -27,11 +27,11 @@ struct xImplSimd_MovHL
|
|||
{
|
||||
u16 Opcode;
|
||||
|
||||
void PS( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void PS( const ModSibBase& to, const xRegisterSSE& from ) const;
|
||||
void PS( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
void PS( const xIndirectVoid& to, const xRegisterSSE& from ) const;
|
||||
|
||||
void PD( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void PD( const ModSibBase& to, const xRegisterSSE& from ) const;
|
||||
void PD( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
void PD( const xIndirectVoid& to, const xRegisterSSE& from ) const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -63,8 +63,8 @@ struct xImplSimd_MoveSSE
|
|||
bool isAligned;
|
||||
|
||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void operator()( const ModSibBase& to, const xRegisterSSE& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
void operator()( const xIndirectVoid& to, const xRegisterSSE& from ) const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -82,8 +82,8 @@ struct xImplSimd_MoveDQ
|
|||
bool isAligned;
|
||||
|
||||
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const ModSibBase& from ) const;
|
||||
void operator()( const ModSibBase& to, const xRegisterSSE& from ) const;
|
||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const;
|
||||
void operator()( const xIndirectVoid& to, const xRegisterSSE& from ) const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -142,32 +142,32 @@ struct xImplSimd_PMove
|
|||
// [SSE-4.1] Zero/Sign-extend the low byte values in src into word integers
|
||||
// and store them in dest.
|
||||
void BW( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void BW( const xRegisterSSE& to, const ModSib64& from ) const;
|
||||
void BW( const xRegisterSSE& to, const xIndirect64& from ) const;
|
||||
|
||||
// [SSE-4.1] Zero/Sign-extend the low byte values in src into dword integers
|
||||
// and store them in dest.
|
||||
void BD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void BD( const xRegisterSSE& to, const ModSib32& from ) const;
|
||||
void BD( const xRegisterSSE& to, const xIndirect32& from ) const;
|
||||
|
||||
// [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers
|
||||
// and store them in dest.
|
||||
void BQ( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void BQ( const xRegisterSSE& to, const ModSib16& from ) const;
|
||||
void BQ( const xRegisterSSE& to, const xIndirect16& from ) const;
|
||||
|
||||
// [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers
|
||||
// and store them in dest.
|
||||
void WD( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void WD( const xRegisterSSE& to, const ModSib64& from ) const;
|
||||
void WD( const xRegisterSSE& to, const xIndirect64& from ) const;
|
||||
|
||||
// [SSE-4.1] Zero/Sign-extend the low word values in src into qword integers
|
||||
// and store them in dest.
|
||||
void WQ( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void WQ( const xRegisterSSE& to, const ModSib32& from ) const;
|
||||
void WQ( const xRegisterSSE& to, const xIndirect32& from ) const;
|
||||
|
||||
// [SSE-4.1] Zero/Sign-extend the low dword values in src into qword integers
|
||||
// and store them in dest.
|
||||
void DQ( const xRegisterSSE& to, const xRegisterSSE& from ) const;
|
||||
void DQ( const xRegisterSSE& to, const ModSib64& from ) const;
|
||||
void DQ( const xRegisterSSE& to, const xIndirect64& from ) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@ struct xImplSimd_Shuffle
|
|||
inline void _selector_assertion_check( u8 selector ) const;
|
||||
|
||||
void PS( const xRegisterSSE& to, const xRegisterSSE& from, u8 selector ) const;
|
||||
void PS( const xRegisterSSE& to, const ModSibBase& from, u8 selector ) const;
|
||||
void PS( const xRegisterSSE& to, const xIndirectVoid& from, u8 selector ) const;
|
||||
|
||||
void PD( const xRegisterSSE& to, const xRegisterSSE& from, u8 selector ) const;
|
||||
void PD( const xRegisterSSE& to, const ModSibBase& from, u8 selector ) const;
|
||||
void PD( const xRegisterSSE& to, const xIndirectVoid& from, u8 selector ) const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -63,6 +63,46 @@ struct xImplSimd_PShuffle
|
|||
//
|
||||
// Operands can be MMX or XMM registers.
|
||||
const xImplSimd_DestRegEither B;
|
||||
|
||||
// below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense
|
||||
// but it doesn't (makes it worse). Will try again in MSVC 2010. --air
|
||||
|
||||
#if 0
|
||||
// Copies words from src and inserts them into dest at word locations selected with
|
||||
// the order operand (8 bit immediate).
|
||||
void W( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm ) const { xOpWrite0F( 0x70, to, from, imm ); }
|
||||
void W( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( 0x70, to, from, imm ); }
|
||||
|
||||
// Copies doublewords from src and inserts them into dest at dword locations selected
|
||||
// with the order operand (8 bit immediate).
|
||||
void D( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const { xOpWrite0F( 0x66, 0x70, to, from, imm ); }
|
||||
void D( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( 0x66, 0x70, to, from, imm ); }
|
||||
|
||||
// Copies words from the low quadword of src and inserts them into the low quadword
|
||||
// of dest at word locations selected with the order operand (8 bit immediate).
|
||||
// The high quadword of src is copied to the high quadword of dest.
|
||||
void LW( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const { xOpWrite0F( 0xf2, 0x70, to, from, imm ); }
|
||||
void LW( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( 0xf2, 0x70, to, from, imm ); }
|
||||
|
||||
// Copies words from the high quadword of src and inserts them into the high quadword
|
||||
// of dest at word locations selected with the order operand (8 bit immediate).
|
||||
// The low quadword of src is copied to the low quadword of dest.
|
||||
void HW( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const { xOpWrite0F( 0xf3, 0x70, to, from, imm ); }
|
||||
void HW( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( 0xf3, 0x70, to, from, imm ); }
|
||||
|
||||
// [sSSE-3] Performs in-place shuffles of bytes in dest according to the shuffle
|
||||
// control mask in src. If the most significant bit (bit[7]) of each byte of the
|
||||
// shuffle control mask is set, then constant zero is written in the result byte.
|
||||
// Each byte in the shuffle control mask forms an index to permute the corresponding
|
||||
// byte in dest. The value of each index is the least significant 4 bits (128-bit
|
||||
// operation) or 3 bits (64-bit operation) of the shuffle control byte.
|
||||
//
|
||||
// Operands can be MMX or XMM registers.
|
||||
void B( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
|
||||
void B( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
|
||||
void B( const xRegisterMMX& to, const xRegisterMMX& from ) const { OpWriteSSE( 0x00, 0x0038 ); }
|
||||
void B( const xRegisterMMX& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x00, 0x0038 ); }
|
||||
#endif
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -161,7 +201,7 @@ struct xImplSimd_InsertExtractHelper
|
|||
void operator()( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const;
|
||||
|
||||
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
|
||||
void operator()( const xRegisterSSE& to, const ModSibBase& from, u8 imm8 ) const;
|
||||
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -172,10 +212,10 @@ struct xImplSimd_InsertExtractHelper
|
|||
struct xImplSimd_PInsert
|
||||
{
|
||||
void W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const;
|
||||
void W( const xRegisterSSE& to, const ModSibBase& from, u8 imm8 ) const;
|
||||
void W( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const;
|
||||
|
||||
void W( const xRegisterMMX& to, const xRegister32& from, u8 imm8 ) const;
|
||||
void W( const xRegisterMMX& to, const ModSibBase& from, u8 imm8 ) const;
|
||||
void W( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm8 ) const;
|
||||
|
||||
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
|
||||
xImplSimd_InsertExtractHelper B;
|
||||
|
@ -200,7 +240,7 @@ struct SimdImpl_PExtract
|
|||
//
|
||||
void W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const;
|
||||
void W( const xRegister32& to, const xRegisterMMX& from, u8 imm8 ) const;
|
||||
void W( const ModSibBase& dest, const xRegisterSSE& from, u8 imm8 ) const;
|
||||
void W( const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8 ) const;
|
||||
|
||||
// [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits
|
||||
// of dest are zero-extended (cleared). This can be used to extract any single packed
|
||||
|
|
|
@ -28,7 +28,7 @@ struct xImpl_Test
|
|||
void operator()( const xRegister8& to, const xRegister8& from ) const;
|
||||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
void operator()( const ModSib32orLess& dest, int imm ) const;
|
||||
void operator()( const xIndirect32orLess& dest, int imm ) const;
|
||||
void operator()( const xRegisterInt& to, int imm ) const;
|
||||
};
|
||||
|
||||
|
@ -52,7 +52,7 @@ struct xImpl_BitScan
|
|||
|
||||
void operator()( const xRegister32& to, const xRegister32& from ) const;
|
||||
void operator()( const xRegister16& to, const xRegister16& from ) const;
|
||||
void operator()( const xRegister16or32& to, const ModSibBase& sibsrc ) const;
|
||||
void operator()( const xRegister16or32& to, const xIndirectVoid& sibsrc ) const;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -68,9 +68,9 @@ struct xImpl_Group8
|
|||
void operator()( const xRegister16& bitbase, const xRegister16& bitoffset ) const;
|
||||
void operator()( const xRegister16or32& bitbase, u8 bitoffset ) const;
|
||||
|
||||
void operator()( const ModSibBase& bitbase, const xRegister16or32& bitoffset ) const;
|
||||
void operator()( const ModSib32& bitbase, u8 bitoffset ) const;
|
||||
void operator()( const ModSib16& bitbase, u8 bitoffset ) const;
|
||||
void operator()( const xIndirectVoid& bitbase, const xRegister16or32& bitoffset ) const;
|
||||
void operator()( const xIndirect32& bitbase, u8 bitoffset ) const;
|
||||
void operator()( const xIndirect16& bitbase, u8 bitoffset ) const;
|
||||
};
|
||||
|
||||
} // End namespace x86Emitter
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
namespace x86Emitter
|
||||
{
|
||||
#if 0
|
||||
// --------------------------------------------------------------------------------------
|
||||
// x86Register Method Implementations (inlined!)
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -98,4 +99,5 @@ namespace x86Emitter
|
|||
pxAssertMsg( Id != -1, "Uninitialized x86 register." );
|
||||
return xAddressInfo( xEmptyReg, *this, 1<<shift );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -129,15 +129,15 @@ namespace x86Emitter
|
|||
// forms are functionally equivalent to Mov reg,imm, and thus better written as MOVs
|
||||
// instead.
|
||||
|
||||
extern void xLEA( xRegister32 to, const ModSibBase& src, bool preserve_flags=false );
|
||||
extern void xLEA( xRegister16 to, const ModSibBase& src, bool preserve_flags=false );
|
||||
extern void xLEA( xRegister32 to, const xIndirectVoid& src, bool preserve_flags=false );
|
||||
extern void xLEA( xRegister16 to, const xIndirectVoid& src, bool preserve_flags=false );
|
||||
|
||||
// ----- Push / Pop Instructions -----
|
||||
// Note: pushad/popad implementations are intentionally left out. The instructions are
|
||||
// invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead.
|
||||
|
||||
extern void xPOP( const ModSibBase& from );
|
||||
extern void xPUSH( const ModSibBase& from );
|
||||
extern void xPOP( const xIndirectVoid& from );
|
||||
extern void xPUSH( const xIndirectVoid& from );
|
||||
|
||||
extern void xPOP( xRegister32 from );
|
||||
|
||||
|
@ -305,48 +305,48 @@ namespace x86Emitter
|
|||
// ------------------------------------------------------------------------
|
||||
|
||||
extern void xEMMS();
|
||||
extern void xSTMXCSR( const ModSib32& dest );
|
||||
extern void xLDMXCSR( const ModSib32& src );
|
||||
extern void xFXSAVE( const ModSibBase& dest );
|
||||
extern void xFXRSTOR( const ModSibBase& src );
|
||||
extern void xSTMXCSR( const xIndirect32& dest );
|
||||
extern void xLDMXCSR( const xIndirect32& src );
|
||||
extern void xFXSAVE( const xIndirectVoid& dest );
|
||||
extern void xFXRSTOR( const xIndirectVoid& src );
|
||||
|
||||
extern void xMOVDZX( const xRegisterSSE& to, const xRegister32& from );
|
||||
extern void xMOVDZX( const xRegisterSSE& to, const ModSibBase& src );
|
||||
extern void xMOVDZX( const xRegisterSSE& to, const xIndirectVoid& src );
|
||||
|
||||
extern void xMOVDZX( const xRegisterMMX& to, const xRegister32& from );
|
||||
extern void xMOVDZX( const xRegisterMMX& to, const ModSibBase& src );
|
||||
extern void xMOVDZX( const xRegisterMMX& to, const xIndirectVoid& src );
|
||||
|
||||
extern void xMOVD( const xRegister32& to, const xRegisterSSE& from );
|
||||
extern void xMOVD( const ModSibBase& dest, const xRegisterSSE& from );
|
||||
extern void xMOVD( const xIndirectVoid& dest, const xRegisterSSE& from );
|
||||
|
||||
extern void xMOVD( const xRegister32& to, const xRegisterMMX& from );
|
||||
extern void xMOVD( const ModSibBase& dest, const xRegisterMMX& from );
|
||||
extern void xMOVD( const xIndirectVoid& dest, const xRegisterMMX& from );
|
||||
|
||||
extern void xMOVQ( const xRegisterMMX& to, const xRegisterMMX& from );
|
||||
extern void xMOVQ( const xRegisterMMX& to, const xRegisterSSE& from );
|
||||
extern void xMOVQ( const xRegisterSSE& to, const xRegisterMMX& from );
|
||||
|
||||
extern void xMOVQ( const ModSibBase& dest, const xRegisterSSE& from );
|
||||
extern void xMOVQ( const ModSibBase& dest, const xRegisterMMX& from );
|
||||
extern void xMOVQ( const xRegisterMMX& to, const ModSibBase& src );
|
||||
extern void xMOVQ( const xIndirectVoid& dest, const xRegisterSSE& from );
|
||||
extern void xMOVQ( const xIndirectVoid& dest, const xRegisterMMX& from );
|
||||
extern void xMOVQ( const xRegisterMMX& to, const xIndirectVoid& src );
|
||||
|
||||
extern void xMOVQZX( const xRegisterSSE& to, const ModSibBase& src );
|
||||
extern void xMOVQZX( const xRegisterSSE& to, const xIndirectVoid& src );
|
||||
extern void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
|
||||
extern void xMOVSS( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xMOVSS( const ModSibBase& to, const xRegisterSSE& from );
|
||||
extern void xMOVSS( const xIndirectVoid& to, const xRegisterSSE& from );
|
||||
extern void xMOVSD( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xMOVSD( const ModSibBase& to, const xRegisterSSE& from );
|
||||
extern void xMOVSD( const xIndirectVoid& to, const xRegisterSSE& from );
|
||||
|
||||
extern void xMOVSSZX( const xRegisterSSE& to, const ModSibBase& from );
|
||||
extern void xMOVSDZX( const xRegisterSSE& to, const ModSibBase& from );
|
||||
extern void xMOVSSZX( const xRegisterSSE& to, const xIndirectVoid& from );
|
||||
extern void xMOVSDZX( const xRegisterSSE& to, const xIndirectVoid& from );
|
||||
|
||||
extern void xMOVNTDQA( const xRegisterSSE& to, const ModSibBase& from );
|
||||
extern void xMOVNTDQA( const ModSibBase& to, const xRegisterSSE& from );
|
||||
extern void xMOVNTDQA( const xRegisterSSE& to, const xIndirectVoid& from );
|
||||
extern void xMOVNTDQA( const xIndirectVoid& to, const xRegisterSSE& from );
|
||||
|
||||
extern void xMOVNTPD( const ModSibBase& to, const xRegisterSSE& from );
|
||||
extern void xMOVNTPS( const ModSibBase& to, const xRegisterSSE& from );
|
||||
extern void xMOVNTQ( const ModSibBase& to, const xRegisterMMX& from );
|
||||
extern void xMOVNTPD( const xIndirectVoid& to, const xRegisterSSE& from );
|
||||
extern void xMOVNTPS( const xIndirectVoid& to, const xRegisterSSE& from );
|
||||
extern void xMOVNTQ( const xIndirectVoid& to, const xRegisterMMX& from );
|
||||
|
||||
extern void xMOVMSKPS( const xRegister32& to, const xRegisterSSE& from );
|
||||
extern void xMOVMSKPD( const xRegister32& to, const xRegisterSSE& from );
|
||||
|
@ -386,10 +386,10 @@ namespace x86Emitter
|
|||
extern const xImplSimd_DestRegSSE xMOVSHDUP;
|
||||
|
||||
extern void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
|
||||
extern void xINSERTPS( const xRegisterSSE& to, const ModSib32& from, u8 imm8 );
|
||||
extern void xINSERTPS( const xRegisterSSE& to, const xIndirect32& from, u8 imm8 );
|
||||
|
||||
extern void xEXTRACTPS( const xRegister32& to, const xRegisterSSE& from, u8 imm8 );
|
||||
extern void xEXTRACTPS( const ModSib32& dest, const xRegisterSSE& from, u8 imm8 );
|
||||
extern void xEXTRACTPS( const xIndirect32& dest, const xRegisterSSE& from, u8 imm8 );
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
@ -423,56 +423,56 @@ namespace x86Emitter
|
|||
//
|
||||
//
|
||||
extern void xCVTDQ2PD( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTDQ2PD( const xRegisterSSE& to, const ModSib64& from );
|
||||
extern void xCVTDQ2PD( const xRegisterSSE& to, const xIndirect64& from );
|
||||
extern void xCVTDQ2PS( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTDQ2PS( const xRegisterSSE& to, const ModSib128& from );
|
||||
extern void xCVTDQ2PS( const xRegisterSSE& to, const xIndirect128& from );
|
||||
|
||||
extern void xCVTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTPD2DQ( const xRegisterSSE& to, const ModSib128& from );
|
||||
extern void xCVTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
||||
extern void xCVTPD2PI( const xRegisterMMX& to, const xRegisterSSE& from );
|
||||
extern void xCVTPD2PI( const xRegisterMMX& to, const ModSib128& from );
|
||||
extern void xCVTPD2PI( const xRegisterMMX& to, const xIndirect128& from );
|
||||
extern void xCVTPD2PS( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTPD2PS( const xRegisterSSE& to, const ModSib128& from );
|
||||
extern void xCVTPD2PS( const xRegisterSSE& to, const xIndirect128& from );
|
||||
|
||||
extern void xCVTPI2PD( const xRegisterSSE& to, const xRegisterMMX& from );
|
||||
extern void xCVTPI2PD( const xRegisterSSE& to, const ModSib64& from );
|
||||
extern void xCVTPI2PD( const xRegisterSSE& to, const xIndirect64& from );
|
||||
extern void xCVTPI2PS( const xRegisterSSE& to, const xRegisterMMX& from );
|
||||
extern void xCVTPI2PS( const xRegisterSSE& to, const ModSib64& from );
|
||||
extern void xCVTPI2PS( const xRegisterSSE& to, const xIndirect64& from );
|
||||
|
||||
extern void xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTPS2DQ( const xRegisterSSE& to, const ModSib128& from );
|
||||
extern void xCVTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
||||
extern void xCVTPS2PD( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTPS2PD( const xRegisterSSE& to, const ModSib64& from );
|
||||
extern void xCVTPS2PD( const xRegisterSSE& to, const xIndirect64& from );
|
||||
extern void xCVTPS2PI( const xRegisterMMX& to, const xRegisterSSE& from );
|
||||
extern void xCVTPS2PI( const xRegisterMMX& to, const ModSib64& from );
|
||||
extern void xCVTPS2PI( const xRegisterMMX& to, const xIndirect64& from );
|
||||
|
||||
extern void xCVTSD2SI( const xRegister32& to, const xRegisterSSE& from );
|
||||
extern void xCVTSD2SI( const xRegister32& to, const ModSib64& from );
|
||||
extern void xCVTSD2SI( const xRegister32& to, const xIndirect64& from );
|
||||
extern void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTSD2SS( const xRegisterSSE& to, const ModSib64& from );
|
||||
extern void xCVTSD2SS( const xRegisterSSE& to, const xIndirect64& from );
|
||||
extern void xCVTSI2SD( const xRegisterMMX& to, const xRegister32& from );
|
||||
extern void xCVTSI2SD( const xRegisterMMX& to, const ModSib32& from );
|
||||
extern void xCVTSI2SD( const xRegisterMMX& to, const xIndirect32& from );
|
||||
extern void xCVTSI2SS( const xRegisterSSE& to, const xRegister32& from );
|
||||
extern void xCVTSI2SS( const xRegisterSSE& to, const ModSib32& from );
|
||||
extern void xCVTSI2SS( const xRegisterSSE& to, const xIndirect32& from );
|
||||
|
||||
extern void xCVTSS2SD( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTSS2SD( const xRegisterSSE& to, const ModSib32& from );
|
||||
extern void xCVTSS2SD( const xRegisterSSE& to, const xIndirect32& from );
|
||||
extern void xCVTSS2SI( const xRegister32& to, const xRegisterSSE& from );
|
||||
extern void xCVTSS2SI( const xRegister32& to, const ModSib32& from );
|
||||
extern void xCVTSS2SI( const xRegister32& to, const xIndirect32& from );
|
||||
|
||||
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTTPD2DQ( const xRegisterSSE& to, const ModSib128& from );
|
||||
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
||||
extern void xCVTTPD2PI( const xRegisterMMX& to, const xRegisterSSE& from );
|
||||
extern void xCVTTPD2PI( const xRegisterMMX& to, const ModSib128& from );
|
||||
extern void xCVTTPD2PI( const xRegisterMMX& to, const xIndirect128& from );
|
||||
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xCVTTPS2DQ( const xRegisterSSE& to, const ModSib128& from );
|
||||
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
|
||||
extern void xCVTTPS2PI( const xRegisterMMX& to, const xRegisterSSE& from );
|
||||
extern void xCVTTPS2PI( const xRegisterMMX& to, const ModSib64& from );
|
||||
extern void xCVTTPS2PI( const xRegisterMMX& to, const xIndirect64& from );
|
||||
|
||||
extern void xCVTTSD2SI( const xRegister32& to, const xRegisterSSE& from );
|
||||
extern void xCVTTSD2SI( const xRegister32& to, const ModSib64& from );
|
||||
extern void xCVTTSD2SI( const xRegister32& to, const xIndirect64& from );
|
||||
extern void xCVTTSS2SI( const xRegister32& to, const xRegisterSSE& from );
|
||||
extern void xCVTTSS2SI( const xRegister32& to, const ModSib32& from );
|
||||
extern void xCVTTSS2SI( const xRegister32& to, const xIndirect32& from );
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -18,58 +18,58 @@
|
|||
#include "x86types.h"
|
||||
#include "instructions.h"
|
||||
|
||||
#define OpWriteSSE( pre, op ) xOpWrite0F( pre, op, to, from )
|
||||
|
||||
namespace x86Emitter {
|
||||
|
||||
extern void SimdPrefix( u8 prefix, u16 opcode );
|
||||
extern void EmitSibMagic( uint regfield, const void* address );
|
||||
extern void EmitSibMagic( uint regfield, const ModSibBase& info );
|
||||
extern void EmitSibMagic( uint reg1, const xRegisterBase& reg2 );
|
||||
extern void EmitSibMagic( const xRegisterBase& reg1, const xRegisterBase& reg2 );
|
||||
extern void EmitSibMagic( const xRegisterBase& reg1, const void* src );
|
||||
extern void EmitSibMagic( const xRegisterBase& reg1, const ModSibBase& sib );
|
||||
#define OpWriteSSE( pre, op ) xOpWrite0F( pre, op, to, from )
|
||||
|
||||
extern void _xMovRtoR( const xRegisterInt& to, const xRegisterInt& from );
|
||||
extern void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xRegisterInt& from );
|
||||
extern void SimdPrefix( u8 prefix, u16 opcode );
|
||||
extern void EmitSibMagic( uint regfield, const void* address );
|
||||
extern void EmitSibMagic( uint regfield, const xIndirectVoid& info );
|
||||
extern void EmitSibMagic( uint reg1, const xRegisterBase& reg2 );
|
||||
extern void EmitSibMagic( const xRegisterBase& reg1, const xRegisterBase& reg2 );
|
||||
extern void EmitSibMagic( const xRegisterBase& reg1, const void* src );
|
||||
extern void EmitSibMagic( const xRegisterBase& reg1, const xIndirectVoid& sib );
|
||||
|
||||
template< typename T > inline
|
||||
void xWrite( T val )
|
||||
{
|
||||
*(T*)x86Ptr = val;
|
||||
x86Ptr += sizeof(T);
|
||||
}
|
||||
extern void _xMovRtoR( const xRegisterInt& to, const xRegisterInt& from );
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
if( prefix != 0 )
|
||||
xWrite16( (opcode<<8) | prefix );
|
||||
else
|
||||
xWrite8( opcode );
|
||||
template< typename T > inline
|
||||
void xWrite( T val )
|
||||
{
|
||||
*(T*)x86Ptr = val;
|
||||
x86Ptr += sizeof(T);
|
||||
}
|
||||
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
if( prefix != 0 )
|
||||
xWrite16( (opcode<<8) | prefix );
|
||||
else
|
||||
xWrite8( opcode );
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
SimdPrefix( prefix, opcode );
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8 )
|
||||
{
|
||||
xOpWrite0F( prefix, opcode, param1, param2 );
|
||||
xWrite8( imm8 );
|
||||
}
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
SimdPrefix( prefix, opcode );
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2 ) { xOpWrite0F( 0, opcode, param1, param2 ); }
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8 )
|
||||
{
|
||||
xOpWrite0F( prefix, opcode, param1, param2 );
|
||||
xWrite8( imm8 );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) { xOpWrite0F( 0, opcode, param1, param2, imm8 ); }
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2 ) { xOpWrite0F( 0, opcode, param1, param2 ); }
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) { xOpWrite0F( 0, opcode, param1, param2, imm8 ); }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ union SSE_MXCSR
|
|||
return bitmask != right.bitmask;
|
||||
}
|
||||
|
||||
operator x86Emitter::ModSib32() const;
|
||||
operator x86Emitter::xIndirect32() const;
|
||||
};
|
||||
|
||||
extern SSE_MXCSR MXCSR_Mask;
|
||||
|
|
|
@ -183,9 +183,6 @@ template< typename T > void xWrite( T val );
|
|||
static const int ModRm_UseSib = 4; // same index value as ESP (used in RM field)
|
||||
static const int ModRm_UseDisp32 = 5; // same index value as EBP (used in Mod field)
|
||||
|
||||
class xAddressInfo;
|
||||
class ModSibBase;
|
||||
|
||||
extern void xSetPtr( void* ptr );
|
||||
extern void xAlignPtr( uint bytes );
|
||||
extern void xAdvancePtr( uint bytes );
|
||||
|
@ -196,6 +193,8 @@ template< typename T > void xWrite( T val );
|
|||
|
||||
extern JccComparisonType xInvertCond( JccComparisonType src );
|
||||
|
||||
class xAddressVoid;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// OperandSizedObject
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -404,16 +403,13 @@ template< typename T > void xWrite( T val );
|
|||
// Returns true if the register is the stack pointer: ESP.
|
||||
bool IsStackPointer() const { return Id == 4; }
|
||||
|
||||
inline xAddressInfo operator+( const xAddressReg& right ) const;
|
||||
inline xAddressInfo operator+( const xAddressInfo& right ) const;
|
||||
inline xAddressInfo operator+( s32 right ) const;
|
||||
inline xAddressInfo operator+( const void* right ) const;
|
||||
|
||||
inline xAddressInfo operator-( s32 right ) const;
|
||||
inline xAddressInfo operator-( const void* right ) const;
|
||||
|
||||
inline xAddressInfo operator*( u32 factor ) const;
|
||||
inline xAddressInfo operator<<( u32 shift ) const;
|
||||
xAddressVoid operator+( const xAddressReg& right ) const;
|
||||
xAddressVoid operator+( s32 right ) const;
|
||||
xAddressVoid operator+( const void* right ) const;
|
||||
xAddressVoid operator-( s32 right ) const;
|
||||
xAddressVoid operator-( const void* right ) const;
|
||||
xAddressVoid operator*( u32 factor ) const;
|
||||
xAddressVoid operator<<( u32 shift ) const;
|
||||
|
||||
/*xAddressReg& operator=( const xRegister32& src )
|
||||
{
|
||||
|
@ -472,73 +468,6 @@ template< typename T > void xWrite( T val );
|
|||
|
||||
extern const xRegisterEmpty xEmptyReg;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xAddressInfo
|
||||
// --------------------------------------------------------------------------------------
|
||||
class xAddressInfo
|
||||
{
|
||||
public:
|
||||
xAddressReg Base; // base register (no scale)
|
||||
xAddressReg Index; // index reg gets multiplied by the scale
|
||||
int Factor; // scale applied to the index register, in factor form (not a shift!)
|
||||
s32 Displacement; // address displacement
|
||||
|
||||
public:
|
||||
__forceinline xAddressInfo( const xAddressReg& base, const xAddressReg& index, int factor=1, s32 displacement=0 )
|
||||
{
|
||||
Base = base;
|
||||
Index = index;
|
||||
Factor = factor;
|
||||
Displacement= displacement;
|
||||
|
||||
pxAssertMsg( base.Id != xRegId_Invalid, "Uninitialized x86 register." );
|
||||
pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." );
|
||||
}
|
||||
|
||||
__forceinline explicit xAddressInfo( const xAddressReg& index, int displacement=0 )
|
||||
{
|
||||
Base = xEmptyReg;
|
||||
Index = index;
|
||||
Factor = 0;
|
||||
Displacement= displacement;
|
||||
|
||||
pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." );
|
||||
}
|
||||
|
||||
__forceinline explicit xAddressInfo( s32 displacement=0 )
|
||||
{
|
||||
Base = xEmptyReg;
|
||||
Index = xEmptyReg;
|
||||
Factor = 0;
|
||||
Displacement= displacement;
|
||||
}
|
||||
|
||||
static xAddressInfo FromIndexReg( const xAddressReg& index, int scale=0, s32 displacement=0 );
|
||||
|
||||
public:
|
||||
bool IsByteSizeDisp() const { return is_s8( Displacement ); }
|
||||
|
||||
__forceinline xAddressInfo& Add( s32 imm )
|
||||
{
|
||||
Displacement += imm;
|
||||
return *this;
|
||||
}
|
||||
|
||||
xAddressInfo& Add( const xAddressReg& src );
|
||||
xAddressInfo& Add( const xAddressInfo& src );
|
||||
|
||||
__forceinline xAddressInfo operator+( const xAddressReg& right ) const { return xAddressInfo( *this ).Add( right ); }
|
||||
__forceinline xAddressInfo operator+( const xAddressInfo& right ) const { return xAddressInfo( *this ).Add( right ); }
|
||||
__forceinline xAddressInfo operator+( s32 imm ) const { return xAddressInfo( *this ).Add( imm ); }
|
||||
__forceinline xAddressInfo operator-( s32 imm ) const { return xAddressInfo( *this ).Add( -imm ); }
|
||||
__forceinline xAddressInfo operator+( const void* addr ) const { return xAddressInfo( *this ).Add( (uptr)addr ); }
|
||||
|
||||
__forceinline void operator+=( const xAddressReg& right ) { Add( right ); }
|
||||
__forceinline void operator+=( const xAddressInfo& right ) { Add( right ); }
|
||||
__forceinline void operator+=( s32 imm ) { Add( imm ); }
|
||||
__forceinline void operator-=( s32 imm ) { Add( -imm ); }
|
||||
};
|
||||
|
||||
extern const xRegisterSSE
|
||||
xmm0, xmm1, xmm2, xmm3,
|
||||
xmm4, xmm5, xmm6, xmm7;
|
||||
|
@ -561,6 +490,124 @@ template< typename T > void xWrite( T val );
|
|||
|
||||
extern const xRegisterCL cl; // I'm special!
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xAddressVoid
|
||||
// --------------------------------------------------------------------------------------
|
||||
class xAddressVoid
|
||||
{
|
||||
public:
|
||||
xAddressReg Base; // base register (no scale)
|
||||
xAddressReg Index; // index reg gets multiplied by the scale
|
||||
int Factor; // scale applied to the index register, in factor form (not a shift!)
|
||||
s32 Displacement; // address displacement
|
||||
|
||||
public:
|
||||
xAddressVoid( const xAddressReg& base, const xAddressReg& index, int factor=1, s32 displacement=0 );
|
||||
|
||||
xAddressVoid( const xAddressReg& index, int displacement=0 );
|
||||
explicit xAddressVoid( const void* displacement );
|
||||
explicit xAddressVoid( s32 displacement=0 );
|
||||
|
||||
public:
|
||||
bool IsByteSizeDisp() const { return is_s8( Displacement ); }
|
||||
|
||||
xAddressVoid& Add( s32 imm )
|
||||
{
|
||||
Displacement += imm;
|
||||
return *this;
|
||||
}
|
||||
|
||||
xAddressVoid& Add( const xAddressReg& src );
|
||||
xAddressVoid& Add( const xAddressVoid& src );
|
||||
|
||||
__forceinline xAddressVoid operator+( const xAddressReg& right ) const { return xAddressVoid( *this ).Add( right ); }
|
||||
__forceinline xAddressVoid operator+( const xAddressVoid& right ) const { return xAddressVoid( *this ).Add( right ); }
|
||||
__forceinline xAddressVoid operator+( s32 imm ) const { return xAddressVoid( *this ).Add( imm ); }
|
||||
__forceinline xAddressVoid operator-( s32 imm ) const { return xAddressVoid( *this ).Add( -imm ); }
|
||||
__forceinline xAddressVoid operator+( const void* addr ) const { return xAddressVoid( *this ).Add( (uptr)addr ); }
|
||||
|
||||
__forceinline void operator+=( const xAddressReg& right ) { Add( right ); }
|
||||
__forceinline void operator+=( s32 imm ) { Add( imm ); }
|
||||
__forceinline void operator-=( s32 imm ) { Add( -imm ); }
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xAddressInfo
|
||||
// --------------------------------------------------------------------------------------
|
||||
template< typename BaseType >
|
||||
class xAddressInfo : public xAddressVoid
|
||||
{
|
||||
typedef xAddressVoid _parent;
|
||||
|
||||
public:
|
||||
xAddressInfo( const xAddressReg& base, const xAddressReg& index, int factor=1, s32 displacement=0 )
|
||||
: _parent( base, index, factor, displacement ) {}
|
||||
|
||||
/*xAddressInfo( const xAddressVoid& src )
|
||||
: _parent( src ) {}*/
|
||||
|
||||
explicit xAddressInfo( const xAddressReg& index, int displacement=0 )
|
||||
: _parent( index, displacement ) {}
|
||||
|
||||
explicit xAddressInfo( s32 displacement=0 )
|
||||
: _parent( displacement ) {}
|
||||
|
||||
static xAddressInfo<BaseType> FromIndexReg( const xAddressReg& index, int scale=0, s32 displacement=0 );
|
||||
|
||||
public:
|
||||
using _parent::operator+=;
|
||||
using _parent::operator-=;
|
||||
|
||||
bool IsByteSizeDisp() const { return is_s8( Displacement ); }
|
||||
|
||||
xAddressInfo<BaseType>& Add( s32 imm )
|
||||
{
|
||||
Displacement += imm;
|
||||
return *this;
|
||||
}
|
||||
|
||||
xAddressInfo<BaseType>& Add( const xAddressReg& src ) { _parent::Add(src); return *this; }
|
||||
xAddressInfo<BaseType>& Add( const xAddressInfo<BaseType>& src ) { _parent::Add(src); return *this; }
|
||||
|
||||
__forceinline xAddressInfo<BaseType> operator+( const xAddressReg& right ) const { return xAddressInfo( *this ).Add( right ); }
|
||||
__forceinline xAddressInfo<BaseType> operator+( const xAddressInfo<BaseType>& right ) const { return xAddressInfo( *this ).Add( right ); }
|
||||
__forceinline xAddressInfo<BaseType> operator+( s32 imm ) const { return xAddressInfo( *this ).Add( imm ); }
|
||||
__forceinline xAddressInfo<BaseType> operator-( s32 imm ) const { return xAddressInfo( *this ).Add( -imm ); }
|
||||
__forceinline xAddressInfo<BaseType> operator+( const void* addr ) const { return xAddressInfo( *this ).Add( (uptr)addr ); }
|
||||
|
||||
__forceinline void operator+=( const xAddressInfo<BaseType>& right ) { Add( right ); }
|
||||
};
|
||||
|
||||
typedef xAddressInfo<u128> xAddress128;
|
||||
typedef xAddressInfo<u64> xAddress64;
|
||||
typedef xAddressInfo<u32> xAddress32;
|
||||
typedef xAddressInfo<u16> xAddress16;
|
||||
typedef xAddressInfo<u8> xAddress8;
|
||||
|
||||
static __forceinline xAddressVoid operator+( const void* addr, const xAddressVoid& right )
|
||||
{
|
||||
return right + addr;
|
||||
}
|
||||
|
||||
static __forceinline xAddressVoid operator+( s32 addr, const xAddressVoid& right )
|
||||
{
|
||||
return right + addr;
|
||||
}
|
||||
|
||||
template< typename OperandType >
|
||||
static __forceinline xAddressInfo<OperandType> operator+( const void* addr, const xAddressInfo<OperandType>& right )
|
||||
{
|
||||
//return xAddressInfo<OperandType>( (sptr)addr ).Add( reg );
|
||||
return right + addr;
|
||||
}
|
||||
|
||||
template< typename OperandType >
|
||||
static __forceinline xAddressInfo<OperandType> operator+( s32 addr, const xAddressInfo<OperandType>& right )
|
||||
{
|
||||
return right + addr;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xImmReg< typename xRegType >
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -596,7 +643,7 @@ template< typename T > void xWrite( T val );
|
|||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ModSib - Internal low-level representation of the ModRM/SIB information.
|
||||
// xIndirectVoid - Internal low-level representation of the ModRM/SIB information.
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This class serves two purposes: It houses 'reduced' ModRM/SIB info only, which means
|
||||
// that the Base, Index, Scale, and Displacement values are all in the correct arrange-
|
||||
|
@ -607,7 +654,7 @@ template< typename T > void xWrite( T val );
|
|||
//
|
||||
// End users should always use xAddressInfo instead.
|
||||
//
|
||||
class ModSibBase : public OperandSizedObject
|
||||
class xIndirectVoid : public OperandSizedObject
|
||||
{
|
||||
public:
|
||||
xAddressReg Base; // base register (no scale)
|
||||
|
@ -616,88 +663,101 @@ template< typename T > void xWrite( T val );
|
|||
s32 Displacement; // offset applied to the Base/Index registers.
|
||||
|
||||
public:
|
||||
explicit ModSibBase( const xAddressInfo& src );
|
||||
explicit ModSibBase( s32 disp );
|
||||
ModSibBase( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 );
|
||||
explicit xIndirectVoid( s32 disp );
|
||||
explicit xIndirectVoid( const xAddressVoid& src );
|
||||
xIndirectVoid( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 );
|
||||
|
||||
virtual uint GetOperandSize() const;
|
||||
ModSibBase& Add( s32 imm );
|
||||
xIndirectVoid& Add( s32 imm );
|
||||
|
||||
bool IsByteSizeDisp() const { return is_s8( Displacement ); }
|
||||
|
||||
__forceinline ModSibBase operator+( const s32 imm ) const { return ModSibBase( *this ).Add( imm ); }
|
||||
__forceinline ModSibBase operator-( const s32 imm ) const { return ModSibBase( *this ).Add( -imm ); }
|
||||
operator xAddressVoid()
|
||||
{
|
||||
return xAddressVoid( Base, Index, Scale, Displacement );
|
||||
}
|
||||
|
||||
__forceinline xIndirectVoid operator+( const s32 imm ) const { return xIndirectVoid( *this ).Add( imm ); }
|
||||
__forceinline xIndirectVoid operator-( const s32 imm ) const { return xIndirectVoid( *this ).Add( -imm ); }
|
||||
|
||||
protected:
|
||||
void Reduce();
|
||||
};
|
||||
|
||||
template< typename OperandType >
|
||||
class xIndirect : public xIndirectVoid
|
||||
{
|
||||
typedef xIndirectVoid _parent;
|
||||
|
||||
public:
|
||||
explicit xIndirect( s32 disp ) : _parent( disp ) {}
|
||||
explicit xIndirect( const xAddressInfo<OperandType>& src ) : _parent( src ) {}
|
||||
xIndirect( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 )
|
||||
: _parent( base, index, scale, displacement ) {}
|
||||
|
||||
virtual uint GetOperandSize() const { return sizeof(OperandType); }
|
||||
|
||||
xIndirect<OperandType>& Add( s32 imm )
|
||||
{
|
||||
Displacement += imm;
|
||||
return *this;
|
||||
}
|
||||
|
||||
__forceinline xIndirect<OperandType> operator+( const s32 imm ) const { return xIndirect( *this ).Add( imm ); }
|
||||
__forceinline xIndirect<OperandType> operator-( const s32 imm ) const { return xIndirect( *this ).Add( -imm ); }
|
||||
|
||||
bool operator==( const xIndirect<OperandType>& src ) const
|
||||
{
|
||||
return
|
||||
( Base == src.Base ) && ( Index == src.Index ) &&
|
||||
( Scale == src.Scale ) && ( Displacement == src.Displacement );
|
||||
}
|
||||
|
||||
bool operator!=( const xIndirect<OperandType>& src ) const
|
||||
{
|
||||
return !operator==( src );
|
||||
}
|
||||
|
||||
protected:
|
||||
void Reduce();
|
||||
};
|
||||
|
||||
typedef xIndirect<u128> xIndirect128;
|
||||
typedef xIndirect<u64> xIndirect64;
|
||||
typedef xIndirect<u32> xIndirect32;
|
||||
typedef xIndirect<u16> xIndirect16;
|
||||
typedef xIndirect<u8> xIndirect8;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ModSib32rrLass - base class 32, 16, and 8 bit operand types
|
||||
// xIndirect32orLass - base class 32, 16, and 8 bit operand types
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ModSib32orLess : public ModSibBase
|
||||
class xIndirect32orLess : public xIndirectVoid
|
||||
{
|
||||
typedef ModSibBase _parent;
|
||||
typedef xIndirectVoid _parent;
|
||||
|
||||
protected:
|
||||
explicit ModSib32orLess( const xAddressInfo& src ) : _parent( src ) {}
|
||||
explicit ModSib32orLess( s32 disp ) : _parent( disp ) {}
|
||||
ModSib32orLess( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) :
|
||||
uint m_OpSize;
|
||||
|
||||
public:
|
||||
xIndirect32orLess( const xIndirect8& src ) : _parent( src ) { m_OpSize = src.GetOperandSize(); }
|
||||
xIndirect32orLess( const xIndirect16& src ) : _parent( src ) { m_OpSize = src.GetOperandSize(); }
|
||||
xIndirect32orLess( const xIndirect32& src ) : _parent( src ) { m_OpSize = src.GetOperandSize(); }
|
||||
|
||||
uint GetOperandSize() const { return m_OpSize; }
|
||||
|
||||
protected:
|
||||
//xIndirect32orLess( const xAddressVoid& src ) : _parent( src ) {}
|
||||
|
||||
explicit xIndirect32orLess( s32 disp ) : _parent( disp ) {}
|
||||
xIndirect32orLess( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) :
|
||||
_parent( base, index, scale, displacement ) {}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ModSib8/16/32/64/128
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Strictly-typed version of ModSibBase, which is used to apply operand size information
|
||||
// to operations that do not involve an implicit operand size via register (such as
|
||||
// imm,mem or mem,imm)
|
||||
//
|
||||
#define DECLARE_CLASS_ModSibBits( bits, baseClass ) \
|
||||
class ModSib##bits : public baseClass \
|
||||
{ \
|
||||
typedef baseClass _parent; \
|
||||
public: \
|
||||
explicit ModSib##bits( const xAddressInfo& src ) : _parent( src ) {} \
|
||||
explicit ModSib##bits( s32 disp ) : _parent( disp ) {} \
|
||||
ModSib##bits( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) \
|
||||
: _parent( base, index, scale, displacement ) {} \
|
||||
\
|
||||
virtual uint GetOperandSize() const { return bits / 8; } \
|
||||
\
|
||||
__forceinline ModSib##bits& Add( s32 imm ) \
|
||||
{ \
|
||||
Displacement += imm; \
|
||||
return *this; \
|
||||
} \
|
||||
\
|
||||
__forceinline ModSib##bits operator+( const s32 imm ) const { return ModSib##bits( *this ).Add( imm ); } \
|
||||
__forceinline ModSib##bits operator-( const s32 imm ) const { return ModSib##bits( *this ).Add( -imm ); } \
|
||||
\
|
||||
bool operator==( const ModSib##bits& src ) const \
|
||||
{ \
|
||||
return \
|
||||
( Base == src.Base ) && ( Index == src.Index ) && \
|
||||
( Scale == src.Scale ) && ( Displacement == src.Displacement ); \
|
||||
} \
|
||||
\
|
||||
bool operator!=( const ModSib##bits& src ) const \
|
||||
{ \
|
||||
return !operator==( src ); \
|
||||
} \
|
||||
}
|
||||
|
||||
DECLARE_CLASS_ModSibBits( 8, ModSib32orLess );
|
||||
DECLARE_CLASS_ModSibBits( 16, ModSib32orLess );
|
||||
DECLARE_CLASS_ModSibBits( 32, ModSib32orLess );
|
||||
DECLARE_CLASS_ModSibBits( 64, ModSibBase );
|
||||
DECLARE_CLASS_ModSibBits( 128, ModSibBase );
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xAddressIndexer
|
||||
// --------------------------------------------------------------------------------------
|
||||
// This is a type-translation "interface class" which provisions our ptr[] syntax.
|
||||
// xAddressReg types go in, and ModSibBase derived types come out.
|
||||
// xAddressReg types go in, and xIndirectVoid derived types come out.
|
||||
//
|
||||
template< typename xModSibType >
|
||||
class xAddressIndexer
|
||||
|
@ -707,14 +767,14 @@ template< typename T > void xWrite( T val );
|
|||
// without doing anything and without compiler error.
|
||||
const xModSibType& operator[]( const xModSibType& src ) const { return src; }
|
||||
|
||||
xModSibType operator[]( xAddressReg src ) const
|
||||
xModSibType operator[]( const xAddressReg& src ) const
|
||||
{
|
||||
return xModSibType( src, xEmptyReg );
|
||||
}
|
||||
|
||||
xModSibType operator[]( const xAddressInfo& src ) const
|
||||
xModSibType operator[]( const xAddressVoid& src ) const
|
||||
{
|
||||
return xModSibType( src );
|
||||
return xModSibType( src.Base, src.Index, src.Factor, src.Displacement );
|
||||
}
|
||||
|
||||
xModSibType operator[]( const void* src ) const
|
||||
|
@ -725,12 +785,12 @@ template< typename T > void xWrite( T val );
|
|||
|
||||
// ptr[] - use this form for instructions which can resolve the address operand size from
|
||||
// the other register operand sizes.
|
||||
extern const xAddressIndexer<ModSibBase> ptr;
|
||||
extern const xAddressIndexer<ModSib128> ptr128;
|
||||
extern const xAddressIndexer<ModSib64> ptr64;
|
||||
extern const xAddressIndexer<ModSib32> ptr32;
|
||||
extern const xAddressIndexer<ModSib16> ptr16;
|
||||
extern const xAddressIndexer<ModSib8> ptr8;
|
||||
extern const xAddressIndexer<xIndirectVoid> ptr;
|
||||
extern const xAddressIndexer<xIndirect128> ptr128;
|
||||
extern const xAddressIndexer<xIndirect64> ptr64;
|
||||
extern const xAddressIndexer<xIndirect32> ptr32;
|
||||
extern const xAddressIndexer<xIndirect16> ptr16;
|
||||
extern const xAddressIndexer<xIndirect8> ptr8;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xDirectOrIndirect
|
||||
|
@ -777,11 +837,11 @@ template< typename T > void xWrite( T val );
|
|||
bool operator!=( const xRegType& src ) const { return (m_RegDirect != src); }
|
||||
};
|
||||
|
||||
typedef xDirectOrIndirect<xRegister8,ModSib8> xDirectOrIndirect8;
|
||||
typedef xDirectOrIndirect<xRegister16,ModSib16> xDirectOrIndirect16;
|
||||
typedef xDirectOrIndirect<xRegister32,ModSib32> xDirectOrIndirect32;
|
||||
typedef xDirectOrIndirect<xRegisterMMX,ModSib64> xDirectOrIndirect64;
|
||||
typedef xDirectOrIndirect<xRegisterSSE,ModSib128> xDirectOrIndirect128;
|
||||
typedef xDirectOrIndirect<xRegister8,xIndirect8> xDirectOrIndirect8;
|
||||
typedef xDirectOrIndirect<xRegister16,xIndirect16> xDirectOrIndirect16;
|
||||
typedef xDirectOrIndirect<xRegister32,xIndirect32> xDirectOrIndirect32;
|
||||
typedef xDirectOrIndirect<xRegisterMMX,xIndirect64> xDirectOrIndirect64;
|
||||
typedef xDirectOrIndirect<xRegisterSSE,xIndirect128> xDirectOrIndirect128;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -889,24 +949,14 @@ template< typename T > void xWrite( T val );
|
|||
}
|
||||
};
|
||||
|
||||
static __forceinline xAddressInfo operator+( const void* addr, const xAddressReg& reg )
|
||||
static __forceinline xAddressVoid operator+( const void* addr, const xAddressReg& reg )
|
||||
{
|
||||
return xAddressInfo( reg, (sptr)addr );
|
||||
return reg + (sptr)addr;
|
||||
}
|
||||
|
||||
static __forceinline xAddressInfo operator+( const void* addr, const xAddressInfo& reg )
|
||||
static __forceinline xAddressVoid operator+( s32 addr, const xAddressReg& reg )
|
||||
{
|
||||
return xAddressInfo( (sptr)addr ).Add( reg );
|
||||
}
|
||||
|
||||
static __forceinline xAddressInfo operator+( s32 addr, const xAddressReg& reg )
|
||||
{
|
||||
return xAddressInfo( reg, (sptr)addr );
|
||||
}
|
||||
|
||||
static __forceinline xAddressInfo operator+( s32 addr, const xAddressInfo& reg )
|
||||
{
|
||||
return xAddressInfo( (sptr)addr ).Add( reg );
|
||||
return reg + (sptr)addr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace x86Emitter {
|
|||
// Note on "[Indirect],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).
|
||||
static void _g1_IndirectImm( G1Type InstType, const ModSib32orLess& sibdest, int imm )
|
||||
static void _g1_IndirectImm( G1Type InstType, const xIndirect32orLess& sibdest, int imm )
|
||||
{
|
||||
if( sibdest.Is8BitOp() )
|
||||
{
|
||||
|
@ -69,14 +69,14 @@ void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xRegisterInt& fr
|
|||
EmitSibMagic( from, to );
|
||||
}
|
||||
|
||||
static void _g1_EmitOp( G1Type InstType, const ModSibBase& sibdest, const xRegisterInt& from )
|
||||
static void _g1_EmitOp( G1Type InstType, const xIndirectVoid& sibdest, const xRegisterInt& from )
|
||||
{
|
||||
from.prefix16();
|
||||
xWrite8( (from.Is8BitOp() ? 0 : 1) | (InstType<<3) );
|
||||
EmitSibMagic( from, sibdest );
|
||||
}
|
||||
|
||||
static void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const ModSibBase& sibsrc )
|
||||
static void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xIndirectVoid& sibsrc )
|
||||
{
|
||||
to.prefix16();
|
||||
xWrite8( (to.Is8BitOp() ? 2 : 3) | (InstType<<3) );
|
||||
|
@ -109,10 +109,10 @@ static void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, int imm )
|
|||
void g1type::operator()( const xRegister8& to, const xRegister8& from ) const { _g1_EmitOp( insttype, to, from ); } \
|
||||
void g1type::operator()( const xRegister16& to, const xRegister16& from ) const { _g1_EmitOp( insttype, to, from ); } \
|
||||
void g1type::operator()( const xRegister32& to, const xRegister32& from ) const { _g1_EmitOp( insttype, to, from ); } \
|
||||
void g1type::operator()( const ModSibBase& to, const xRegisterInt& from ) const { _g1_EmitOp( insttype, to, from ); } \
|
||||
void g1type::operator()( const xRegisterInt& to, const ModSibBase& from ) const { _g1_EmitOp( insttype, to, from ); } \
|
||||
void g1type::operator()( const xIndirectVoid& to, const xRegisterInt& from ) const { _g1_EmitOp( insttype, to, from ); } \
|
||||
void g1type::operator()( const xRegisterInt& to, const xIndirectVoid& from ) const { _g1_EmitOp( insttype, to, from ); } \
|
||||
void g1type::operator()( const xRegisterInt& to, int imm ) const { _g1_EmitOp( insttype, to, imm ); } \
|
||||
void g1type::operator()( const ModSib32orLess& sibdest, int imm ) const { _g1_IndirectImm( insttype, sibdest, imm ); }
|
||||
void g1type::operator()( const xIndirect32orLess& sibdest, int imm ) const { _g1_IndirectImm( insttype, sibdest, imm ); }
|
||||
|
||||
ImplementGroup1( xImpl_Group1, InstType )
|
||||
ImplementGroup1( xImpl_G1Logic, InstType )
|
||||
|
@ -160,14 +160,14 @@ void xImpl_Group2::operator()(const xRegisterInt& to, u8 imm ) const
|
|||
}
|
||||
}
|
||||
|
||||
void xImpl_Group2::operator()( const ModSib32orLess& sibdest, const xRegisterCL& /* from */ ) const
|
||||
void xImpl_Group2::operator()( const xIndirect32orLess& sibdest, const xRegisterCL& /* from */ ) const
|
||||
{
|
||||
sibdest.prefix16();
|
||||
xWrite8( sibdest.Is8BitOp() ? 0xd2 : 0xd3 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
}
|
||||
|
||||
void xImpl_Group2::operator()( const ModSib32orLess& sibdest, u8 imm ) const
|
||||
void xImpl_Group2::operator()( const xIndirect32orLess& sibdest, u8 imm ) const
|
||||
{
|
||||
if( imm == 0 ) return;
|
||||
|
||||
|
@ -206,7 +206,7 @@ static void _g3_EmitOp( G3Type InstType, const xRegisterInt& from )
|
|||
EmitSibMagic( InstType, from );
|
||||
}
|
||||
|
||||
static void _g3_EmitOp( G3Type InstType, const ModSib32orLess& from )
|
||||
static void _g3_EmitOp( G3Type InstType, const xIndirect32orLess& from )
|
||||
{
|
||||
from.prefix16();
|
||||
xWrite8( from.Is8BitOp() ? 0xf6 : 0xf7 );
|
||||
|
@ -214,10 +214,10 @@ static void _g3_EmitOp( G3Type InstType, const ModSib32orLess& from )
|
|||
}
|
||||
|
||||
void xImpl_Group3::operator()( const xRegisterInt& from ) const { _g3_EmitOp( InstType, from ); }
|
||||
void xImpl_Group3::operator()( const ModSib32orLess& from ) const { _g3_EmitOp( InstType, from ); }
|
||||
void xImpl_Group3::operator()( const xIndirect32orLess& from ) const { _g3_EmitOp( InstType, from ); }
|
||||
|
||||
void xImpl_iDiv::operator()( const xRegisterInt& from ) const { _g3_EmitOp( G3Type_iDIV, from ); }
|
||||
void xImpl_iDiv::operator()( const ModSib32orLess& from ) const { _g3_EmitOp( G3Type_iDIV, from ); }
|
||||
void xImpl_iDiv::operator()( const xIndirect32orLess& from ) const { _g3_EmitOp( G3Type_iDIV, from ); }
|
||||
|
||||
template< typename SrcType >
|
||||
static void _imul_ImmStyle( const xRegisterInt& param1, const SrcType& param2, int imm )
|
||||
|
@ -237,17 +237,17 @@ static void _imul_ImmStyle( const xRegisterInt& param1, const SrcType& param2, i
|
|||
}
|
||||
|
||||
void xImpl_iMul::operator()( const xRegisterInt& from ) const { _g3_EmitOp( G3Type_iMUL, from ); }
|
||||
void xImpl_iMul::operator()( const ModSib32orLess& from ) const { _g3_EmitOp( G3Type_iMUL, from ); }
|
||||
void xImpl_iMul::operator()( const xIndirect32orLess& from ) const { _g3_EmitOp( G3Type_iMUL, from ); }
|
||||
|
||||
void xImpl_iMul::operator()( const xRegister32& to, const xRegister32& from ) const { xOpWrite0F( 0xaf, to, from ); }
|
||||
void xImpl_iMul::operator()( const xRegister32& to, const ModSibBase& src ) const { xOpWrite0F( 0xaf, to, src ); }
|
||||
void xImpl_iMul::operator()( const xRegister32& to, const xIndirectVoid& src ) const { xOpWrite0F( 0xaf, to, src ); }
|
||||
void xImpl_iMul::operator()( const xRegister16& to, const xRegister16& from ) const { xOpWrite0F( 0x66, 0xaf, to, from ); }
|
||||
void xImpl_iMul::operator()( const xRegister16& to, const ModSibBase& src ) const { xOpWrite0F( 0x66, 0xaf, to, src ); }
|
||||
void xImpl_iMul::operator()( const xRegister16& to, const xIndirectVoid& src ) const { xOpWrite0F( 0x66, 0xaf, to, src ); }
|
||||
|
||||
void xImpl_iMul::operator()( const xRegister32& to, const xRegister32& from, s32 imm ) const{ _imul_ImmStyle( to, from, imm ); }
|
||||
void xImpl_iMul::operator()( const xRegister32& to, const ModSibBase& from, s32 imm ) const { _imul_ImmStyle( to, from, imm ); }
|
||||
void xImpl_iMul::operator()( const xRegister32& to, const xIndirectVoid& from, s32 imm ) const { _imul_ImmStyle( to, from, imm ); }
|
||||
void xImpl_iMul::operator()( const xRegister16& to, const xRegister16& from, s16 imm ) const{ _imul_ImmStyle( to, from, imm ); }
|
||||
void xImpl_iMul::operator()( const xRegister16& to, const ModSibBase& from, s16 imm ) const { _imul_ImmStyle( to, from, imm ); }
|
||||
void xImpl_iMul::operator()( const xRegister16& to, const xIndirectVoid& from, s16 imm ) const { _imul_ImmStyle( to, from, imm ); }
|
||||
|
||||
const xImpl_Group3 xNOT = { G3Type_NOT };
|
||||
const xImpl_Group3 xNEG = { G3Type_NEG };
|
||||
|
@ -263,15 +263,15 @@ const xImpl_iMul xMUL = { { 0x00, 0x59 }, { 0x66, 0x59 }, { 0xf3, 0x59 }, { 0xf2
|
|||
|
||||
void xImpl_Group8::operator()( const xRegister32& bitbase, const xRegister32& bitoffset ) const { xOpWrite0F( 0xa3 | (InstType << 3), bitbase, bitoffset ); }
|
||||
void xImpl_Group8::operator()( const xRegister16& bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, 0xa3 | (InstType << 3), bitbase, bitoffset ); }
|
||||
void xImpl_Group8::operator()( const ModSib32& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
|
||||
void xImpl_Group8::operator()( const ModSib16& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
|
||||
void xImpl_Group8::operator()( const xIndirect32& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
|
||||
void xImpl_Group8::operator()( const xIndirect16& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
|
||||
|
||||
void xImpl_Group8::operator()( const xRegister16or32& bitbase, u8 bitoffset ) const
|
||||
{
|
||||
xOpWrite0F( (bitbase->GetOperandSize() == 2) ? 0x66 : 0x00, 0xba, InstType, bitbase, bitoffset );
|
||||
}
|
||||
|
||||
void xImpl_Group8::operator()( const ModSibBase& bitbase, const xRegister16or32& bitoffset ) const
|
||||
void xImpl_Group8::operator()( const xIndirectVoid& bitbase, const xRegister16or32& bitoffset ) const
|
||||
{
|
||||
xOpWrite0F( (bitoffset->GetOperandSize() == 2) ? 0x66 : 0x00, 0xa3 | (InstType << 3), bitoffset, bitbase );
|
||||
}
|
||||
|
|
|
@ -34,10 +34,10 @@
|
|||
namespace x86Emitter {
|
||||
|
||||
void xImpl_JmpCall::operator()( const xRegister32& absreg ) const { xOpWrite( 0x00, 0xff, isJmp ? 4 : 2, absreg ); }
|
||||
void xImpl_JmpCall::operator()( const ModSib32& src ) const { xOpWrite( 0x00, 0xff, isJmp ? 4 : 2, src ); }
|
||||
void xImpl_JmpCall::operator()( const xIndirect32& src ) const { xOpWrite( 0x00, 0xff, isJmp ? 4 : 2, src ); }
|
||||
|
||||
void xImpl_JmpCall::operator()( const xRegister16& absreg ) const { xOpWrite( 0x66, 0xff, isJmp ? 4 : 2, absreg ); }
|
||||
void xImpl_JmpCall::operator()( const ModSib16& src ) const { xOpWrite( 0x66, 0xff, isJmp ? 4 : 2, src ); }
|
||||
void xImpl_JmpCall::operator()( const xIndirect16& src ) const { xOpWrite( 0x66, 0xff, isJmp ? 4 : 2, src ); }
|
||||
|
||||
const xImpl_JmpCall xJMP = { true };
|
||||
const xImpl_JmpCall xCALL = { false };
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
#include "legacy_internal.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
emitterT void ModRM( uint mod, uint reg, uint rm )
|
||||
{
|
||||
// Note: Following assertions are for legacy support only.
|
||||
|
@ -54,32 +52,32 @@ emitterT void SibSB( uint ss, uint index, uint base )
|
|||
|
||||
using namespace x86Emitter;
|
||||
|
||||
static ModSib32 _mhlp32( x86IntRegType to )
|
||||
static xIndirect32 _mhlp32( x86IntRegType to )
|
||||
{
|
||||
return ptr32[xAddressReg( to )];
|
||||
}
|
||||
|
||||
static ModSib32 _mhlp32( x86IntRegType to1, x86IntRegType to2 )
|
||||
static xIndirect32 _mhlp32( x86IntRegType to1, x86IntRegType to2 )
|
||||
{
|
||||
return ptr32[xAddressReg( to1 ) + xAddressReg( to2 )];
|
||||
}
|
||||
|
||||
static ModSib16 _mhlp16( x86IntRegType to )
|
||||
static xIndirect16 _mhlp16( x86IntRegType to )
|
||||
{
|
||||
return ptr16[xAddressReg( to )];
|
||||
}
|
||||
|
||||
static ModSib16 _mhlp16( x86IntRegType to1, x86IntRegType to2 )
|
||||
static xIndirect16 _mhlp16( x86IntRegType to1, x86IntRegType to2 )
|
||||
{
|
||||
return ptr16[xAddressReg( to1 ) + xAddressReg( to2 )];
|
||||
}
|
||||
|
||||
static ModSib8 _mhlp8( x86IntRegType to )
|
||||
static xIndirect8 _mhlp8( x86IntRegType to )
|
||||
{
|
||||
return ptr8[xAddressReg( to )];
|
||||
}
|
||||
|
||||
static ModSib8 _mhlp8( x86IntRegType to1, x86IntRegType to2 )
|
||||
static xIndirect8 _mhlp8( x86IntRegType to1, x86IntRegType to2 )
|
||||
{
|
||||
return ptr8[xAddressReg( to1 ) + xAddressReg( to2 )];
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ void xImpl_Mov::operator()( const xRegister32& to, const xRegister32& from ) con
|
|||
EmitSibMagic( from, to );
|
||||
}
|
||||
|
||||
void xImpl_Mov::operator()( const ModSibBase& dest, const xRegisterInt& from ) const
|
||||
void xImpl_Mov::operator()( const xIndirectVoid& dest, const xRegisterInt& from ) const
|
||||
{
|
||||
from.prefix16();
|
||||
|
||||
|
@ -86,7 +86,7 @@ void xImpl_Mov::operator()( const ModSibBase& dest, const xRegisterInt& from ) c
|
|||
}
|
||||
}
|
||||
|
||||
void xImpl_Mov::operator()( const xRegisterInt& to, const ModSibBase& src ) const
|
||||
void xImpl_Mov::operator()( const xRegisterInt& to, const xIndirectVoid& src ) const
|
||||
{
|
||||
to.prefix16();
|
||||
|
||||
|
@ -105,7 +105,7 @@ void xImpl_Mov::operator()( const xRegisterInt& to, const ModSibBase& src ) cons
|
|||
}
|
||||
}
|
||||
|
||||
void xImpl_Mov::operator()( const ModSib32orLess& dest, int imm ) const
|
||||
void xImpl_Mov::operator()( const xIndirect32orLess& dest, int imm ) const
|
||||
{
|
||||
dest.prefix16();
|
||||
xWrite8( dest.Is8BitOp() ? 0xc6 : 0xc7 );
|
||||
|
@ -143,26 +143,26 @@ const xImpl_Mov xMOV;
|
|||
|
||||
|
||||
void xCMOV( JccComparisonType ccType, const xRegister32& to, const xRegister32& from ) { ccSane(); xOpWrite0F( 0x40 | ccType, to, from ); }
|
||||
void xCMOV( JccComparisonType ccType, const xRegister32& to, const ModSibBase& sibsrc ) { ccSane(); xOpWrite0F( 0x40 | ccType, to, sibsrc ); }
|
||||
void xCMOV( JccComparisonType ccType, const xRegister32& to, const xIndirectVoid& sibsrc ) { ccSane(); xOpWrite0F( 0x40 | ccType, to, sibsrc ); }
|
||||
//void xCMOV( JccComparisonType ccType, const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } // too.. lazy.. to fix.
|
||||
|
||||
void xCMOV( JccComparisonType ccType, const xRegister16& to, const xRegister16& from ) { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, from ); }
|
||||
void xCMOV( JccComparisonType ccType, const xRegister16& to, const ModSibBase& sibsrc ) { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, sibsrc ); }
|
||||
void xCMOV( JccComparisonType ccType, const xRegister16& to, const xIndirectVoid& sibsrc ) { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, sibsrc ); }
|
||||
//void xCMOV( JccComparisonType ccType, const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); }
|
||||
|
||||
void xSET( JccComparisonType ccType, const xRegister8& to ) { ccSane(); xOpWrite0F( 0x90 | ccType, 0, to ); }
|
||||
void xSET( JccComparisonType ccType, const ModSib8& dest ) { ccSane(); xOpWrite0F( 0x90 | ccType, 0, dest ); }
|
||||
void xSET( JccComparisonType ccType, const xIndirect8& dest ) { ccSane(); xOpWrite0F( 0x90 | ccType, 0, dest ); }
|
||||
|
||||
void xImpl_CMov::operator()( const xRegister32& to, const xRegister32& from ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, from ); }
|
||||
void xImpl_CMov::operator()( const xRegister32& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, sibsrc ); }
|
||||
void xImpl_CMov::operator()( const xRegister32& to, const xIndirectVoid& sibsrc ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, sibsrc ); }
|
||||
void xImpl_CMov::operator()( const xRegister16& to, const xRegister16& from ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, from ); }
|
||||
void xImpl_CMov::operator()( const xRegister16& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, sibsrc ); }
|
||||
void xImpl_CMov::operator()( const xRegister16& to, const xIndirectVoid& sibsrc ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, sibsrc ); }
|
||||
|
||||
//void xImpl_CMov::operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); }
|
||||
//void xImpl_CMov::operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); }
|
||||
|
||||
void xImpl_Set::operator()( const xRegister8& to ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, to ); }
|
||||
void xImpl_Set::operator()( const ModSib8& dest ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, dest ); }
|
||||
void xImpl_Set::operator()( const xIndirect8& dest ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, dest ); }
|
||||
//void xImpl_Set::operator()( const xDirectOrIndirect8& dest ) const { ccSane(); _DoI_helpermess( *this, dest ); }
|
||||
|
||||
void xImpl_MovExtend::operator()( const xRegister16or32& to, const xRegister8& from ) const
|
||||
|
@ -175,7 +175,7 @@ void xImpl_MovExtend::operator()( const xRegister16or32& to, const xRegister8& f
|
|||
);
|
||||
}
|
||||
|
||||
void xImpl_MovExtend::operator()( const xRegister16or32& to, const ModSib8& sibsrc ) const
|
||||
void xImpl_MovExtend::operator()( const xRegister16or32& to, const xIndirect8& sibsrc ) const
|
||||
{
|
||||
EbpAssert();
|
||||
xOpWrite0F(
|
||||
|
@ -191,7 +191,7 @@ void xImpl_MovExtend::operator()( const xRegister32& to, const xRegister16& from
|
|||
xOpWrite0F( SignExtend ? 0xbf : 0xb7, to, from );
|
||||
}
|
||||
|
||||
void xImpl_MovExtend::operator()( const xRegister32& to, const ModSib16& sibsrc ) const
|
||||
void xImpl_MovExtend::operator()( const xRegister32& to, const xIndirect16& sibsrc ) const
|
||||
{
|
||||
EbpAssert();
|
||||
xOpWrite0F( SignExtend ? 0xbf : 0xb7, to, sibsrc );
|
||||
|
|
|
@ -73,7 +73,7 @@ SSE_MXCSR& SSE_MXCSR::ApplyReserveMask()
|
|||
return *this;
|
||||
}
|
||||
|
||||
SSE_MXCSR::operator x86Emitter::ModSib32() const
|
||||
SSE_MXCSR::operator x86Emitter::xIndirect32() const
|
||||
{
|
||||
return x86Emitter::ptr32[&bitmask];
|
||||
}
|
||||
|
@ -135,87 +135,87 @@ const xImplSimd_DestRegSSE xPTEST = { 0x66,0x1738 };
|
|||
//
|
||||
|
||||
__forceinline void xCVTDQ2PD( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf3, 0xe6 ); }
|
||||
__forceinline void xCVTDQ2PD( const xRegisterSSE& to, const ModSib64& from ) { OpWriteSSE( 0xf3, 0xe6 ); }
|
||||
__forceinline void xCVTDQ2PD( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0xf3, 0xe6 ); }
|
||||
__forceinline void xCVTDQ2PS( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x00, 0x5b ); }
|
||||
__forceinline void xCVTDQ2PS( const xRegisterSSE& to, const ModSib128& from ) { OpWriteSSE( 0x00, 0x5b ); }
|
||||
__forceinline void xCVTDQ2PS( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x00, 0x5b ); }
|
||||
|
||||
__forceinline void xCVTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0xe6 ); }
|
||||
__forceinline void xCVTPD2DQ( const xRegisterSSE& to, const ModSib128& from ) { OpWriteSSE( 0xf2, 0xe6 ); }
|
||||
__forceinline void xCVTPD2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0xf2, 0xe6 ); }
|
||||
__forceinline void xCVTPD2PI( const xRegisterMMX& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x2d ); }
|
||||
__forceinline void xCVTPD2PI( const xRegisterMMX& to, const ModSib128& from ) { OpWriteSSE( 0x66, 0x2d ); }
|
||||
__forceinline void xCVTPD2PI( const xRegisterMMX& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x2d ); }
|
||||
__forceinline void xCVTPD2PS( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x5a ); }
|
||||
__forceinline void xCVTPD2PS( const xRegisterSSE& to, const ModSib128& from ) { OpWriteSSE( 0x66, 0x5a ); }
|
||||
__forceinline void xCVTPD2PS( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x5a ); }
|
||||
|
||||
__forceinline void xCVTPI2PD( const xRegisterSSE& to, const xRegisterMMX& from ) { OpWriteSSE( 0x66, 0x2a ); }
|
||||
__forceinline void xCVTPI2PD( const xRegisterSSE& to, const ModSib64& from ) { OpWriteSSE( 0x66, 0x2a ); }
|
||||
__forceinline void xCVTPI2PD( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x66, 0x2a ); }
|
||||
__forceinline void xCVTPI2PS( const xRegisterSSE& to, const xRegisterMMX& from ) { OpWriteSSE( 0x00, 0x2a ); }
|
||||
__forceinline void xCVTPI2PS( const xRegisterSSE& to, const ModSib64& from ) { OpWriteSSE( 0x00, 0x2a ); }
|
||||
__forceinline void xCVTPI2PS( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x2a ); }
|
||||
|
||||
__forceinline void xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x5b ); }
|
||||
__forceinline void xCVTPS2DQ( const xRegisterSSE& to, const ModSib128& from ) { OpWriteSSE( 0x66, 0x5b ); }
|
||||
__forceinline void xCVTPS2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x5b ); }
|
||||
__forceinline void xCVTPS2PD( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x00, 0x5a ); }
|
||||
__forceinline void xCVTPS2PD( const xRegisterSSE& to, const ModSib64& from ) { OpWriteSSE( 0x00, 0x5a ); }
|
||||
__forceinline void xCVTPS2PD( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x5a ); }
|
||||
__forceinline void xCVTPS2PI( const xRegisterMMX& to, const xRegisterSSE& from ) { OpWriteSSE( 0x00, 0x2d ); }
|
||||
__forceinline void xCVTPS2PI( const xRegisterMMX& to, const ModSib64& from ) { OpWriteSSE( 0x00, 0x2d ); }
|
||||
__forceinline void xCVTPS2PI( const xRegisterMMX& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x2d ); }
|
||||
|
||||
__forceinline void xCVTSD2SI( const xRegister32& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x2d ); }
|
||||
__forceinline void xCVTSD2SI( const xRegister32& to, const ModSib64& from ) { OpWriteSSE( 0xf2, 0x2d ); }
|
||||
__forceinline void xCVTSD2SI( const xRegister32& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x2d ); }
|
||||
__forceinline void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x5a ); }
|
||||
__forceinline void xCVTSD2SS( const xRegisterSSE& to, const ModSib64& from ) { OpWriteSSE( 0xf2, 0x5a ); }
|
||||
__forceinline void xCVTSD2SS( const xRegisterSSE& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x5a ); }
|
||||
__forceinline void xCVTSI2SD( const xRegisterMMX& to, const xRegister32& from ) { OpWriteSSE( 0xf2, 0x2a ); }
|
||||
__forceinline void xCVTSI2SD( const xRegisterMMX& to, const ModSib32& from ) { OpWriteSSE( 0xf2, 0x2a ); }
|
||||
__forceinline void xCVTSI2SD( const xRegisterMMX& to, const xIndirect32& from ) { OpWriteSSE( 0xf2, 0x2a ); }
|
||||
__forceinline void xCVTSI2SS( const xRegisterSSE& to, const xRegister32& from ) { OpWriteSSE( 0xf3, 0x2a ); }
|
||||
__forceinline void xCVTSI2SS( const xRegisterSSE& to, const ModSib32& from ) { OpWriteSSE( 0xf3, 0x2a ); }
|
||||
__forceinline void xCVTSI2SS( const xRegisterSSE& to, const xIndirect32& from ) { OpWriteSSE( 0xf3, 0x2a ); }
|
||||
|
||||
__forceinline void xCVTSS2SD( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf3, 0x5a ); }
|
||||
__forceinline void xCVTSS2SD( const xRegisterSSE& to, const ModSib32& from ) { OpWriteSSE( 0xf3, 0x5a ); }
|
||||
__forceinline void xCVTSS2SD( const xRegisterSSE& to, const xIndirect32& from ) { OpWriteSSE( 0xf3, 0x5a ); }
|
||||
__forceinline void xCVTSS2SI( const xRegister32& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf3, 0x2d ); }
|
||||
__forceinline void xCVTSS2SI( const xRegister32& to, const ModSib32& from ) { OpWriteSSE( 0xf3, 0x2d ); }
|
||||
__forceinline void xCVTSS2SI( const xRegister32& to, const xIndirect32& from ) { OpWriteSSE( 0xf3, 0x2d ); }
|
||||
|
||||
__forceinline void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0xe6 ); }
|
||||
__forceinline void xCVTTPD2DQ( const xRegisterSSE& to, const ModSib128& from ) { OpWriteSSE( 0x66, 0xe6 ); }
|
||||
__forceinline void xCVTTPD2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0xe6 ); }
|
||||
__forceinline void xCVTTPD2PI( const xRegisterMMX& to, const xRegisterSSE& from ) { OpWriteSSE( 0x66, 0x2c ); }
|
||||
__forceinline void xCVTTPD2PI( const xRegisterMMX& to, const ModSib128& from ) { OpWriteSSE( 0x66, 0x2c ); }
|
||||
__forceinline void xCVTTPD2PI( const xRegisterMMX& to, const xIndirect128& from ) { OpWriteSSE( 0x66, 0x2c ); }
|
||||
__forceinline void xCVTTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf3, 0x5b ); }
|
||||
__forceinline void xCVTTPS2DQ( const xRegisterSSE& to, const ModSib128& from ) { OpWriteSSE( 0xf3, 0x5b ); }
|
||||
__forceinline void xCVTTPS2DQ( const xRegisterSSE& to, const xIndirect128& from ) { OpWriteSSE( 0xf3, 0x5b ); }
|
||||
__forceinline void xCVTTPS2PI( const xRegisterMMX& to, const xRegisterSSE& from ) { OpWriteSSE( 0x00, 0x2c ); }
|
||||
__forceinline void xCVTTPS2PI( const xRegisterMMX& to, const ModSib64& from ) { OpWriteSSE( 0x00, 0x2c ); }
|
||||
__forceinline void xCVTTPS2PI( const xRegisterMMX& to, const xIndirect64& from ) { OpWriteSSE( 0x00, 0x2c ); }
|
||||
|
||||
__forceinline void xCVTTSD2SI( const xRegister32& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf2, 0x2c ); }
|
||||
__forceinline void xCVTTSD2SI( const xRegister32& to, const ModSib64& from ) { OpWriteSSE( 0xf2, 0x2c ); }
|
||||
__forceinline void xCVTTSD2SI( const xRegister32& to, const xIndirect64& from ) { OpWriteSSE( 0xf2, 0x2c ); }
|
||||
__forceinline void xCVTTSS2SI( const xRegister32& to, const xRegisterSSE& from ) { OpWriteSSE( 0xf3, 0x2c ); }
|
||||
__forceinline void xCVTTSS2SI( const xRegister32& to, const ModSib32& from ) { OpWriteSSE( 0xf3, 0x2c ); }
|
||||
__forceinline void xCVTTSS2SI( const xRegister32& to, const xIndirect32& from ) { OpWriteSSE( 0xf3, 0x2c ); }
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void xImplSimd_DestRegSSE::operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
void xImplSimd_DestRegSSE::operator()( const xRegisterSSE& to, const ModSibBase& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
void xImplSimd_DestRegSSE::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
|
||||
void xImplSimd_DestRegImmSSE::operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
void xImplSimd_DestRegImmSSE::operator()( const xRegisterSSE& to, const ModSibBase& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
void xImplSimd_DestRegImmSSE::operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
|
||||
void xImplSimd_DestRegImmMMX::operator()( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); }
|
||||
void xImplSimd_DestRegImmMMX::operator()( const xRegisterMMX& to, const ModSibBase& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); }
|
||||
void xImplSimd_DestRegImmMMX::operator()( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); }
|
||||
|
||||
void xImplSimd_DestRegEither::operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
void xImplSimd_DestRegEither::operator()( const xRegisterSSE& to, const ModSibBase& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
void xImplSimd_DestRegEither::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
|
||||
void xImplSimd_DestRegEither::operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
||||
void xImplSimd_DestRegEither::operator()( const xRegisterMMX& to, const ModSibBase& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
||||
void xImplSimd_DestRegEither::operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
||||
|
||||
void xImplSimd_DestSSE_CmpImm::operator()( const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
void xImplSimd_DestSSE_CmpImm::operator()( const xRegisterSSE& to, const ModSibBase& from, SSE2_ComparisonType imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
void xImplSimd_DestSSE_CmpImm::operator()( const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
|
||||
// =====================================================================================================
|
||||
// SIMD Arithmetic Instructions
|
||||
// =====================================================================================================
|
||||
|
||||
void _SimdShiftHelper::operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
void _SimdShiftHelper::operator()( const xRegisterSSE& to, const ModSibBase& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
void _SimdShiftHelper::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( Prefix, Opcode ); }
|
||||
|
||||
void _SimdShiftHelper::operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
||||
void _SimdShiftHelper::operator()( const xRegisterMMX& to, const ModSibBase& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
||||
void _SimdShiftHelper::operator()( const xRegisterMMX& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x00, Opcode ); }
|
||||
|
||||
void _SimdShiftHelper::operator()( const xRegisterSSE& to, u8 imm8 ) const
|
||||
{
|
||||
|
@ -365,16 +365,16 @@ const xImplSimd_Round xROUND =
|
|||
// =====================================================================================================
|
||||
|
||||
void xImplSimd_Compare::PS( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( 0x00, 0xc2, to, from, (u8)CType ); }
|
||||
void xImplSimd_Compare::PS( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( 0x00, 0xc2, to, from, (u8)CType ); }
|
||||
void xImplSimd_Compare::PS( const xRegisterSSE& to, const xIndirectVoid& from ) const { xOpWrite0F( 0x00, 0xc2, to, from, (u8)CType ); }
|
||||
|
||||
void xImplSimd_Compare::PD( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( 0x66, 0xc2, to, from, (u8)CType ); }
|
||||
void xImplSimd_Compare::PD( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( 0x66, 0xc2, to, from, (u8)CType ); }
|
||||
void xImplSimd_Compare::PD( const xRegisterSSE& to, const xIndirectVoid& from ) const { xOpWrite0F( 0x66, 0xc2, to, from, (u8)CType ); }
|
||||
|
||||
void xImplSimd_Compare::SS( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( 0xf3, 0xc2, to, from, (u8)CType ); }
|
||||
void xImplSimd_Compare::SS( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( 0xf3, 0xc2, to, from, (u8)CType ); }
|
||||
void xImplSimd_Compare::SS( const xRegisterSSE& to, const xIndirectVoid& from ) const { xOpWrite0F( 0xf3, 0xc2, to, from, (u8)CType ); }
|
||||
|
||||
void xImplSimd_Compare::SD( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( 0xf2, 0xc2, to, from, (u8)CType ); }
|
||||
void xImplSimd_Compare::SD( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( 0xf2, 0xc2, to, from, (u8)CType ); }
|
||||
void xImplSimd_Compare::SD( const xRegisterSSE& to, const xIndirectVoid& from ) const { xOpWrite0F( 0xf2, 0xc2, to, from, (u8)CType ); }
|
||||
|
||||
const xImplSimd_MinMax xMIN =
|
||||
{
|
||||
|
@ -464,7 +464,7 @@ void xImplSimd_Shuffle::PS( const xRegisterSSE& to, const xRegisterSSE& from, u8
|
|||
xOpWrite0F( 0xc6, to, from, selector );
|
||||
}
|
||||
|
||||
void xImplSimd_Shuffle::PS( const xRegisterSSE& to, const ModSibBase& from, u8 selector ) const
|
||||
void xImplSimd_Shuffle::PS( const xRegisterSSE& to, const xIndirectVoid& from, u8 selector ) const
|
||||
{
|
||||
xOpWrite0F( 0xc6, to, from, selector );
|
||||
}
|
||||
|
@ -475,7 +475,7 @@ void xImplSimd_Shuffle::PD( const xRegisterSSE& to, const xRegisterSSE& from, u8
|
|||
xOpWrite0F( 0x66, 0xc6, to, from, selector & 0x3 );
|
||||
}
|
||||
|
||||
void xImplSimd_Shuffle::PD( const xRegisterSSE& to, const ModSibBase& from, u8 selector ) const
|
||||
void xImplSimd_Shuffle::PD( const xRegisterSSE& to, const xIndirectVoid& from, u8 selector ) const
|
||||
{
|
||||
_selector_assertion_check( selector );
|
||||
xOpWrite0F( 0x66, 0xc6, to, from, selector & 0x3 );
|
||||
|
@ -486,19 +486,19 @@ void xImplSimd_InsertExtractHelper::operator()( const xRegisterSSE& to, const xR
|
|||
xOpWrite0F( 0x66, Opcode, to, from, imm8 );
|
||||
}
|
||||
|
||||
void xImplSimd_InsertExtractHelper::operator()( const xRegisterSSE& to, const ModSibBase& from, u8 imm8 ) const
|
||||
void xImplSimd_InsertExtractHelper::operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const
|
||||
{
|
||||
xOpWrite0F( 0x66, Opcode, to, from, imm8 );
|
||||
}
|
||||
|
||||
void xImplSimd_PInsert::W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
||||
void xImplSimd_PInsert::W( const xRegisterSSE& to, const ModSibBase& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
||||
void xImplSimd_PInsert::W( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
||||
void xImplSimd_PInsert::W( const xRegisterMMX& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); }
|
||||
void xImplSimd_PInsert::W( const xRegisterMMX& to, const ModSibBase& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); }
|
||||
void xImplSimd_PInsert::W( const xRegisterMMX& to, const xIndirectVoid& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); }
|
||||
|
||||
void SimdImpl_PExtract::W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc5, to, from, imm8 ); }
|
||||
void SimdImpl_PExtract::W( const xRegister32& to, const xRegisterMMX& from, u8 imm8 ) const { xOpWrite0F( 0xc5, to, from, imm8 ); }
|
||||
void SimdImpl_PExtract::W( const ModSibBase& dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0x153a, from, dest, imm8 ); }
|
||||
void SimdImpl_PExtract::W( const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0x153a, from, dest, imm8 ); }
|
||||
|
||||
const xImplSimd_Shuffle xSHUF = { };
|
||||
|
||||
|
@ -557,11 +557,11 @@ const SimdImpl_PExtract xPEXTR =
|
|||
// SIMD Move And Blend Instructions
|
||||
// =====================================================================================================
|
||||
|
||||
void xImplSimd_MovHL::PS( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
void xImplSimd_MovHL::PS( const ModSibBase& to, const xRegisterSSE& from ) const { xOpWrite0F( Opcode+1, from, to ); }
|
||||
void xImplSimd_MovHL::PS( const xRegisterSSE& to, const xIndirectVoid& from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
void xImplSimd_MovHL::PS( const xIndirectVoid& to, const xRegisterSSE& from ) const { xOpWrite0F( Opcode+1, from, to ); }
|
||||
|
||||
void xImplSimd_MovHL::PD( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); }
|
||||
void xImplSimd_MovHL::PD( const ModSibBase& to, const xRegisterSSE& from ) const { xOpWrite0F( 0x66, Opcode+1, from, to ); }
|
||||
void xImplSimd_MovHL::PD( const xRegisterSSE& to, const xIndirectVoid& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); }
|
||||
void xImplSimd_MovHL::PD( const xIndirectVoid& to, const xRegisterSSE& from ) const { xOpWrite0F( 0x66, Opcode+1, from, to ); }
|
||||
|
||||
void xImplSimd_MovHL_RtoR::PS( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
void xImplSimd_MovHL_RtoR::PD( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); }
|
||||
|
@ -574,7 +574,7 @@ void xImplSimd_MoveSSE::operator()( const xRegisterSSE& to, const xRegisterSSE&
|
|||
if( to != from ) xOpWrite0F( Prefix, MovPS_OpAligned, to, from );
|
||||
}
|
||||
|
||||
void xImplSimd_MoveSSE::operator()( const xRegisterSSE& to, const ModSibBase& from ) const
|
||||
void xImplSimd_MoveSSE::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const
|
||||
{
|
||||
// ModSib form is aligned if it's displacement-only and the displacement is aligned:
|
||||
bool isReallyAligned = isAligned || ( ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty() );
|
||||
|
@ -582,7 +582,7 @@ void xImplSimd_MoveSSE::operator()( const xRegisterSSE& to, const ModSibBase& fr
|
|||
xOpWrite0F( Prefix, isReallyAligned ? MovPS_OpAligned : MovPS_OpUnaligned, to, from );
|
||||
}
|
||||
|
||||
void xImplSimd_MoveSSE::operator()( const ModSibBase& to, const xRegisterSSE& from ) const
|
||||
void xImplSimd_MoveSSE::operator()( const xIndirectVoid& to, const xRegisterSSE& from ) const
|
||||
{
|
||||
// ModSib form is aligned if it's displacement-only and the displacement is aligned:
|
||||
bool isReallyAligned = isAligned || ( (to.Displacement & 0x0f) == 0 && to.Index.IsEmpty() && to.Base.IsEmpty() );
|
||||
|
@ -597,14 +597,14 @@ void xImplSimd_MoveDQ::operator()( const xRegisterSSE& to, const xRegisterSSE& f
|
|||
if( to != from ) xOpWrite0F( MovDQ_PrefixAligned, 0x6f, to, from );
|
||||
}
|
||||
|
||||
void xImplSimd_MoveDQ::operator()( const xRegisterSSE& to, const ModSibBase& from ) const
|
||||
void xImplSimd_MoveDQ::operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const
|
||||
{
|
||||
// ModSib form is aligned if it's displacement-only and the displacement is aligned:
|
||||
bool isReallyAligned = isAligned || ( (from.Displacement & 0x0f) == 0 && from.Index.IsEmpty() && from.Base.IsEmpty() );
|
||||
xOpWrite0F( isReallyAligned ? MovDQ_PrefixAligned : MovDQ_PrefixUnaligned, 0x6f, to, from );
|
||||
}
|
||||
|
||||
void xImplSimd_MoveDQ::operator()( const ModSibBase& to, const xRegisterSSE& from ) const
|
||||
void xImplSimd_MoveDQ::operator()( const xIndirectVoid& to, const xRegisterSSE& from ) const
|
||||
{
|
||||
// ModSib form is aligned if it's displacement-only and the displacement is aligned:
|
||||
bool isReallyAligned = isAligned || ( (to.Displacement & 0x0f) == 0 && to.Index.IsEmpty() && to.Base.IsEmpty() );
|
||||
|
@ -614,22 +614,22 @@ void xImplSimd_MoveDQ::operator()( const ModSibBase& to, const xRegisterSSE& fro
|
|||
}
|
||||
|
||||
void xImplSimd_PMove::BW( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, OpcodeBase ); }
|
||||
void xImplSimd_PMove::BW( const xRegisterSSE& to, const ModSib64& from ) const { OpWriteSSE( 0x66, OpcodeBase ); }
|
||||
void xImplSimd_PMove::BW( const xRegisterSSE& to, const xIndirect64& from ) const { OpWriteSSE( 0x66, OpcodeBase ); }
|
||||
|
||||
void xImplSimd_PMove::BD( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x100 ); }
|
||||
void xImplSimd_PMove::BD( const xRegisterSSE& to, const ModSib32& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x100 ); }
|
||||
void xImplSimd_PMove::BD( const xRegisterSSE& to, const xIndirect32& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x100 ); }
|
||||
|
||||
void xImplSimd_PMove::BQ( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x200 ); }
|
||||
void xImplSimd_PMove::BQ( const xRegisterSSE& to, const ModSib16& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x200 ); }
|
||||
void xImplSimd_PMove::BQ( const xRegisterSSE& to, const xIndirect16& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x200 ); }
|
||||
|
||||
void xImplSimd_PMove::WD( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x300 ); }
|
||||
void xImplSimd_PMove::WD( const xRegisterSSE& to, const ModSib64& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x300 ); }
|
||||
void xImplSimd_PMove::WD( const xRegisterSSE& to, const xIndirect64& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x300 ); }
|
||||
|
||||
void xImplSimd_PMove::WQ( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x400 ); }
|
||||
void xImplSimd_PMove::WQ( const xRegisterSSE& to, const ModSib32& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x400 ); }
|
||||
void xImplSimd_PMove::WQ( const xRegisterSSE& to, const xIndirect32& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x400 ); }
|
||||
|
||||
void xImplSimd_PMove::DQ( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x500 ); }
|
||||
void xImplSimd_PMove::DQ( const xRegisterSSE& to, const ModSib64& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x500 ); }
|
||||
void xImplSimd_PMove::DQ( const xRegisterSSE& to, const xIndirect64& from ) const { OpWriteSSE( 0x66, OpcodeBase+0x500 ); }
|
||||
|
||||
|
||||
const xImplSimd_MoveSSE xMOVAPS = { 0x00, true };
|
||||
|
@ -685,16 +685,16 @@ const xImplSimd_DestRegSSE xMOVSHDUP = { 0xf3,0x16 };
|
|||
//
|
||||
|
||||
__forceinline void xMOVDZX( const xRegisterSSE& to, const xRegister32& from ) { xOpWrite0F( 0x66, 0x6e, to, from ); }
|
||||
__forceinline void xMOVDZX( const xRegisterSSE& to, const ModSibBase& src ) { xOpWrite0F( 0x66, 0x6e, to, src ); }
|
||||
__forceinline void xMOVDZX( const xRegisterSSE& to, const xIndirectVoid& src ) { xOpWrite0F( 0x66, 0x6e, to, src ); }
|
||||
|
||||
__forceinline void xMOVDZX( const xRegisterMMX& to, const xRegister32& from ) { xOpWrite0F( 0x6e, to, from ); }
|
||||
__forceinline void xMOVDZX( const xRegisterMMX& to, const ModSibBase& src ) { xOpWrite0F( 0x6e, to, src ); }
|
||||
__forceinline void xMOVDZX( const xRegisterMMX& to, const xIndirectVoid& src ) { xOpWrite0F( 0x6e, to, src ); }
|
||||
|
||||
__forceinline void xMOVD( const xRegister32& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, to ); }
|
||||
__forceinline void xMOVD( const ModSibBase& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, dest ); }
|
||||
__forceinline void xMOVD( const xIndirectVoid& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, dest ); }
|
||||
|
||||
__forceinline void xMOVD( const xRegister32& to, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, to ); }
|
||||
__forceinline void xMOVD( const ModSibBase& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, dest ); }
|
||||
__forceinline void xMOVD( const xIndirectVoid& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, dest ); }
|
||||
|
||||
|
||||
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
||||
|
@ -703,18 +703,18 @@ __forceinline void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from ) {
|
|||
|
||||
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
||||
// being cleared to zero.
|
||||
__forceinline void xMOVQZX( const xRegisterSSE& to, const ModSibBase& src ) { xOpWrite0F( 0xf3, 0x7e, to, src ); }
|
||||
__forceinline void xMOVQZX( const xRegisterSSE& to, const xIndirectVoid& src ) { xOpWrite0F( 0xf3, 0x7e, to, src ); }
|
||||
|
||||
// Moves from XMM to XMM, with the *upper 64 bits* of the destination register
|
||||
// being cleared to zero.
|
||||
__forceinline void xMOVQZX( const xRegisterSSE& to, const void* src ) { xOpWrite0F( 0xf3, 0x7e, to, src ); }
|
||||
|
||||
// Moves lower quad of XMM to ptr64 (no bits are cleared)
|
||||
__forceinline void xMOVQ( const ModSibBase& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd6, from, dest ); }
|
||||
__forceinline void xMOVQ( const xIndirectVoid& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd6, from, dest ); }
|
||||
|
||||
__forceinline void xMOVQ( const xRegisterMMX& to, const xRegisterMMX& from ) { if( to != from ) xOpWrite0F( 0x6f, to, from ); }
|
||||
__forceinline void xMOVQ( const xRegisterMMX& to, const ModSibBase& src ) { xOpWrite0F( 0x6f, to, src ); }
|
||||
__forceinline void xMOVQ( const ModSibBase& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7f, from, dest ); }
|
||||
__forceinline void xMOVQ( const xRegisterMMX& to, const xIndirectVoid& src ) { xOpWrite0F( 0x6f, to, src ); }
|
||||
__forceinline void xMOVQ( const xIndirectVoid& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7f, from, dest ); }
|
||||
|
||||
// This form of xMOVQ is Intel's adeptly named 'MOVQ2DQ'
|
||||
__forceinline void xMOVQ( const xRegisterSSE& to, const xRegisterMMX& from ) { xOpWrite0F( 0xf3, 0xd6, to, from ); }
|
||||
|
@ -734,8 +734,8 @@ __forceinline void xMOVQ( const xRegisterMMX& to, const xRegisterSSE& from )
|
|||
|
||||
#define IMPLEMENT_xMOVS( ssd, prefix ) \
|
||||
__forceinline void xMOV##ssd( const xRegisterSSE& to, const xRegisterSSE& from ) { if( to != from ) xOpWrite0F( prefix, 0x10, to, from ); } \
|
||||
__forceinline void xMOV##ssd##ZX( const xRegisterSSE& to, const ModSibBase& from ) { xOpWrite0F( prefix, 0x10, to, from ); } \
|
||||
__forceinline void xMOV##ssd( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( prefix, 0x11, from, to ); }
|
||||
__forceinline void xMOV##ssd##ZX( const xRegisterSSE& to, const xIndirectVoid& from ) { xOpWrite0F( prefix, 0x10, to, from ); } \
|
||||
__forceinline void xMOV##ssd( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( prefix, 0x11, from, to ); }
|
||||
|
||||
IMPLEMENT_xMOVS( SS, 0xf3 )
|
||||
IMPLEMENT_xMOVS( SD, 0xf2 )
|
||||
|
@ -744,18 +744,18 @@ IMPLEMENT_xMOVS( SD, 0xf2 )
|
|||
// Non-temporal movs only support a register as a target (ie, load form only, no stores)
|
||||
//
|
||||
|
||||
__forceinline void xMOVNTDQA( const xRegisterSSE& to, const ModSibBase& from )
|
||||
__forceinline void xMOVNTDQA( const xRegisterSSE& to, const xIndirectVoid& from )
|
||||
{
|
||||
xWrite32( 0x2A380f66 );
|
||||
EmitSibMagic( to.Id, from );
|
||||
}
|
||||
|
||||
__forceinline void xMOVNTDQA( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xe7, from, to ); }
|
||||
__forceinline void xMOVNTDQA( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xe7, from, to ); }
|
||||
|
||||
__forceinline void xMOVNTPD( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x2b, from, to ); }
|
||||
__forceinline void xMOVNTPS( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x2b, from, to ); }
|
||||
__forceinline void xMOVNTPD( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x2b, from, to ); }
|
||||
__forceinline void xMOVNTPS( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( 0x2b, from, to ); }
|
||||
|
||||
__forceinline void xMOVNTQ( const ModSibBase& to, const xRegisterMMX& from ) { xOpWrite0F( 0xe7, from, to ); }
|
||||
__forceinline void xMOVNTQ( const xIndirectVoid& to, const xRegisterMMX& from ) { xOpWrite0F( 0xe7, from, to ); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
@ -809,14 +809,14 @@ __forceinline void xPALIGNR( const xRegisterMMX& to, const xRegisterMMX& from, u
|
|||
// with 0.0 if set to 1.
|
||||
//
|
||||
__emitinline void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); }
|
||||
__emitinline void xINSERTPS( const xRegisterSSE& to, const ModSib32& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); }
|
||||
__emitinline void xINSERTPS( const xRegisterSSE& to, const xIndirect32& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); }
|
||||
|
||||
// [SSE-4.1] Extract a single-precision floating-point value from src at an offset
|
||||
// determined by imm8[1-0]*32. The extracted single precision floating-point value
|
||||
// is stored into the low 32-bits of dest (or at a 32-bit memory pointer).
|
||||
//
|
||||
__emitinline void xEXTRACTPS( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x173a, to, from, imm8 ); }
|
||||
__emitinline void xEXTRACTPS( const ModSib32& dest, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x173a, from, dest, imm8 ); }
|
||||
__emitinline void xEXTRACTPS( const xIndirect32& dest, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x173a, from, dest, imm8 ); }
|
||||
|
||||
|
||||
// =====================================================================================================
|
||||
|
@ -837,14 +837,14 @@ __forceinline void xFEMMS() { xWrite16( 0x0E0F ); }
|
|||
|
||||
|
||||
// Store Streaming SIMD Extension Control/Status to Mem32.
|
||||
__emitinline void xSTMXCSR( const ModSib32& dest )
|
||||
__emitinline void xSTMXCSR( const xIndirect32& dest )
|
||||
{
|
||||
SimdPrefix( 0, 0xae );
|
||||
EmitSibMagic( 3, dest );
|
||||
}
|
||||
|
||||
// Load Streaming SIMD Extension Control/Status from Mem32.
|
||||
__emitinline void xLDMXCSR( const ModSib32& src )
|
||||
__emitinline void xLDMXCSR( const xIndirect32& src )
|
||||
{
|
||||
SimdPrefix( 0, 0xae );
|
||||
EmitSibMagic( 2, src );
|
||||
|
@ -852,7 +852,7 @@ __emitinline void xLDMXCSR( const ModSib32& src )
|
|||
|
||||
// Save x87 FPU, MMX Technology, and SSE State to buffer
|
||||
// Target buffer must be at least 512 bytes in length to hold the result.
|
||||
__emitinline void xFXSAVE( const ModSibBase& dest )
|
||||
__emitinline void xFXSAVE( const xIndirectVoid& dest )
|
||||
{
|
||||
SimdPrefix( 0, 0xae );
|
||||
EmitSibMagic( 0, dest );
|
||||
|
@ -860,7 +860,7 @@ __emitinline void xFXSAVE( const ModSibBase& dest )
|
|||
|
||||
// Restore x87 FPU, MMX , XMM, and MXCSR State.
|
||||
// Source buffer should be 512 bytes in length.
|
||||
__emitinline void xFXRSTOR( const ModSibBase& src )
|
||||
__emitinline void xFXRSTOR( const xIndirectVoid& src )
|
||||
{
|
||||
SimdPrefix( 0, 0xae );
|
||||
EmitSibMagic( 1, src );
|
||||
|
|
|
@ -95,12 +95,12 @@ __forceinline void xWrite64( u64 val )
|
|||
// Empty initializers are due to frivolously pointless GCC errors (it demands the
|
||||
// objects be initialized even though they have no actual variable members).
|
||||
|
||||
const xAddressIndexer<ModSibBase> ptr = { };
|
||||
const xAddressIndexer<ModSib128> ptr128 = { };
|
||||
const xAddressIndexer<ModSib64> ptr64 = { };
|
||||
const xAddressIndexer<ModSib32> ptr32 = { };
|
||||
const xAddressIndexer<ModSib16> ptr16 = { };
|
||||
const xAddressIndexer<ModSib8> ptr8 = { };
|
||||
const xAddressIndexer<xIndirectVoid> ptr = { };
|
||||
const xAddressIndexer<xIndirect128> ptr128 = { };
|
||||
const xAddressIndexer<xIndirect64> ptr64 = { };
|
||||
const xAddressIndexer<xIndirect32> ptr32 = { };
|
||||
const xAddressIndexer<xIndirect16> ptr16 = { };
|
||||
const xAddressIndexer<xIndirect8> ptr8 = { };
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
@ -239,7 +239,7 @@ void EmitSibMagic( uint regfield, const void* address )
|
|||
// Prefixes are typically 0x66, 0xf2, or 0xf3. OpcodePrefixes are either 0x38 or
|
||||
// 0x3a [and other value will result in assertion failue].
|
||||
//
|
||||
__emitinline void xOpWrite0F( u8 prefix, u16 opcode, int instId, const ModSibBase& sib )
|
||||
__emitinline void xOpWrite0F( u8 prefix, u16 opcode, int instId, const xIndirectVoid& sib )
|
||||
{
|
||||
SimdPrefix( prefix, opcode );
|
||||
EmitSibMagic( instId, sib );
|
||||
|
@ -251,7 +251,7 @@ __emitinline void xOpWrite0F( u8 prefix, u16 opcode, int instId, const void* dat
|
|||
EmitSibMagic( instId, data );
|
||||
}
|
||||
|
||||
__emitinline void xOpWrite0F( u16 opcode, int instId, const ModSibBase& sib )
|
||||
__emitinline void xOpWrite0F( u16 opcode, int instId, const xIndirectVoid& sib )
|
||||
{
|
||||
xOpWrite0F( 0, opcode, instId, sib );
|
||||
}
|
||||
|
@ -260,10 +260,10 @@ __emitinline void xOpWrite0F( u16 opcode, int instId, const ModSibBase& sib )
|
|||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// returns TRUE if this instruction requires SIB to be encoded, or FALSE if the
|
||||
// instruction ca be encoded as ModRm alone.
|
||||
static __forceinline bool NeedsSibMagic( const ModSibBase& info )
|
||||
static __forceinline bool NeedsSibMagic( const xIndirectVoid& info )
|
||||
{
|
||||
// no registers? no sibs!
|
||||
// (ModSibBase::Reduce always places a register in Index, and optionally leaves
|
||||
// (xIndirectVoid::Reduce always places a register in Index, and optionally leaves
|
||||
// Base empty if only register is specified)
|
||||
if( info.Index.IsEmpty() ) return false;
|
||||
|
||||
|
@ -282,7 +282,7 @@ static __forceinline bool NeedsSibMagic( const ModSibBase& info )
|
|||
// regfield - register field to be written to the ModRm. This is either a register specifier
|
||||
// or an opcode extension. In either case, the instruction determines the value for us.
|
||||
//
|
||||
void EmitSibMagic( uint regfield, const ModSibBase& info )
|
||||
void EmitSibMagic( uint regfield, const xIndirectVoid& info )
|
||||
{
|
||||
pxAssertDev( regfield < 8, "Invalid x86 register identifier." );
|
||||
|
||||
|
@ -360,7 +360,7 @@ void EmitSibMagic( const xRegisterBase& reg1, const void* src )
|
|||
EmitSibMagic( reg1.Id, src );
|
||||
}
|
||||
|
||||
void EmitSibMagic( const xRegisterBase& reg1, const ModSibBase& sib )
|
||||
void EmitSibMagic( const xRegisterBase& reg1, const xIndirectVoid& sib )
|
||||
{
|
||||
EmitSibMagic( reg1.Id, sib );
|
||||
}
|
||||
|
@ -430,10 +430,93 @@ __emitinline void xAdvancePtr( uint bytes )
|
|||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xAddressInfo Method Implementations
|
||||
// xAddressReg (operator overloads)
|
||||
// --------------------------------------------------------------------------------------
|
||||
xAddressVoid xAddressReg::operator+( const xAddressReg& right ) const
|
||||
{
|
||||
pxAssertMsg( right.Id != -1 || Id != -1, "Uninitialized x86 register." );
|
||||
return xAddressVoid( *this, right );
|
||||
}
|
||||
|
||||
xAddressVoid xAddressReg::operator+( s32 right ) const
|
||||
{
|
||||
pxAssertMsg( Id != -1, "Uninitialized x86 register." );
|
||||
return xAddressVoid( *this, right );
|
||||
}
|
||||
|
||||
xAddressVoid xAddressReg::operator+( const void* right ) const
|
||||
{
|
||||
pxAssertMsg( Id != -1, "Uninitialized x86 register." );
|
||||
return xAddressVoid( *this, (sptr)right );
|
||||
}
|
||||
|
||||
xAddressVoid xAddressReg::operator-( s32 right ) const
|
||||
{
|
||||
pxAssertMsg( Id != -1, "Uninitialized x86 register." );
|
||||
return xAddressVoid( *this, -right );
|
||||
}
|
||||
|
||||
xAddressVoid xAddressReg::operator-( const void* right ) const
|
||||
{
|
||||
pxAssertMsg( Id != -1, "Uninitialized x86 register." );
|
||||
return xAddressVoid( *this, -(s32)right );
|
||||
}
|
||||
|
||||
xAddressVoid xAddressReg::operator*( u32 factor ) const
|
||||
{
|
||||
pxAssertMsg( Id != -1, "Uninitialized x86 register." );
|
||||
return xAddressVoid( xEmptyReg, *this, factor );
|
||||
}
|
||||
|
||||
xAddressVoid xAddressReg::operator<<( u32 shift ) const
|
||||
{
|
||||
pxAssertMsg( Id != -1, "Uninitialized x86 register." );
|
||||
return xAddressVoid( xEmptyReg, *this, 1<<shift );
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xAddressVoid (method implementations)
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
xAddressInfo& xAddressInfo::Add( const xAddressReg& src )
|
||||
xAddressVoid::xAddressVoid( const xAddressReg& base, const xAddressReg& index, int factor, s32 displacement )
|
||||
{
|
||||
Base = base;
|
||||
Index = index;
|
||||
Factor = factor;
|
||||
Displacement= displacement;
|
||||
|
||||
pxAssertMsg( base.Id != xRegId_Invalid, "Uninitialized x86 register." );
|
||||
pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." );
|
||||
}
|
||||
|
||||
xAddressVoid::xAddressVoid( const xAddressReg& index, int displacement )
|
||||
{
|
||||
Base = xEmptyReg;
|
||||
Index = index;
|
||||
Factor = 0;
|
||||
Displacement= displacement;
|
||||
|
||||
pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." );
|
||||
}
|
||||
|
||||
xAddressVoid::xAddressVoid( s32 displacement )
|
||||
{
|
||||
Base = xEmptyReg;
|
||||
Index = xEmptyReg;
|
||||
Factor = 0;
|
||||
Displacement= displacement;
|
||||
}
|
||||
|
||||
xAddressVoid::xAddressVoid( const void* displacement )
|
||||
{
|
||||
Base = xEmptyReg;
|
||||
Index = xEmptyReg;
|
||||
Factor = 0;
|
||||
Displacement= (s32)displacement;
|
||||
}
|
||||
|
||||
xAddressVoid& xAddressVoid::Add( const xAddressReg& src )
|
||||
{
|
||||
if( src == Index )
|
||||
{
|
||||
|
@ -463,7 +546,7 @@ xAddressInfo& xAddressInfo::Add( const xAddressReg& src )
|
|||
return *this;
|
||||
}
|
||||
|
||||
xAddressInfo& xAddressInfo::Add( const xAddressInfo& src )
|
||||
xAddressVoid& xAddressVoid::Add( const xAddressVoid& src )
|
||||
{
|
||||
Add( src.Base );
|
||||
Add( src.Displacement );
|
||||
|
@ -488,7 +571,7 @@ xAddressInfo& xAddressInfo::Add( const xAddressInfo& src )
|
|||
return *this;
|
||||
}
|
||||
|
||||
ModSibBase::ModSibBase( const xAddressInfo& src )
|
||||
xIndirectVoid::xIndirectVoid( const xAddressVoid& src )
|
||||
{
|
||||
Base = src.Base;
|
||||
Index = src.Index;
|
||||
|
@ -498,7 +581,7 @@ ModSibBase::ModSibBase( const xAddressInfo& src )
|
|||
Reduce();
|
||||
}
|
||||
|
||||
ModSibBase::ModSibBase( s32 disp )
|
||||
xIndirectVoid::xIndirectVoid( s32 disp )
|
||||
{
|
||||
Base = xEmptyReg;
|
||||
Index = xEmptyReg;
|
||||
|
@ -508,7 +591,7 @@ ModSibBase::ModSibBase( s32 disp )
|
|||
// no reduction necessary :D
|
||||
}
|
||||
|
||||
ModSibBase::ModSibBase( xAddressReg base, xAddressReg index, int scale, s32 displacement )
|
||||
xIndirectVoid::xIndirectVoid( xAddressReg base, xAddressReg index, int scale, s32 displacement )
|
||||
{
|
||||
Base = base;
|
||||
Index = index;
|
||||
|
@ -531,7 +614,7 @@ ModSibBase::ModSibBase( xAddressReg base, xAddressReg index, int scale, s32 disp
|
|||
// but it's too much trouble for code that isn't performance critical anyway.
|
||||
// And, with luck, maybe VC10 will optimize it better and make it a non-issue. :D
|
||||
//
|
||||
void ModSibBase::Reduce()
|
||||
void xIndirectVoid::Reduce()
|
||||
{
|
||||
if( Index.IsStackPointer() )
|
||||
{
|
||||
|
@ -595,13 +678,13 @@ void ModSibBase::Reduce()
|
|||
}
|
||||
}
|
||||
|
||||
uint ModSibBase::GetOperandSize() const
|
||||
uint xIndirectVoid::GetOperandSize() const
|
||||
{
|
||||
pxFail( "Invalid operation on ModSibBase" );
|
||||
pxFail( "Invalid operation on xIndirectVoid" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
ModSibBase& ModSibBase::Add( s32 imm )
|
||||
xIndirectVoid& xIndirectVoid::Add( s32 imm )
|
||||
{
|
||||
Displacement += imm;
|
||||
return *this;
|
||||
|
@ -615,7 +698,7 @@ ModSibBase& ModSibBase::Add( s32 imm )
|
|||
// preserve_flags - set to ture to disable use of SHL on [Index*Base] forms
|
||||
// of LEA, which alters flags states.
|
||||
//
|
||||
static void EmitLeaMagic( const xRegisterInt& to, const ModSibBase& src, bool preserve_flags )
|
||||
static void EmitLeaMagic( const xRegisterInt& to, const xIndirectVoid& src, bool preserve_flags )
|
||||
{
|
||||
int displacement_size = (src.Displacement == 0) ? 0 :
|
||||
( ( src.IsByteSizeDisp() ) ? 1 : 2 );
|
||||
|
@ -730,13 +813,13 @@ static void EmitLeaMagic( const xRegisterInt& to, const ModSibBase& src, bool pr
|
|||
}
|
||||
}
|
||||
|
||||
__emitinline void xLEA( xRegister32 to, const ModSibBase& src, bool preserve_flags )
|
||||
__emitinline void xLEA( xRegister32 to, const xIndirectVoid& src, bool preserve_flags )
|
||||
{
|
||||
EmitLeaMagic( to, src, preserve_flags );
|
||||
}
|
||||
|
||||
|
||||
__emitinline void xLEA( xRegister16 to, const ModSibBase& src, bool preserve_flags )
|
||||
__emitinline void xLEA( xRegister16 to, const xIndirectVoid& src, bool preserve_flags )
|
||||
{
|
||||
xWrite8( 0x66 );
|
||||
EmitLeaMagic( to, src, preserve_flags );
|
||||
|
@ -764,7 +847,7 @@ void xImpl_Test::operator()( const xRegister32& to, const xRegister32& from ) co
|
|||
EmitSibMagic( from, to );
|
||||
}
|
||||
|
||||
void xImpl_Test::operator()( const ModSib32orLess& dest, int imm ) const
|
||||
void xImpl_Test::operator()( const xIndirect32orLess& dest, int imm ) const
|
||||
{
|
||||
dest.prefix16();
|
||||
xWrite8( dest.Is8BitOp() ? 0xf6 : 0xf7 );
|
||||
|
@ -788,7 +871,7 @@ void xImpl_Test::operator()( const xRegisterInt& to, int imm ) const
|
|||
|
||||
void xImpl_BitScan::operator()( const xRegister32& to, const xRegister32& from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
void xImpl_BitScan::operator()( const xRegister16& to, const xRegister16& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); }
|
||||
void xImpl_BitScan::operator()( const xRegister16or32& to, const ModSibBase& sibsrc ) const
|
||||
void xImpl_BitScan::operator()( const xRegister16or32& to, const xIndirectVoid& sibsrc ) const
|
||||
{
|
||||
xOpWrite0F( (to->GetOperandSize() == 2) ? 0x66 : 0x00, Opcode, to, sibsrc );
|
||||
}
|
||||
|
@ -807,7 +890,7 @@ void xImpl_IncDec::operator()( const xRegisterInt& to ) const
|
|||
}
|
||||
}
|
||||
|
||||
void xImpl_IncDec::operator()( const ModSib32orLess& to ) const
|
||||
void xImpl_IncDec::operator()( const xIndirect32orLess& to ) const
|
||||
{
|
||||
to.prefix16();
|
||||
xWrite8( to.Is8BitOp() ? 0xfe : 0xff );
|
||||
|
@ -827,12 +910,12 @@ void xImpl_DwordShift::operator()( const xRegister16& to, const xRegister16& fro
|
|||
xOpWrite0F( 0x66, OpcodeBase, to, from );
|
||||
}
|
||||
|
||||
void xImpl_DwordShift::operator()( const ModSibBase& dest, const xRegister16or32& from, const xRegisterCL& /* clreg */ ) const
|
||||
void xImpl_DwordShift::operator()( const xIndirectVoid& dest, const xRegister16or32& from, const xRegisterCL& /* clreg */ ) const
|
||||
{
|
||||
xOpWrite0F( (from->GetOperandSize() == 2) ? 0x66 : 0x00, OpcodeBase, from, dest );
|
||||
}
|
||||
|
||||
void xImpl_DwordShift::operator()( const ModSibBase& dest, const xRegister16or32& from, u8 shiftcnt ) const
|
||||
void xImpl_DwordShift::operator()( const xIndirectVoid& dest, const xRegister16or32& from, u8 shiftcnt ) const
|
||||
{
|
||||
if( shiftcnt != 0 )
|
||||
xOpWrite0F( (from->GetOperandSize() == 2) ? 0x66 : 0x00, OpcodeBase, from, dest, shiftcnt );
|
||||
|
@ -855,13 +938,13 @@ const xImpl_DwordShift xSHRD = { 0xac };
|
|||
// Note: pushad/popad implementations are intentionally left out. The instructions are
|
||||
// invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead.
|
||||
|
||||
__emitinline void xPOP( const ModSibBase& from )
|
||||
__emitinline void xPOP( const xIndirectVoid& from )
|
||||
{
|
||||
xWrite8( 0x8f );
|
||||
EmitSibMagic( 0, from );
|
||||
}
|
||||
|
||||
__emitinline void xPUSH( const ModSibBase& from )
|
||||
__emitinline void xPUSH( const xIndirectVoid& from )
|
||||
{
|
||||
xWrite8( 0xff );
|
||||
EmitSibMagic( 6, from );
|
||||
|
|
|
@ -57,26 +57,24 @@ public:
|
|||
operator xRegisterSSE() const { return m_reg; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Moves 128 bits from point B to point A, using SSE's MOVAPS (or MOVDQA).
|
||||
// This instruction always uses an SSE register, even if all registers are allocated! It
|
||||
// saves an SSE register to memory first, performs the copy, and restores the register.
|
||||
//
|
||||
void iMOV128_SSE( const ModSibBase& destRm, const ModSibBase& srcRm )
|
||||
static void iMOV128_SSE( const xIndirectVoid& destRm, const xIndirectVoid& srcRm )
|
||||
{
|
||||
iAllocRegSSE reg;
|
||||
xMOVDQA( reg, srcRm );
|
||||
xMOVDQA( destRm, reg );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Moves 64 bits of data from point B to point A, using either MMX, SSE, or x86 registers
|
||||
// if neither MMX nor SSE is available to the task.
|
||||
//
|
||||
// Optimizations: This method uses MMX is the cpu is in MMX mode, or SSE if it's in FPU
|
||||
// mode (saving on potential EMMS uses).
|
||||
//
|
||||
void iMOV64_Smart( const ModSibBase& destRm, const ModSibBase& srcRm )
|
||||
static void iMOV64_Smart( const xIndirectVoid& destRm, const xIndirectVoid& srcRm )
|
||||
{
|
||||
if( (x86FpuState == FPU_STATE) && _hasFreeXMMreg() )
|
||||
{
|
||||
|
|
|
@ -123,7 +123,7 @@ void VifUnpackSSE_Dynarec::writeBackRow() const {
|
|||
// ToDo: Do we need to write back to vifregs.rX too!? :/
|
||||
}
|
||||
|
||||
static void ShiftDisplacementWindow( xAddressInfo& addr, const xRegister32& modReg )
|
||||
static void ShiftDisplacementWindow( xAddressVoid& addr, const xRegister32& modReg )
|
||||
{
|
||||
// Shifts the displacement factor of a given indirect address, so that the address
|
||||
// remains in the optimal 0xf0 range (which allows for byte-form displacements when
|
||||
|
|
|
@ -43,6 +43,7 @@ void loadRowCol(nVifStruct& v) {
|
|||
xMOVAPS(xmm1, ptr32[&v.vifRegs->r1]);
|
||||
xMOVAPS(xmm2, ptr32[&v.vifRegs->r2]);
|
||||
xMOVAPS(xmm6, ptr32[&v.vifRegs->r3]);
|
||||
|
||||
xPSHUF.D(xmm0, xmm0, _v0);
|
||||
xPSHUF.D(xmm1, xmm1, _v0);
|
||||
xPSHUF.D(xmm2, xmm2, _v0);
|
||||
|
|
|
@ -37,8 +37,8 @@ public:
|
|||
bool doMask; // masking write enable flag
|
||||
|
||||
protected:
|
||||
xAddressInfo dstIndirect;
|
||||
xAddressInfo srcIndirect;
|
||||
xAddressVoid dstIndirect;
|
||||
xAddressVoid srcIndirect;
|
||||
xRegisterSSE workReg;
|
||||
xRegisterSSE destReg;
|
||||
|
||||
|
|
|
@ -801,7 +801,7 @@ void _saveEAX(VURegs *VU, int x86reg, uptr offset, int info)
|
|||
|
||||
// (this is one of my test cases for the new emitter --air)
|
||||
using namespace x86Emitter;
|
||||
xAddressInfo indexer( offset );
|
||||
xAddressVoid indexer( offset );
|
||||
if( x86reg != -1 ) indexer.Add( xAddressReg( x86reg ) );
|
||||
|
||||
if ( _X ) xMOV(ptr32[indexer], 0x00000000);
|
||||
|
|
Loading…
Reference in New Issue