Emitter code cleanups, and re-added GCC 4.4.x code I accidentally removed in a prev rev.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2148 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-11-07 15:46:09 +00:00
parent 7f610e46f6
commit ae64b98e6a
4 changed files with 133 additions and 78 deletions

View File

@ -281,10 +281,42 @@ static const int __pagesize = PCSX2_PAGESIZE;
# define unlikely(x) __builtin_expect(!!(x), 0) # define unlikely(x) __builtin_expect(!!(x), 0)
#endif #endif
// --------------------------------------------------------------------------------------
// GNU C/C++ Specific Defines
// --------------------------------------------------------------------------------------
#ifdef __GNUC__
// GCC 4.4.0 is a bit nutty, as compilers go. it gets a define to itself.
# define GCC_VERSION ( __GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
// Test for GCC > 4.4.0; Should be adjusted when new versions come out
# if GCC_VERSION >= 40400
# define THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0
# define __nooptimization __attribute__((optimize("O0")))
# endif
// This theoretically unoptimizes. Not having much luck so far.
/*
# ifdef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0
# pragma GCC optimize ("O0")
# endif
# ifdef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0
# pragma GCC reset_options
# endif
*/
#endif // end GCC-specific section.
#ifndef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0 #ifndef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0
# define __nooptimization # define __nooptimization
#endif #endif
///////////////////////////////////////////////////////////////////////////////////////
typedef struct { typedef struct {
int size; int size;
s8 *data; s8 *data;

View File

@ -109,24 +109,6 @@ struct xImpl_Set
//void operator()( const xDirectOrIndirect8& dest ) const; //void operator()( const xDirectOrIndirect8& dest ) const;
}; };
class xRegister16or32
{
protected:
const xRegisterInt& m_convtype;
public:
xRegister16or32( const xRegister32& src ) : m_convtype( src ) {}
xRegister16or32( const xRegister16& src ) : m_convtype( src ) {}
//operator const xRegisterInt&() const { return m_convtype; }
operator const xRegisterBase&() const { return m_convtype; }
const xRegisterInt* operator->() const
{
return &m_convtype;
}
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_MovExtend // xImpl_MovExtend

View File

@ -52,7 +52,7 @@ extern const char* xGetRegName( int regid, int operandSize );
template< typename T > template< typename T >
static __forceinline bool is_s8( T imm ) { return (s8)imm == (s32)imm; } static __forceinline bool is_s8( T imm ) { return (s8)imm == (s32)imm; }
template< typename T > __forceinline void xWrite( T val ); template< typename T > void xWrite( T val );
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ALWAYS_USE_MOVAPS [define] / AlwaysUseMovaps [const] // ALWAYS_USE_MOVAPS [define] / AlwaysUseMovaps [const]
@ -208,8 +208,16 @@ template< typename T > __forceinline void xWrite( T val );
public: public:
int Id; int Id;
xRegisterBase(): Id( xRegId_Invalid ) {} xRegisterBase()
explicit xRegisterBase( int regId ) : Id( regId ) { pxAssert( (Id >= xRegId_Empty) && (Id < 8) ); } {
Id = xRegId_Invalid;
}
explicit xRegisterBase( int regId )
{
Id = regId;
pxAssert( (Id >= xRegId_Empty) && (Id < 8) );
}
bool IsEmpty() const { return Id < 0 ; } bool IsEmpty() const { return Id < 0 ; }
bool IsInvalid() const { return Id == xRegId_Invalid; } bool IsInvalid() const { return Id == xRegId_Invalid; }
@ -252,7 +260,6 @@ template< typename T > __forceinline void xWrite( T val );
public: public:
xRegister8(): _parent() {} xRegister8(): _parent() {}
//explicit xRegister8( const xRegisterBase& src ) : _parent( src ) {}
explicit xRegister8( int regId ) : _parent( regId ) {} explicit xRegister8( int regId ) : _parent( regId ) {}
virtual uint GetOperandSize() const { return 1; } virtual uint GetOperandSize() const { return 1; }
@ -267,7 +274,6 @@ template< typename T > __forceinline void xWrite( T val );
public: public:
xRegister16(): _parent() {} xRegister16(): _parent() {}
//explicit xRegister16( const xRegisterBase& src ) : _parent( src ) {}
explicit xRegister16( int regId ) : _parent( regId ) {} explicit xRegister16( int regId ) : _parent( regId ) {}
virtual uint GetOperandSize() const { return 2; } virtual uint GetOperandSize() const { return 2; }
@ -282,7 +288,6 @@ template< typename T > __forceinline void xWrite( T val );
public: public:
xRegister32(): _parent() {} xRegister32(): _parent() {}
//explicit xRegister32( const xRegisterBase& src ) : _parent( src ) {}
explicit xRegister32( int regId ) : _parent( regId ) {} explicit xRegister32( int regId ) : _parent( regId ) {}
virtual uint GetOperandSize() const { return 4; } virtual uint GetOperandSize() const { return 4; }
@ -303,7 +308,7 @@ template< typename T > __forceinline void xWrite( T val );
public: public:
xRegisterMMX(): _parent() {} xRegisterMMX(): _parent() {}
xRegisterMMX( const xRegisterBase& src ) : _parent( src ) {} //xRegisterMMX( const xRegisterBase& src ) : _parent( src ) {}
explicit xRegisterMMX( int regId ) : _parent( regId ) {} explicit xRegisterMMX( int regId ) : _parent( regId ) {}
virtual uint GetOperandSize() const { return 8; } virtual uint GetOperandSize() const { return 8; }
@ -318,7 +323,7 @@ template< typename T > __forceinline void xWrite( T val );
public: public:
xRegisterSSE(): _parent() {} xRegisterSSE(): _parent() {}
xRegisterSSE( const xRegisterBase& src ) : _parent( src ) {} //xRegisterSSE( const xRegisterBase& src ) : _parent( src ) {}
explicit xRegisterSSE( int regId ) : _parent( regId ) {} explicit xRegisterSSE( int regId ) : _parent( regId ) {}
virtual uint GetOperandSize() const { return 16; } virtual uint GetOperandSize() const { return 16; }
@ -372,11 +377,11 @@ template< typename T > __forceinline void xWrite( T val );
}*/ }*/
}; };
class xRegisterEmpty // --------------------------------------------------------------------------------------
// xRegisterEmpty
// --------------------------------------------------------------------------------------
struct xRegisterEmpty
{ {
public:
xRegisterEmpty() {}
operator xRegister8() const operator xRegister8() const
{ {
return xRegister8( xRegId_Empty ); return xRegister8( xRegId_Empty );
@ -403,6 +408,23 @@ template< typename T > __forceinline void xWrite( T val );
} }
}; };
class xRegister16or32
{
protected:
const xRegisterInt& m_convtype;
public:
xRegister16or32( const xRegister32& src ) : m_convtype( src ) {}
xRegister16or32( const xRegister16& src ) : m_convtype( src ) {}
operator const xRegisterBase&() const { return m_convtype; }
const xRegisterInt* operator->() const
{
return &m_convtype;
}
};
extern const xRegisterEmpty xEmptyReg; extern const xRegisterEmpty xEmptyReg;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -411,37 +433,39 @@ template< typename T > __forceinline void xWrite( T val );
class xAddressInfo class xAddressInfo
{ {
public: public:
xAddressReg Base; // base register (no scale) xAddressReg Base; // base register (no scale)
xAddressReg Index; // index reg gets multiplied by the scale xAddressReg Index; // index reg gets multiplied by the scale
int Factor; // scale applied to the index register, in factor form (not a shift!) int Factor; // scale applied to the index register, in factor form (not a shift!)
s32 Displacement; // address displacement s32 Displacement; // address displacement
public: public:
__forceinline xAddressInfo( const xAddressReg& base, const xAddressReg& index, int factor=1, s32 displacement=0 ) : __forceinline xAddressInfo( const xAddressReg& base, const xAddressReg& index, int factor=1, s32 displacement=0 )
Base( base ),
Index( index ),
Factor( factor ),
Displacement( displacement )
{ {
Base = base;
Index = index;
Factor = factor;
Displacement= displacement;
pxAssertMsg( base.Id != xRegId_Invalid, "Uninitialized x86 register." ); pxAssertMsg( base.Id != xRegId_Invalid, "Uninitialized x86 register." );
pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." ); pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." );
} }
__forceinline explicit xAddressInfo( const xAddressReg& index, int displacement=0 ) : __forceinline explicit xAddressInfo( const xAddressReg& index, int displacement=0 )
Base( xEmptyReg ),
Index( index ),
Factor(0),
Displacement( displacement )
{ {
Base = xEmptyReg;
Index = index;
Factor = 0;
Displacement= displacement;
pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." ); pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." );
} }
__forceinline explicit xAddressInfo( s32 displacement=0 ) : __forceinline explicit xAddressInfo( s32 displacement=0 )
Base( xEmptyReg ),
Index( xEmptyReg ),
Factor(0),
Displacement( displacement )
{ {
Base = xEmptyReg;
Index = xEmptyReg;
Factor = 0;
Displacement= displacement;
} }
static xAddressInfo FromIndexReg( const xAddressReg& index, int scale=0, s32 displacement=0 ); static xAddressInfo FromIndexReg( const xAddressReg& index, int scale=0, s32 displacement=0 );
@ -501,15 +525,20 @@ template< typename T > __forceinline void xWrite( T val );
template< typename xRegType > template< typename xRegType >
class xImmReg class xImmReg
{ {
xRegType m_reg; xRegType m_reg;
int m_imm; int m_imm;
public: public:
xImmReg() : xImmReg() : m_reg()
m_reg(), m_imm( 0 ) { } {
m_imm = 0;
}
xImmReg( int imm, const xRegType& reg = xEmptyReg ) : xImmReg( int imm, const xRegType& reg = xEmptyReg )
m_reg( reg ), m_imm( imm ) { } {
m_reg = reg;
m_imm = imm;
}
const xRegType& GetReg() const { return m_reg; } const xRegType& GetReg() const { return m_reg; }
const int GetImm() const { return m_imm; } const int GetImm() const { return m_imm; }
@ -537,31 +566,43 @@ template< typename T > __forceinline void xWrite( T val );
s32 Displacement; // offset applied to the Base/Index registers. s32 Displacement; // offset applied to the Base/Index registers.
public: public:
explicit ModSibBase( const xAddressInfo& src ) : explicit ModSibBase( const xAddressInfo& src )
Base( src.Base ), Index( src.Index ), Scale( src.Factor ),
Displacement( src.Displacement )
{ {
Base = src.Base;
Index = src.Index;
Scale = src.Factor;
Displacement= src.Displacement;
Reduce(); Reduce();
} }
ModSibBase( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) : ModSibBase( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 )
Base( base ), Index( index ), Scale( scale ),
Displacement( displacement )
{ {
Base = base;
Index = index;
Scale = scale;
Displacement= displacement;
Reduce(); Reduce();
} }
explicit ModSibBase( s32 disp ) : explicit ModSibBase( s32 disp )
Base(), Index(), Scale(0),
Displacement( disp )
{ {
Base = xEmptyReg;
Index = xEmptyReg;
Scale = 0;
Displacement= disp;
// no reduction necessary :D // no reduction necessary :D
} }
ModSibBase( const void* target ) : ModSibBase( const void* target )
Base(), Index(), Scale(0),
Displacement( (s32)target )
{ {
Base = xEmptyReg;
Index = xEmptyReg;
Scale = 0;
Displacement= (s32)target;
// no reduction necessary :D // no reduction necessary :D
} }
@ -589,7 +630,6 @@ template< typename T > __forceinline void xWrite( T val );
typedef ModSibBase _parent; typedef ModSibBase _parent;
protected: protected:
//explicit ModSib32orLess( const ModSibBase& src ) : _parent( src ) {}
explicit ModSib32orLess( const xAddressInfo& src ) : _parent( src ) {} explicit ModSib32orLess( const xAddressInfo& src ) : _parent( src ) {}
explicit ModSib32orLess( s32 disp ) : _parent( disp ) {} explicit ModSib32orLess( s32 disp ) : _parent( disp ) {}
ModSib32orLess( const void* target ) : _parent( target ) {} ModSib32orLess( const void* target ) : _parent( target ) {}
@ -677,8 +717,6 @@ template< typename T > __forceinline void xWrite( T val );
{ {
return xModSibType( (uptr)src ); return xModSibType( (uptr)src );
} }
xAddressIndexer() {} // GCC initialization dummy
}; };
// ptr[] - use this form for instructions which can resolve the address operand size from // ptr[] - use this form for instructions which can resolve the address operand size from

View File

@ -70,7 +70,7 @@ __threadlocal XMMSSEType g_xmmtypes[iREGCNT_XMM] = { XMMT_INT };
namespace x86Emitter { namespace x86Emitter {
template< typename T > __forceinline void xWrite( T val ) template< typename T > void xWrite( T val )
{ {
*(T*)x86Ptr = val; *(T*)x86Ptr = val;
x86Ptr += sizeof(T); x86Ptr += sizeof(T);
@ -102,16 +102,19 @@ __forceinline void xWrite64( u64 val )
xWrite( val ); xWrite( val );
} }
const xAddressIndexer<ModSibBase> ptr; // Empty initializers are due to frivolously pointless GCC errors (it demands the
const xAddressIndexer<ModSib128> ptr128; // objects be initialized even though they have no actual variable members).
const xAddressIndexer<ModSib64> ptr64;
const xAddressIndexer<ModSib32> ptr32; const xAddressIndexer<ModSibBase> ptr = { };
const xAddressIndexer<ModSib16> ptr16; const xAddressIndexer<ModSib128> ptr128 = { };
const xAddressIndexer<ModSib8> ptr8; const xAddressIndexer<ModSib64> ptr64 = { };
const xAddressIndexer<ModSib32> ptr32 = { };
const xAddressIndexer<ModSib16> ptr16 = { };
const xAddressIndexer<ModSib8> ptr8 = { };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
const xRegisterEmpty xEmptyReg; const xRegisterEmpty xEmptyReg = { };
const xRegisterSSE const xRegisterSSE
xmm0( 0 ), xmm1( 1 ), xmm0( 0 ), xmm1( 1 ),