mirror of https://github.com/PCSX2/pcsx2.git
commit
9e773ff980
|
@ -31,11 +31,12 @@ namespace x86Emitter {
|
|||
extern void EmitSibMagic( const xRegisterBase& reg1, const void* src );
|
||||
extern void EmitSibMagic( const xRegisterBase& reg1, const xIndirectVoid& sib );
|
||||
|
||||
void EmitRex( const xRegisterBase& reg1, const xRegisterBase& reg2 );
|
||||
void EmitRex( const xRegisterBase& reg1, const void* src );
|
||||
void EmitRex( const xRegisterBase& reg1, const xIndirectVoid& sib );
|
||||
void EmitRex( const xRegisterBase& reg1 );
|
||||
void EmitRex( const xIndirectVoid& sib );
|
||||
extern void EmitRex( uint regfield, const void* address );
|
||||
extern void EmitRex( uint regfield, const xIndirectVoid& info );
|
||||
extern void EmitRex( uint reg1, const xRegisterBase& reg2 );
|
||||
extern void EmitRex( const xRegisterBase& reg1, const xRegisterBase& reg2 );
|
||||
extern void EmitRex( const xRegisterBase& reg1, const void* src );
|
||||
extern void EmitRex( const xRegisterBase& reg1, const xIndirectVoid& sib );
|
||||
|
||||
extern void _xMovRtoR( const xRegisterInt& to, const xRegisterInt& from );
|
||||
|
||||
|
@ -49,18 +50,42 @@ namespace x86Emitter {
|
|||
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 );
|
||||
if( prefix != 0 ) xWrite8( prefix );
|
||||
EmitRex( param1, param2 );
|
||||
|
||||
xWrite8( opcode );
|
||||
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpAccWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
if( prefix != 0 ) xWrite8( prefix );
|
||||
EmitRex( param1, param2 );
|
||||
|
||||
xWrite8( opcode );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// emitter helpers for xmm instruction with prefixes, most of which are using
|
||||
// the basic opcode format (items inside braces denote optional or conditional
|
||||
// emission):
|
||||
//
|
||||
// [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB]
|
||||
//
|
||||
// Prefixes are typically 0x66, 0xf2, or 0xf3. OpcodePrefixes are either 0x38 or
|
||||
// 0x3a [and other value will result in assertion failue].
|
||||
//
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
SimdPrefix( prefix, opcode );
|
||||
if( prefix != 0 ) xWrite8( prefix );
|
||||
EmitRex( param1, param2 );
|
||||
|
||||
SimdPrefix( 0, opcode );
|
||||
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
|
||||
|
|
|
@ -45,15 +45,15 @@ static void _g1_IndirectImm( G1Type InstType, const xIndirect64orLess& sibdest,
|
|||
{
|
||||
if( sibdest.Is8BitOp() )
|
||||
{
|
||||
xWrite8( 0x80 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
xOpWrite( sibdest.GetPrefix16(), 0x80, InstType, sibdest );
|
||||
|
||||
xWrite<s8>( imm );
|
||||
}
|
||||
else
|
||||
{
|
||||
sibdest.prefix16();
|
||||
xWrite8( is_s8( imm ) ? 0x83 : 0x81 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
u8 opcode = is_s8( imm ) ? 0x83 : 0x81;
|
||||
xOpWrite( sibdest.GetPrefix16(), opcode, InstType, sibdest );
|
||||
|
||||
if( is_s8( imm ) )
|
||||
xWrite<s8>( imm );
|
||||
else
|
||||
|
@ -64,42 +64,40 @@ static void _g1_IndirectImm( G1Type InstType, const xIndirect64orLess& sibdest,
|
|||
void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xRegisterInt& from )
|
||||
{
|
||||
pxAssert( to.GetOperandSize() == from.GetOperandSize() );
|
||||
to.prefix16();
|
||||
xWrite8( (to.Is8BitOp() ? 0 : 1) | (InstType<<3) );
|
||||
EmitSibMagic( from, to );
|
||||
|
||||
u8 opcode = (to.Is8BitOp() ? 0 : 1) | (InstType<<3);
|
||||
xOpWrite( to.GetPrefix16(), opcode, from, to );
|
||||
}
|
||||
|
||||
static void _g1_EmitOp( G1Type InstType, const xIndirectVoid& sibdest, const xRegisterInt& from )
|
||||
{
|
||||
from.prefix16();
|
||||
xWrite8( (from.Is8BitOp() ? 0 : 1) | (InstType<<3) );
|
||||
EmitSibMagic( from, sibdest );
|
||||
u8 opcode = (from.Is8BitOp() ? 0 : 1) | (InstType<<3);
|
||||
xOpWrite( from.GetPrefix16(), opcode, from, sibdest );
|
||||
}
|
||||
|
||||
static void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xIndirectVoid& sibsrc )
|
||||
{
|
||||
to.prefix16();
|
||||
xWrite8( (to.Is8BitOp() ? 2 : 3) | (InstType<<3) );
|
||||
EmitSibMagic( to, sibsrc );
|
||||
u8 opcode = (to.Is8BitOp() ? 2 : 3) | (InstType<<3);
|
||||
xOpWrite( to.GetPrefix16(), opcode, to, sibsrc );
|
||||
}
|
||||
|
||||
static void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, int imm )
|
||||
{
|
||||
to.prefix16();
|
||||
if( !to.Is8BitOp() && is_s8( imm ) )
|
||||
{
|
||||
xWrite8( 0x83 );
|
||||
EmitSibMagic( InstType, to );
|
||||
xOpWrite( to.GetPrefix16(), 0x83, InstType, to );
|
||||
xWrite<s8>( imm );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( to.IsAccumulator() )
|
||||
xWrite8( (to.Is8BitOp() ? 4 : 5) | (InstType<<3) );
|
||||
if( to.IsAccumulator() ) {
|
||||
u8 opcode = (to.Is8BitOp() ? 4 : 5) | (InstType<<3);
|
||||
xOpAccWrite( to.GetPrefix16(), opcode, InstType, to );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite8( to.Is8BitOp() ? 0x80 : 0x81 );
|
||||
EmitSibMagic( InstType, to );
|
||||
u8 opcode = to.Is8BitOp() ? 0x80 : 0x81;
|
||||
xOpWrite( to.GetPrefix16(), opcode, InstType, to );
|
||||
}
|
||||
to.xWriteImm( imm );
|
||||
}
|
||||
|
@ -134,52 +132,42 @@ const xImpl_Group1 xSBB = { G1Type_SBB };
|
|||
|
||||
void xImpl_Group2::operator()( const xRegisterInt& to, const xRegisterCL& /* from */ ) const
|
||||
{
|
||||
to.prefix16();
|
||||
xWrite8( to.Is8BitOp() ? 0xd2 : 0xd3 );
|
||||
EmitSibMagic( InstType, to );
|
||||
xOpWrite( to.GetPrefix16(), to.Is8BitOp() ? 0xd2 : 0xd3, InstType, to );
|
||||
}
|
||||
|
||||
void xImpl_Group2::operator()(const xRegisterInt& to, u8 imm ) const
|
||||
{
|
||||
if( imm == 0 ) return;
|
||||
|
||||
to.prefix16();
|
||||
if( imm == 1 )
|
||||
{
|
||||
// special encoding of 1's
|
||||
xWrite8( to.Is8BitOp() ? 0xd0 : 0xd1 );
|
||||
EmitSibMagic( InstType, to );
|
||||
xOpWrite( to.GetPrefix16(), to.Is8BitOp() ? 0xd0 : 0xd1, InstType, to );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite8( to.Is8BitOp() ? 0xc0 : 0xc1 );
|
||||
EmitSibMagic( InstType, to );
|
||||
xOpWrite( to.GetPrefix16(), to.Is8BitOp() ? 0xc0 : 0xc1, InstType, to );
|
||||
xWrite8( imm );
|
||||
}
|
||||
}
|
||||
|
||||
void xImpl_Group2::operator()( const xIndirect64orLess& sibdest, const xRegisterCL& /* from */ ) const
|
||||
{
|
||||
sibdest.prefix16();
|
||||
xWrite8( sibdest.Is8BitOp() ? 0xd2 : 0xd3 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
xOpWrite( sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd2 : 0xd3, InstType, sibdest );
|
||||
}
|
||||
|
||||
void xImpl_Group2::operator()( const xIndirect64orLess& sibdest, u8 imm ) const
|
||||
{
|
||||
if( imm == 0 ) return;
|
||||
|
||||
sibdest.prefix16();
|
||||
if( imm == 1 )
|
||||
{
|
||||
// special encoding of 1's
|
||||
xWrite8( sibdest.Is8BitOp() ? 0xd0 : 0xd1 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
xOpWrite( sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd0 : 0xd1, InstType, sibdest );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite8( sibdest.Is8BitOp() ? 0xc0 : 0xc1 );
|
||||
EmitSibMagic( InstType, sibdest );
|
||||
xOpWrite( sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xc0 : 0xc1, InstType, sibdest );
|
||||
xWrite8( imm );
|
||||
}
|
||||
}
|
||||
|
@ -199,16 +187,12 @@ const xImpl_Group2 xSAR = { G2Type_SAR };
|
|||
|
||||
static void _g3_EmitOp( G3Type InstType, const xRegisterInt& from )
|
||||
{
|
||||
from.prefix16();
|
||||
xWrite8(from.Is8BitOp() ? 0xf6 : 0xf7 );
|
||||
EmitSibMagic( InstType, from );
|
||||
xOpWrite( from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from );
|
||||
}
|
||||
|
||||
static void _g3_EmitOp( G3Type InstType, const xIndirect64orLess& from )
|
||||
{
|
||||
from.prefix16();
|
||||
xWrite8( from.Is8BitOp() ? 0xf6 : 0xf7 );
|
||||
EmitSibMagic( InstType, from );
|
||||
xOpWrite( from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from );
|
||||
}
|
||||
|
||||
void xImpl_Group3::operator()( const xRegisterInt& from ) const { _g3_EmitOp( InstType, from ); }
|
||||
|
@ -220,13 +204,9 @@ void xImpl_iDiv::operator()( const xIndirect64orLess& from ) const { _g3_EmitO
|
|||
template< typename SrcType >
|
||||
static void _imul_ImmStyle( const xRegisterInt& param1, const SrcType& param2, int imm )
|
||||
{
|
||||
// for iMul OpSize is allowed to be 16 or 32 bit only.
|
||||
const uint OpSize = param1.GetOperandSize();
|
||||
pxAssert( param1.GetOperandSize() == param2.GetOperandSize() );
|
||||
|
||||
pxAssert( OpSize == param2.GetOperandSize() );
|
||||
pxAssert( OpSize > 1 );
|
||||
|
||||
xOpWrite0F( (OpSize == 2) ? 0x66 : 0, is_s8( imm ) ? 0x6b : 0x69, param1, param2 );
|
||||
xOpWrite0F( param1.GetPrefix16(), is_s8( imm ) ? 0x6b : 0x69, param1, param2 );
|
||||
|
||||
if( is_s8( imm ) )
|
||||
xWrite8( (u8)imm );
|
||||
|
|
|
@ -40,9 +40,7 @@ void _xMovRtoR( const xRegisterInt& to, const xRegisterInt& from )
|
|||
|
||||
if( to == from ) return; // ignore redundant MOVs.
|
||||
|
||||
from.prefix16();
|
||||
xWrite8( from.Is8BitOp() ? 0x88 : 0x89 );
|
||||
EmitSibMagic( from, to );
|
||||
xOpWrite( from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, to );
|
||||
}
|
||||
|
||||
void xImpl_Mov::operator()( const xRegisterInt& to, const xRegisterInt& from ) const
|
||||
|
@ -53,47 +51,47 @@ void xImpl_Mov::operator()( const xRegisterInt& to, const xRegisterInt& from ) c
|
|||
|
||||
void xImpl_Mov::operator()( const xIndirectVoid& dest, const xRegisterInt& from ) const
|
||||
{
|
||||
from.prefix16();
|
||||
|
||||
// mov eax has a special from when writing directly to a DISP32 address
|
||||
// (sans any register index/base registers).
|
||||
|
||||
if( from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty() )
|
||||
{
|
||||
xWrite8( from.Is8BitOp() ? 0xa2 : 0xa3 );
|
||||
// FIXME: in 64 bits, it could be 8B whereas Displacement is limited to 4B normally
|
||||
#ifdef __x86_64__
|
||||
pxAssert(0);
|
||||
#endif
|
||||
xOpAccWrite( from.GetPrefix16(), from.Is8BitOp() ? 0xa2 : 0xa3, from.Id, dest );
|
||||
xWrite32( dest.Displacement );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite8( from.Is8BitOp() ? 0x88 : 0x89 );
|
||||
EmitSibMagic( from.Id, dest );
|
||||
xOpWrite( from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from.Id, dest );
|
||||
}
|
||||
}
|
||||
|
||||
void xImpl_Mov::operator()( const xRegisterInt& to, const xIndirectVoid& src ) const
|
||||
{
|
||||
to.prefix16();
|
||||
|
||||
// mov eax has a special from when reading directly from a DISP32 address
|
||||
// (sans any register index/base registers).
|
||||
|
||||
if( to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty() )
|
||||
{
|
||||
xWrite8( to.Is8BitOp() ? 0xa0 : 0xa1 );
|
||||
// FIXME: in 64 bits, it could be 8B whereas Displacement is limited to 4B normally
|
||||
#ifdef __x86_64__
|
||||
pxAssert(0);
|
||||
#endif
|
||||
xOpAccWrite( to.GetPrefix16(), to.Is8BitOp() ? 0xa0 : 0xa1, to, src );
|
||||
xWrite32( src.Displacement );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite8( to.Is8BitOp() ? 0x8a : 0x8b );
|
||||
EmitSibMagic( to, src );
|
||||
xOpWrite( to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src );
|
||||
}
|
||||
}
|
||||
|
||||
void xImpl_Mov::operator()( const xIndirect64orLess& dest, int imm ) const
|
||||
{
|
||||
dest.prefix16();
|
||||
xWrite8( dest.Is8BitOp() ? 0xc6 : 0xc7 );
|
||||
EmitSibMagic( 0, dest );
|
||||
xOpWrite( dest.GetPrefix16(), dest.Is8BitOp() ? 0xc6 : 0xc7, 0, dest );
|
||||
dest.xWriteImm( imm );
|
||||
}
|
||||
|
||||
|
@ -106,9 +104,8 @@ void xImpl_Mov::operator()( const xRegisterInt& to, int imm, bool preserve_flags
|
|||
else
|
||||
{
|
||||
// Note: MOV does not have (reg16/32,imm8) forms.
|
||||
|
||||
to.prefix16();
|
||||
xWrite8( (to.Is8BitOp() ? 0xb0 : 0xb8) | to.Id );
|
||||
u8 opcode = (to.Is8BitOp() ? 0xb0 : 0xb8) | to.Id;
|
||||
xOpAccWrite( to.GetPrefix16(), opcode, 0, to);
|
||||
to.xWriteImm( imm );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,9 @@ namespace x86Emitter {
|
|||
//
|
||||
__emitinline void SimdPrefix( u8 prefix, u16 opcode )
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
pxAssertMsg(prefix == 0, "REX prefix must be just before the opcode");
|
||||
#endif
|
||||
const bool is16BitOpcode = ((opcode & 0xff) == 0x38) || ((opcode & 0xff) == 0x3a);
|
||||
|
||||
// If the lower byte is not a valid prefix and the upper byte is non-zero it
|
||||
|
@ -220,15 +223,13 @@ void _SimdShiftHelper::operator()( const xRegisterMMX& to, const xIndirectVoid&
|
|||
|
||||
void _SimdShiftHelper::operator()( const xRegisterSSE& to, u8 imm8 ) const
|
||||
{
|
||||
SimdPrefix( 0x66, OpcodeImm );
|
||||
EmitSibMagic( (int)Modcode, to );
|
||||
xOpWrite0F( 0x66, OpcodeImm, (int)Modcode, to );
|
||||
xWrite8( imm8 );
|
||||
}
|
||||
|
||||
void _SimdShiftHelper::operator()( const xRegisterMMX& to, u8 imm8 ) const
|
||||
{
|
||||
SimdPrefix( 0x00, OpcodeImm );
|
||||
EmitSibMagic( (int)Modcode, to );
|
||||
xOpWrite0F( 0x00, OpcodeImm, (int)Modcode, to );
|
||||
xWrite8( imm8 );
|
||||
}
|
||||
|
||||
|
@ -747,8 +748,7 @@ IMPLEMENT_xMOVS( SD, 0xf2 )
|
|||
|
||||
__fi void xMOVNTDQA( const xRegisterSSE& to, const xIndirectVoid& from )
|
||||
{
|
||||
xWrite32( 0x2A380f66 );
|
||||
EmitSibMagic( to.Id, from );
|
||||
xOpWrite0F( 0x66, 0x2a38, to.Id, from);
|
||||
}
|
||||
|
||||
__fi void xMOVNTDQA( const xIndirectVoid& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xe7, from, to ); }
|
||||
|
@ -833,31 +833,27 @@ __fi void xEMMS() { xWrite16( 0x770F ); }
|
|||
// Store Streaming SIMD Extension Control/Status to Mem32.
|
||||
__emitinline void xSTMXCSR( const xIndirect32& dest )
|
||||
{
|
||||
SimdPrefix( 0, 0xae );
|
||||
EmitSibMagic( 3, dest );
|
||||
xOpWrite0F( 0, 0xae, 3, dest );
|
||||
}
|
||||
|
||||
// Load Streaming SIMD Extension Control/Status from Mem32.
|
||||
__emitinline void xLDMXCSR( const xIndirect32& src )
|
||||
{
|
||||
SimdPrefix( 0, 0xae );
|
||||
EmitSibMagic( 2, src );
|
||||
xOpWrite0F( 0, 0xae, 2, 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 xIndirectVoid& dest )
|
||||
{
|
||||
SimdPrefix( 0, 0xae );
|
||||
EmitSibMagic( 0, dest );
|
||||
xOpWrite0F( 0, 0xae, 0, dest );
|
||||
}
|
||||
|
||||
// Restore x87 FPU, MMX , XMM, and MXCSR State.
|
||||
// Source buffer should be 512 bytes in length.
|
||||
__emitinline void xFXRSTOR( const xIndirectVoid& src )
|
||||
{
|
||||
SimdPrefix( 0, 0xae );
|
||||
EmitSibMagic( 1, src );
|
||||
xOpWrite0F( 0, 0xae, 1, src );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -266,34 +266,6 @@ void EmitSibMagic( uint regfield, const void* address )
|
|||
xWrite<s32>( (s32)displacement );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// emitter helpers for xmm instruction with prefixes, most of which are using
|
||||
// the basic opcode format (items inside braces denote optional or conditional
|
||||
// emission):
|
||||
//
|
||||
// [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB]
|
||||
//
|
||||
// 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 xIndirectVoid& sib )
|
||||
{
|
||||
SimdPrefix( prefix, opcode );
|
||||
EmitSibMagic( instId, sib );
|
||||
}
|
||||
|
||||
__emitinline void xOpWrite0F( u8 prefix, u16 opcode, int instId, const void* data )
|
||||
{
|
||||
SimdPrefix( prefix, opcode );
|
||||
EmitSibMagic( instId, data );
|
||||
}
|
||||
|
||||
__emitinline void xOpWrite0F( u16 opcode, int instId, const xIndirectVoid& sib )
|
||||
{
|
||||
xOpWrite0F( 0, opcode, instId, sib );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// returns TRUE if this instruction requires SIB to be encoded, or FALSE if the
|
||||
// instruction ca be encoded as ModRm alone.
|
||||
|
@ -406,51 +378,71 @@ void EmitSibMagic( const xRegisterBase& reg1, const xIndirectVoid& sib )
|
|||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
__emitinline static void EmitRex(bool w, bool r, bool x, bool b)
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
u8 rex = 0x40 | (w << 3) | (r << 2) | (x << 1) | b;
|
||||
if (rex != 0x40)
|
||||
xWrite8(rex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void EmitRex( uint regfield, const void* address )
|
||||
{
|
||||
pxAssert(0);
|
||||
bool w = false;
|
||||
bool r = false;
|
||||
bool x = false;
|
||||
bool b = false;
|
||||
EmitRex(w, r, x, b);
|
||||
}
|
||||
|
||||
void EmitRex( uint regfield, const xIndirectVoid& info )
|
||||
{
|
||||
bool w = info.Base.IsWide();
|
||||
bool r = false;
|
||||
bool x = false;
|
||||
bool b = info.IsExtended();
|
||||
EmitRex(w, r, x, b);
|
||||
}
|
||||
|
||||
void EmitRex( uint reg1, const xRegisterBase& reg2 )
|
||||
{
|
||||
bool w = reg2.IsWide();
|
||||
bool r = false;
|
||||
bool x = false;
|
||||
bool b = reg2.IsExtended();
|
||||
EmitRex(w, r, x, b);
|
||||
}
|
||||
|
||||
void EmitRex( const xRegisterBase& reg1, const xRegisterBase& reg2 )
|
||||
{
|
||||
u8 w = reg1.IsWide() << 3;
|
||||
u8 r = reg1.IsExtended() << 2;
|
||||
u8 x = 0;
|
||||
u8 b = reg2.IsExtended();
|
||||
xWrite8( 0x40 | w | r | x | b );
|
||||
bool w = reg1.IsWide();
|
||||
bool r = reg1.IsExtended();
|
||||
bool x = false;
|
||||
bool b = reg2.IsExtended();
|
||||
EmitRex(w, r, x, b);
|
||||
}
|
||||
|
||||
void EmitRex( const xRegisterBase& reg1, const void* src )
|
||||
{
|
||||
pxAssert(0); //see fixme
|
||||
u8 w = reg1.IsWide() << 3;
|
||||
u8 r = reg1.IsExtended() << 2;
|
||||
u8 x = 0;
|
||||
u8 b = 0; // FIXME src.IsExtended();
|
||||
xWrite8( 0x40 | w | r | x | b );
|
||||
bool w = reg1.IsWide();
|
||||
bool r = reg1.IsExtended();
|
||||
bool x = false;
|
||||
bool b = false; // FIXME src.IsExtended();
|
||||
EmitRex(w, r, x, b);
|
||||
}
|
||||
|
||||
void EmitRex( const xRegisterBase& reg1, const xIndirectVoid& sib )
|
||||
{
|
||||
u8 w = reg1.IsWide() << 3;
|
||||
u8 r = reg1.IsExtended() << 2;
|
||||
u8 x = sib.Index.IsExtended() << 1;
|
||||
u8 w = reg1.IsWide();
|
||||
u8 r = reg1.IsExtended();
|
||||
u8 x = sib.Index.IsExtended();
|
||||
u8 b = sib.Base.IsExtended();
|
||||
xWrite8( 0x40 | w | r | x | b );
|
||||
EmitRex(w, r, x, b);
|
||||
}
|
||||
|
||||
void EmitRex( const xRegisterBase& reg1)
|
||||
{
|
||||
u8 w = reg1.IsWide() << 3;
|
||||
u8 r = 0;
|
||||
u8 x = 0;
|
||||
u8 b = reg1.IsExtended();
|
||||
xWrite8( 0x40 | w | r | x | b );
|
||||
}
|
||||
|
||||
void EmitRex( const xIndirectVoid& sib)
|
||||
{
|
||||
u8 w = sib.Base.IsWide() << 3;
|
||||
u8 r = 0;
|
||||
u8 x = 0;
|
||||
u8 b = sib.IsExtended();
|
||||
xWrite8( 0x40 | w | r | x | b );
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// xSetPtr / xAlignPtr / xGetPtr / xAdvancePtr
|
||||
|
@ -929,29 +921,21 @@ __emitinline void xLEA( xRegister16 to, const xIndirectVoid& src, bool preserve_
|
|||
void xImpl_Test::operator()( const xRegisterInt& to, const xRegisterInt& from ) const
|
||||
{
|
||||
pxAssert( to.GetOperandSize() == from.GetOperandSize() );
|
||||
to.prefix16();
|
||||
xWrite8( to.Is8BitOp() ? 0x84 : 0x85 );
|
||||
EmitSibMagic( from, to );
|
||||
xOpWrite( to.GetPrefix16(), to.Is8BitOp() ? 0x84 : 0x85, from, to );
|
||||
}
|
||||
|
||||
void xImpl_Test::operator()( const xIndirect64orLess& dest, int imm ) const
|
||||
{
|
||||
dest.prefix16();
|
||||
xWrite8( dest.Is8BitOp() ? 0xf6 : 0xf7 );
|
||||
EmitSibMagic( 0, dest );
|
||||
xOpWrite( dest.GetPrefix16(), dest.Is8BitOp() ? 0xf6 : 0xf7, 0, dest );
|
||||
dest.xWriteImm( imm );
|
||||
}
|
||||
|
||||
void xImpl_Test::operator()( const xRegisterInt& to, int imm ) const
|
||||
{
|
||||
to.prefix16();
|
||||
|
||||
if( to.IsAccumulator() )
|
||||
xWrite8( to.Is8BitOp() ? 0xa8 : 0xa9 );
|
||||
else
|
||||
{
|
||||
xWrite8( to.Is8BitOp() ? 0xf6 : 0xf7 );
|
||||
EmitSibMagic( 0, to );
|
||||
if( to.IsAccumulator() ) {
|
||||
xOpAccWrite( to.GetPrefix16(), to.Is8BitOp() ? 0xa8 : 0xa9, 0, to );
|
||||
} else {
|
||||
xOpWrite( to.GetPrefix16(), to.Is8BitOp() ? 0xf6 : 0xf7, 0, to );
|
||||
}
|
||||
to.xWriteImm( imm );
|
||||
}
|
||||
|
@ -969,11 +953,15 @@ void xImpl_IncDec::operator()( const xRegisterInt& to ) const
|
|||
{
|
||||
if( to.Is8BitOp() )
|
||||
{
|
||||
xWrite8( 0xfe );
|
||||
EmitSibMagic( isDec ? 1 : 0, to );
|
||||
u8 regfield = isDec ? 1 : 0;
|
||||
xOpWrite( to.GetPrefix16(), 0xfe, regfield, to);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
pxAssertMsg(0, "Single Byte INC/DEC aren't valid in 64 bits."
|
||||
"You need to use the ModR/M form (FF/0 FF/1 opcodes)");
|
||||
#endif
|
||||
to.prefix16();
|
||||
xWrite8( (isDec ? 0x48 : 0x40) | to.Id );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue