Merge pulled request #174 from Sonicadvance1/x86_64-emitter-fixes

Fix a couple issues in the x86emitter on x86_64.
This commit is contained in:
Pseudonym 2014-07-31 15:43:35 +01:00
commit 03bfffea23
2 changed files with 29 additions and 22 deletions

View File

@ -675,10 +675,10 @@ template< typename T > void xWrite( T val );
class xIndirectVoid : public OperandSizedObject class xIndirectVoid : public OperandSizedObject
{ {
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
uint Scale; // scale applied to the index register, in scale/shift form uint Scale; // scale applied to the index register, in scale/shift form
s32 Displacement; // offset applied to the Base/Index registers. sptr Displacement; // offset applied to the Base/Index registers.
public: public:
explicit xIndirectVoid( s32 disp ); explicit xIndirectVoid( s32 disp );

View File

@ -226,7 +226,14 @@ static __fi void SibSB( u32 ss, u32 index, u32 base )
void EmitSibMagic( uint regfield, const void* address ) void EmitSibMagic( uint regfield, const void* address )
{ {
ModRM( 0, regfield, ModRm_UseDisp32 ); ModRM( 0, regfield, ModRm_UseDisp32 );
xWrite<s32>( (s32)address );
// SIB encoding only supports 32bit offsets, even on x86_64
// We must make sure that the displacement is within the 32bit range
// Else we will fail out in a spectacular fashion
sptr displacement = (sptr)address;
pxAssertDev(displacement >= -0x80000000LL && displacement < 0x80000000LL, "SIB target is too far away, needs an indirect register");
xWrite<s32>( (s32)displacement );
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -461,7 +468,7 @@ xAddressVoid xAddressReg::operator-( s32 right ) const
xAddressVoid xAddressReg::operator-( const void* right ) const xAddressVoid xAddressReg::operator-( const void* right ) const
{ {
pxAssertMsg( Id != -1, "Uninitialized x86 register." ); pxAssertMsg( Id != -1, "Uninitialized x86 register." );
return xAddressVoid( *this, -(s32)right ); return xAddressVoid( *this, -(sptr)right );
} }
xAddressVoid xAddressReg::operator*( u32 factor ) const xAddressVoid xAddressReg::operator*( u32 factor ) const
@ -483,10 +490,10 @@ xAddressVoid xAddressReg::operator<<( u32 shift ) const
xAddressVoid::xAddressVoid( const xAddressReg& base, const xAddressReg& index, int factor, s32 displacement ) xAddressVoid::xAddressVoid( const xAddressReg& base, const xAddressReg& index, int factor, s32 displacement )
{ {
Base = base; Base = base;
Index = index; Index = index;
Factor = factor; Factor = factor;
Displacement= displacement; 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." );
@ -494,28 +501,28 @@ xAddressVoid::xAddressVoid( const xAddressReg& base, const xAddressReg& index, i
xAddressVoid::xAddressVoid( const xAddressReg& index, int displacement ) xAddressVoid::xAddressVoid( const xAddressReg& index, int displacement )
{ {
Base = xEmptyReg; Base = xEmptyReg;
Index = index; Index = index;
Factor = 0; Factor = 0;
Displacement= displacement; Displacement = displacement;
pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." ); pxAssertMsg( index.Id != xRegId_Invalid, "Uninitialized x86 register." );
} }
xAddressVoid::xAddressVoid( s32 displacement ) xAddressVoid::xAddressVoid( s32 displacement )
{ {
Base = xEmptyReg; Base = xEmptyReg;
Index = xEmptyReg; Index = xEmptyReg;
Factor = 0; Factor = 0;
Displacement= displacement; Displacement = displacement;
} }
xAddressVoid::xAddressVoid( const void* displacement ) xAddressVoid::xAddressVoid( const void* displacement )
{ {
Base = xEmptyReg; Base = xEmptyReg;
Index = xEmptyReg; Index = xEmptyReg;
Factor = 0; Factor = 0;
Displacement= (s32)displacement; Displacement = (sptr)displacement;
} }
xAddressVoid& xAddressVoid::Add( const xAddressReg& src ) xAddressVoid& xAddressVoid::Add( const xAddressReg& src )