mirror of https://github.com/PCSX2/pcsx2.git
Emitter: fixed a bug in MOVSX/ZX's reg->reg form [resolves Issue 159 - missing geometry in DQ8], and moved some files around.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@988 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
986b4fdf93
commit
ac2f5713fc
|
@ -2925,22 +2925,6 @@
|
||||||
RelativePath="..\..\x86\ix86\ix86_fpu.cpp"
|
RelativePath="..\..\x86\ix86\ix86_fpu.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\x86\ix86\ix86_impl_dwshift.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\x86\ix86\ix86_impl_group1.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\x86\ix86\ix86_impl_group2.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\x86\ix86\ix86_impl_movs.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_inlines.inl"
|
RelativePath="..\..\x86\ix86\ix86_inlines.inl"
|
||||||
>
|
>
|
||||||
|
@ -2993,6 +2977,30 @@
|
||||||
RelativePath="..\..\x86\ix86\ix86_types.h"
|
RelativePath="..\..\x86\ix86\ix86_types.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\x86\ix86\implement\movs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="Implement"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\x86\ix86\implement\dwshift.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\x86\ix86\implement\group1.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\x86\ix86\implement\group2.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\x86\ix86\implement\incdec.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\ClassDiagram1.cd"
|
RelativePath=".\ClassDiagram1.cd"
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Header: ix86_impl_dwshift.h -- covers SHLD and SHRD.
|
// Implementations here cover SHLD and SHRD.
|
||||||
// Note: This header is meant to be included from within the x86Emitter::Internal namespace.
|
// Note: This header is meant to be included from within the x86Emitter::Internal namespace.
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ public:
|
||||||
{
|
{
|
||||||
prefix16();
|
prefix16();
|
||||||
write16( 0xa50f | (isShiftRight ? 0x800 : 0) );
|
write16( 0xa50f | (isShiftRight ? 0x800 : 0) );
|
||||||
ModRM( 3, from.Id, to.Id );
|
ModRM_Direct( from.Id, to.Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
static __emitinline void Emit( const iRegister<OperandSize>& to, const iRegister<OperandSize>& from, u8 imm )
|
static __emitinline void Emit( const iRegister<OperandSize>& to, const iRegister<OperandSize>& from, u8 imm )
|
||||||
|
@ -57,7 +57,7 @@ public:
|
||||||
if( imm == 0 ) return;
|
if( imm == 0 ) return;
|
||||||
prefix16();
|
prefix16();
|
||||||
write16( 0xa40f | (isShiftRight ? 0x800 : 0) );
|
write16( 0xa40f | (isShiftRight ? 0x800 : 0) );
|
||||||
ModRM( 3, from.Id, to.Id );
|
ModRM_Direct( from.Id, to.Id );
|
||||||
write8( imm );
|
write8( imm );
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Note: This header is meant to be included from within the x86Emitter::Internal namespace.
|
// Note: This header is meant to be included from within the x86Emitter::Internal namespace.
|
||||||
|
|
||||||
// Instructions implemented in this header are as follows -->>
|
// Instructions implemented in this header are as follows -->>
|
||||||
|
|
||||||
enum G1Type
|
enum G1Type
|
||||||
|
@ -52,7 +51,7 @@ public:
|
||||||
{
|
{
|
||||||
prefix16();
|
prefix16();
|
||||||
iWrite<u8>( (Is8BitOperand() ? 0 : 1) | (InstType<<3) );
|
iWrite<u8>( (Is8BitOperand() ? 0 : 1) | (InstType<<3) );
|
||||||
ModRM( 3, from.Id, to.Id );
|
ModRM_Direct( from.Id, to.Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
static __emitinline void Emit( const ModSibBase& sibdest, const iRegister<OperandSize>& from )
|
static __emitinline void Emit( const ModSibBase& sibdest, const iRegister<OperandSize>& from )
|
||||||
|
@ -89,7 +88,7 @@ public:
|
||||||
if( !Is8BitOperand() && is_s8( imm ) )
|
if( !Is8BitOperand() && is_s8( imm ) )
|
||||||
{
|
{
|
||||||
iWrite<u8>( 0x83 );
|
iWrite<u8>( 0x83 );
|
||||||
ModRM( 3, InstType, to.Id );
|
ModRM_Direct( InstType, to.Id );
|
||||||
iWrite<s8>( imm );
|
iWrite<s8>( imm );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -99,7 +98,7 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iWrite<u8>( Is8BitOperand() ? 0x80 : 0x81 );
|
iWrite<u8>( Is8BitOperand() ? 0x80 : 0x81 );
|
||||||
ModRM( 3, InstType, to.Id );
|
ModRM_Direct( InstType, to.Id );
|
||||||
}
|
}
|
||||||
iWrite<ImmType>( imm );
|
iWrite<ImmType>( imm );
|
||||||
}
|
}
|
||||||
|
@ -148,11 +147,7 @@ public:
|
||||||
__noinline void operator()( const iRegister32& to, const ModSibBase& sibsrc ) const{ m_32::Emit( to, sibsrc ); }
|
__noinline void operator()( const iRegister32& to, const ModSibBase& sibsrc ) const{ m_32::Emit( to, sibsrc ); }
|
||||||
__noinline void operator()( const ModSibStrict<4>& sibdest, u32 imm ) const { m_32::Emit( sibdest, imm ); }
|
__noinline void operator()( const ModSibStrict<4>& sibdest, u32 imm ) const { m_32::Emit( sibdest, imm ); }
|
||||||
|
|
||||||
void operator()( const iRegister32& to, u32 imm, bool needs_flags=false ) const
|
void operator()( const iRegister32& to, u32 imm ) const { m_32::Emit( to, imm ); }
|
||||||
{
|
|
||||||
//if( needs_flags || (imm != 0) || !_optimize_imm0() )
|
|
||||||
m_32::Emit( to, imm );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 16 Bit Interface -----------
|
// ---------- 16 Bit Interface -----------
|
||||||
__forceinline void operator()( const iRegister16& to, const iRegister16& from ) const { m_16::Emit( to, from ); }
|
__forceinline void operator()( const iRegister16& to, const iRegister16& from ) const { m_16::Emit( to, from ); }
|
||||||
|
@ -162,7 +157,7 @@ public:
|
||||||
__noinline void operator()( const iRegister16& to, const ModSibBase& sibsrc ) const{ m_16::Emit( to, sibsrc ); }
|
__noinline void operator()( const iRegister16& to, const ModSibBase& sibsrc ) const{ m_16::Emit( to, sibsrc ); }
|
||||||
__noinline void operator()( const ModSibStrict<2>& sibdest, u16 imm ) const { m_16::Emit( sibdest, imm ); }
|
__noinline void operator()( const ModSibStrict<2>& sibdest, u16 imm ) const { m_16::Emit( sibdest, imm ); }
|
||||||
|
|
||||||
void operator()( const iRegister16& to, u16 imm, bool needs_flags=false ) const { m_16::Emit( to, imm ); }
|
void operator()( const iRegister16& to, u16 imm ) const { m_16::Emit( to, imm ); }
|
||||||
|
|
||||||
// ---------- 8 Bit Interface -----------
|
// ---------- 8 Bit Interface -----------
|
||||||
__forceinline void operator()( const iRegister8& to, const iRegister8& from ) const { m_8::Emit( to, from ); }
|
__forceinline void operator()( const iRegister8& to, const iRegister8& from ) const { m_8::Emit( to, from ); }
|
||||||
|
@ -172,7 +167,7 @@ public:
|
||||||
__noinline void operator()( const iRegister8& to, const ModSibBase& sibsrc ) const{ m_8::Emit( to, sibsrc ); }
|
__noinline void operator()( const iRegister8& to, const ModSibBase& sibsrc ) const{ m_8::Emit( to, sibsrc ); }
|
||||||
__noinline void operator()( const ModSibStrict<1>& sibdest, u8 imm ) const { m_8::Emit( sibdest, imm ); }
|
__noinline void operator()( const ModSibStrict<1>& sibdest, u8 imm ) const { m_8::Emit( sibdest, imm ); }
|
||||||
|
|
||||||
void operator()( const iRegister8& to, u8 imm, bool needs_flags=false ) const { m_8::Emit( to, imm ); }
|
void operator()( const iRegister8& to, u8 imm ) const { m_8::Emit( to, imm ); }
|
||||||
|
|
||||||
Group1ImplAll() {} // Why does GCC need these?
|
Group1ImplAll() {} // Why does GCC need these?
|
||||||
};
|
};
|
|
@ -19,7 +19,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Note: This header is meant to be included from within the x86Emitter::Internal namespace.
|
// Note: This header is meant to be included from within the x86Emitter::Internal namespace.
|
||||||
|
|
||||||
// Instructions implemented in this header are as follows -->>
|
// Instructions implemented in this header are as follows -->>
|
||||||
|
|
||||||
enum G2Type
|
enum G2Type
|
||||||
|
@ -56,7 +55,7 @@ public:
|
||||||
{
|
{
|
||||||
prefix16();
|
prefix16();
|
||||||
iWrite<u8>( Is8BitOperand() ? 0xd2 : 0xd3 );
|
iWrite<u8>( Is8BitOperand() ? 0xd2 : 0xd3 );
|
||||||
ModRM( 3, InstType, to.Id );
|
ModRM_Direct( InstType, to.Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
static __emitinline void Emit( const iRegister<OperandSize>& to, u8 imm )
|
static __emitinline void Emit( const iRegister<OperandSize>& to, u8 imm )
|
||||||
|
@ -68,12 +67,12 @@ public:
|
||||||
{
|
{
|
||||||
// special encoding of 1's
|
// special encoding of 1's
|
||||||
iWrite<u8>( Is8BitOperand() ? 0xd0 : 0xd1 );
|
iWrite<u8>( Is8BitOperand() ? 0xd0 : 0xd1 );
|
||||||
ModRM( 3, InstType, to.Id );
|
ModRM_Direct( InstType, to.Id );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iWrite<u8>( Is8BitOperand() ? 0xc0 : 0xc1 );
|
iWrite<u8>( Is8BitOperand() ? 0xc0 : 0xc1 );
|
||||||
ModRM( 3, InstType, to.Id );
|
ModRM_Direct( InstType, to.Id );
|
||||||
iWrite<u8>( imm );
|
iWrite<u8>( imm );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* Pcsx2 - Pc Ps2 Emulator
|
||||||
|
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Implementations found here: Increment and Decrement Instructions!
|
||||||
|
// Note: This header is meant to be included from within the x86Emitter::Internal namespace.
|
|
@ -44,8 +44,9 @@ public:
|
||||||
|
|
||||||
static __emitinline void Emit( JccComparisonType cc, const iRegister<OperandSize>& to, const iRegister<OperandSize>& from )
|
static __emitinline void Emit( JccComparisonType cc, const iRegister<OperandSize>& to, const iRegister<OperandSize>& from )
|
||||||
{
|
{
|
||||||
|
if( to == from ) return;
|
||||||
emit_base( cc );
|
emit_base( cc );
|
||||||
ModRM( 3, to.Id, from.Id );
|
ModRM( ModRm_Direct, to.Id, from.Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
static __emitinline void Emit( JccComparisonType cc, const iRegister<OperandSize>& to, const void* src )
|
static __emitinline void Emit( JccComparisonType cc, const iRegister<OperandSize>& to, const void* src )
|
||||||
|
@ -123,7 +124,7 @@ public:
|
||||||
static __emitinline void Emit( const iRegister<DestOperandSize>& to, const iRegister<SrcOperandSize>& from, bool SignExtend )
|
static __emitinline void Emit( const iRegister<DestOperandSize>& to, const iRegister<SrcOperandSize>& from, bool SignExtend )
|
||||||
{
|
{
|
||||||
emit_base( SignExtend );
|
emit_base( SignExtend );
|
||||||
ModRM( 3, from.Id, to.Id );
|
ModRM_Direct( to.Id, from.Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
static __emitinline void Emit( const iRegister<DestOperandSize>& to, const ModSibStrict<SrcOperandSize>& sibsrc, bool SignExtend )
|
static __emitinline void Emit( const iRegister<DestOperandSize>& to, const ModSibStrict<SrcOperandSize>& sibsrc, bool SignExtend )
|
|
@ -128,6 +128,11 @@ namespace Internal
|
||||||
//x86Ptr++;
|
//x86Ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__forceinline void ModRM_Direct( uint reg, uint rm )
|
||||||
|
{
|
||||||
|
ModRM( Mod_Direct, reg, rm );
|
||||||
|
}
|
||||||
|
|
||||||
__forceinline void SibSB( u32 ss, u32 index, u32 base )
|
__forceinline void SibSB( u32 ss, u32 index, u32 base )
|
||||||
{
|
{
|
||||||
iWrite<u8>( (ss << 6) | (index << 3) | base );
|
iWrite<u8>( (ss << 6) | (index << 3) | base );
|
||||||
|
@ -679,7 +684,7 @@ static __forceinline void EmitMulDiv_OneRegForm( MulDivType InstType, const ModS
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// All ioMul forms are valid for 16 and 32 bit register operands only!
|
// All iMul forms are valid for 16 and 32 bit register operands only!
|
||||||
|
|
||||||
template< typename ImmType >
|
template< typename ImmType >
|
||||||
class iMulImpl
|
class iMulImpl
|
||||||
|
@ -752,12 +757,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Internal
|
|
||||||
{
|
|
||||||
typedef iMulImpl<u32> iMUL32;
|
|
||||||
typedef iMulImpl<u16> iMUL16;
|
|
||||||
}
|
|
||||||
|
|
||||||
__forceinline void iUMUL( const iRegister32& from ) { EmitMulDiv_OneRegForm( MDT_Mul, from ); }
|
__forceinline void iUMUL( const iRegister32& from ) { EmitMulDiv_OneRegForm( MDT_Mul, from ); }
|
||||||
__forceinline void iUMUL( const iRegister16& from ) { EmitMulDiv_OneRegForm( MDT_Mul, from ); }
|
__forceinline void iUMUL( const iRegister16& from ) { EmitMulDiv_OneRegForm( MDT_Mul, from ); }
|
||||||
__forceinline void iUMUL( const iRegister8& from ) { EmitMulDiv_OneRegForm( MDT_Mul, from ); }
|
__forceinline void iUMUL( const iRegister8& from ) { EmitMulDiv_OneRegForm( MDT_Mul, from ); }
|
||||||
|
@ -773,22 +772,32 @@ __forceinline void iSDIV( const iRegister16& from ) { EmitMulDiv_OneRegForm( MD
|
||||||
__forceinline void iSDIV( const iRegister8& from ) { EmitMulDiv_OneRegForm( MDT_iDiv, from ); }
|
__forceinline void iSDIV( const iRegister8& from ) { EmitMulDiv_OneRegForm( MDT_iDiv, from ); }
|
||||||
__noinline void iSDIV( const ModSibSized& from ) { EmitMulDiv_OneRegForm( MDT_iDiv, from ); }
|
__noinline void iSDIV( const ModSibSized& from ) { EmitMulDiv_OneRegForm( MDT_iDiv, from ); }
|
||||||
|
|
||||||
__forceinline void iSMUL( const iRegister32& from ) { EmitMulDiv_OneRegForm( MDT_iMul, from ); }
|
__forceinline void iSMUL( const iRegister32& from ) { EmitMulDiv_OneRegForm( MDT_iMul, from ); }
|
||||||
|
__forceinline void iSMUL( const iRegister16& from ) { EmitMulDiv_OneRegForm( MDT_iMul, from ); }
|
||||||
|
__forceinline void iSMUL( const iRegister8& from ) { EmitMulDiv_OneRegForm( MDT_iMul, from ); }
|
||||||
|
__noinline void iSMUL( const ModSibSized& from ) { EmitMulDiv_OneRegForm( MDT_iMul, from ); }
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// iMUL's special forms (unique to iMUL alone)
|
||||||
|
|
||||||
|
namespace Internal
|
||||||
|
{
|
||||||
|
typedef iMulImpl<u32> iMUL32;
|
||||||
|
typedef iMulImpl<u16> iMUL16;
|
||||||
|
}
|
||||||
|
|
||||||
__forceinline void iSMUL( const iRegister32& to, const iRegister32& from ) { iMUL32::Emit( to, from ); }
|
__forceinline void iSMUL( const iRegister32& to, const iRegister32& from ) { iMUL32::Emit( to, from ); }
|
||||||
__forceinline void iSMUL( const iRegister32& to, const void* src ) { iMUL32::Emit( to, src ); }
|
__forceinline void iSMUL( const iRegister32& to, const void* src ) { iMUL32::Emit( to, src ); }
|
||||||
__forceinline void iSMUL( const iRegister32& to, const iRegister32& from, s32 imm ) { iMUL32::Emit( to, from, imm ); }
|
__forceinline void iSMUL( const iRegister32& to, const iRegister32& from, s32 imm ) { iMUL32::Emit( to, from, imm ); }
|
||||||
__noinline void iSMUL( const iRegister32& to, const ModSibBase& src ) { iMUL32::Emit( to, src ); }
|
__noinline void iSMUL( const iRegister32& to, const ModSibBase& src ) { iMUL32::Emit( to, src ); }
|
||||||
__noinline void iSMUL( const iRegister32& to, const ModSibBase& from, s32 imm ) { iMUL32::Emit( to, from, imm ); }
|
__noinline void iSMUL( const iRegister32& to, const ModSibBase& from, s32 imm ) { iMUL32::Emit( to, from, imm ); }
|
||||||
|
|
||||||
__forceinline void iSMUL( const iRegister16& from ) { EmitMulDiv_OneRegForm( MDT_iMul, from ); }
|
|
||||||
__forceinline void iSMUL( const iRegister16& to, const iRegister16& from ) { iMUL16::Emit( to, from ); }
|
__forceinline void iSMUL( const iRegister16& to, const iRegister16& from ) { iMUL16::Emit( to, from ); }
|
||||||
__forceinline void iSMUL( const iRegister16& to, const void* src ) { iMUL16::Emit( to, src ); }
|
__forceinline void iSMUL( const iRegister16& to, const void* src ) { iMUL16::Emit( to, src ); }
|
||||||
__forceinline void iSMUL( const iRegister16& to, const iRegister16& from, s16 imm ) { iMUL16::Emit( to, from, imm ); }
|
__forceinline void iSMUL( const iRegister16& to, const iRegister16& from, s16 imm ) { iMUL16::Emit( to, from, imm ); }
|
||||||
__noinline void iSMUL( const iRegister16& to, const ModSibBase& src ) { iMUL16::Emit( to, src ); }
|
__noinline void iSMUL( const iRegister16& to, const ModSibBase& src ) { iMUL16::Emit( to, src ); }
|
||||||
__noinline void iSMUL( const iRegister16& to, const ModSibBase& from, s16 imm ) { iMUL16::Emit( to, from, imm ); }
|
__noinline void iSMUL( const iRegister16& to, const ModSibBase& from, s16 imm ) { iMUL16::Emit( to, from, imm ); }
|
||||||
|
|
||||||
__forceinline void iSMUL( const iRegister8& from ) { EmitMulDiv_OneRegForm( MDT_iMul, from ); }
|
|
||||||
__noinline void iSMUL( const ModSibSized& from ) { EmitMulDiv_OneRegForm( MDT_iMul, from ); }
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -176,6 +176,31 @@ emitterT void SHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift )
|
||||||
iSHRD( iRegister32(to), iRegister32(from), shift );
|
iSHRD( iRegister32(to), iRegister32(from), shift );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* mul eax by r32 to edx:eax */
|
||||||
|
emitterT void MUL32R( x86IntRegType from ) { iUMUL( iRegister32(from) ); }
|
||||||
|
/* imul eax by r32 to edx:eax */
|
||||||
|
emitterT void IMUL32R( x86IntRegType from ) { iSMUL( iRegister32(from) ); }
|
||||||
|
/* mul eax by m32 to edx:eax */
|
||||||
|
emitterT void MUL32M( u32 from ) { iUMUL( ptr32[from] ); }
|
||||||
|
/* imul eax by m32 to edx:eax */
|
||||||
|
emitterT void IMUL32M( u32 from ) { iSMUL( ptr32[from] ); }
|
||||||
|
|
||||||
|
/* imul r32 by r32 to r32 */
|
||||||
|
emitterT void IMUL32RtoR( x86IntRegType to, x86IntRegType from )
|
||||||
|
{
|
||||||
|
iSMUL( iRegister32(to), iRegister32(from) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* div eax by r32 to edx:eax */
|
||||||
|
emitterT void DIV32R( x86IntRegType from ) { iUDIV( iRegister32(from) ); }
|
||||||
|
/* idiv eax by r32 to edx:eax */
|
||||||
|
emitterT void IDIV32R( x86IntRegType from ) { iSDIV( iRegister32(from) ); }
|
||||||
|
/* div eax by m32 to edx:eax */
|
||||||
|
emitterT void DIV32M( u32 from ) { iUDIV( ptr32[from] ); }
|
||||||
|
/* idiv eax by m32 to edx:eax */
|
||||||
|
emitterT void IDIV32M( u32 from ) { iSDIV( ptr32[from] ); }
|
||||||
|
|
||||||
|
|
||||||
emitterT void LEA32RtoR(x86IntRegType to, x86IntRegType from, s32 offset)
|
emitterT void LEA32RtoR(x86IntRegType to, x86IntRegType from, s32 offset)
|
||||||
{
|
{
|
||||||
iLEA( iRegister32( to ), ptr[x86IndexReg(from)+offset] );
|
iLEA( iRegister32( to ), ptr[x86IndexReg(from)+offset] );
|
||||||
|
@ -413,30 +438,6 @@ emitterT void DEC16M( u32 to )
|
||||||
write32( MEMADDR(to, 4) );
|
write32( MEMADDR(to, 4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mul eax by r32 to edx:eax */
|
|
||||||
emitterT void MUL32R( x86IntRegType from ) { iUMUL( iRegister32(from) ); }
|
|
||||||
/* imul eax by r32 to edx:eax */
|
|
||||||
emitterT void IMUL32R( x86IntRegType from ) { iSMUL( iRegister32(from) ); }
|
|
||||||
/* mul eax by m32 to edx:eax */
|
|
||||||
emitterT void MUL32M( u32 from ) { iUMUL( ptr32[from] ); }
|
|
||||||
/* imul eax by m32 to edx:eax */
|
|
||||||
emitterT void IMUL32M( u32 from ) { iSMUL( ptr32[from] ); }
|
|
||||||
|
|
||||||
/* imul r32 by r32 to r32 */
|
|
||||||
emitterT void IMUL32RtoR( x86IntRegType to, x86IntRegType from )
|
|
||||||
{
|
|
||||||
iSMUL( iRegister32(to), iRegister32(from) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* div eax by r32 to edx:eax */
|
|
||||||
emitterT void DIV32R( x86IntRegType from ) { iUDIV( iRegister32(from) ); }
|
|
||||||
/* idiv eax by r32 to edx:eax */
|
|
||||||
emitterT void IDIV32R( x86IntRegType from ) { iSDIV( iRegister32(from) ); }
|
|
||||||
/* div eax by m32 to edx:eax */
|
|
||||||
emitterT void DIV32M( u32 from ) { iUDIV( ptr32[from] ); }
|
|
||||||
/* idiv eax by m32 to edx:eax */
|
|
||||||
emitterT void IDIV32M( u32 from ) { iSDIV( ptr32[from] ); }
|
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
// logical instructions /
|
// logical instructions /
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
|
|
@ -147,6 +147,15 @@ namespace x86Emitter
|
||||||
# define __noinline
|
# define __noinline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ModRM 'mod' field enumeration. Provided mostly for reference:
|
||||||
|
enum ModRm_ModField
|
||||||
|
{
|
||||||
|
Mod_NoDisp = 0, // effective address operation with no displacement, in the form of [reg] (or uses special Disp32-only encoding in the case of [ebp] form)
|
||||||
|
Mod_Disp8, // effective address operation with 8 bit displacement, in the form of [reg+disp8]
|
||||||
|
Mod_Disp32, // effective address operation with 32 bit displacement, in the form of [reg+disp32],
|
||||||
|
Mod_Direct, // direct reg/reg operation
|
||||||
|
};
|
||||||
|
|
||||||
static const int ModRm_Direct = 3; // when used as the first parameter, specifies direct register operation (no mem)
|
static const int ModRm_Direct = 3; // when used as the first parameter, specifies direct register operation (no mem)
|
||||||
static const int ModRm_UseSib = 4; // same index value as ESP (used in RM field)
|
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)
|
static const int ModRm_UseDisp32 = 5; // same index value as EBP (used in Mod field)
|
||||||
|
@ -636,57 +645,17 @@ namespace x86Emitter
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
extern void ModRM( uint mod, uint reg, uint rm );
|
extern void ModRM( uint mod, uint reg, uint rm );
|
||||||
|
extern void ModRM_Direct( uint reg, uint rm );
|
||||||
extern void SibSB( u32 ss, u32 index, u32 base );
|
extern void SibSB( u32 ss, u32 index, u32 base );
|
||||||
extern void iWriteDisp( int regfield, s32 displacement );
|
extern void iWriteDisp( int regfield, s32 displacement );
|
||||||
extern void iWriteDisp( int regfield, const void* address );
|
extern void iWriteDisp( int regfield, const void* address );
|
||||||
|
|
||||||
extern void EmitSibMagic( uint regfield, const ModSibBase& info );
|
extern void EmitSibMagic( uint regfield, const ModSibBase& info );
|
||||||
|
|
||||||
#include "ix86_impl_group1.h"
|
#include "implement/group1.h"
|
||||||
#include "ix86_impl_group2.h"
|
#include "implement/group2.h"
|
||||||
#include "ix86_impl_movs.h" // cmov and movsx/zx
|
#include "implement/movs.h" // cmov and movsx/zx
|
||||||
#include "ix86_impl_dwshift.h" // dowubleword shifts!
|
#include "implement/dwshift.h" // dowubleword shifts!
|
||||||
|
|
||||||
// if the immediate is zero, we can replace the instruction, or ignore it
|
|
||||||
// entirely, depending on the instruction being issued. That's what we do here.
|
|
||||||
// (returns FALSE if no optimization is performed)
|
|
||||||
// [TODO] : Work-in-progress!
|
|
||||||
//template< G1Type InstType, typename RegType >
|
|
||||||
//static __forceinline void _optimize_imm0( RegType to );
|
|
||||||
|
|
||||||
/*template< G1Type InstType, typename RegType >
|
|
||||||
static __forceinline void _optimize_imm0( const RegType& to )
|
|
||||||
{
|
|
||||||
switch( InstType )
|
|
||||||
{
|
|
||||||
// ADD, SUB, and OR can be ignored if the imm is zero..
|
|
||||||
case G1Type_ADD:
|
|
||||||
case G1Type_SUB:
|
|
||||||
case G1Type_OR:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// ADC and SBB can never be ignored (could have carry bits)
|
|
||||||
// XOR behavior is distinct as well [or is it the same as NEG or NOT?]
|
|
||||||
case G1Type_ADC:
|
|
||||||
case G1Type_SBB:
|
|
||||||
case G1Type_XOR:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// replace AND with XOR (or SUB works too.. whatever!)
|
|
||||||
case G1Type_AND:
|
|
||||||
iXOR( to, to );
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// replace CMP with OR reg,reg:
|
|
||||||
case G1Type_CMP:
|
|
||||||
iOR( to, to );
|
|
||||||
return true;
|
|
||||||
|
|
||||||
jNO_DEFAULT
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue