Fix a couple issues in the x86emitter on x86_64.

This won't fix the billions of errors that will happen at runtime of using the x86 emitter, but chooses to make some better coding practice choices
that enables it to compile on x86_64.

in the xIndirectVoid class, instead of using s32 for the offset, use sptr which will be 32bit or 64bit depending on architecture.
This also fixes a few alignment issues in xAddressVoid's constructors.

In EmitSibMagic we are casting a void* to s32, which won't work on x86_64, so first do a cast from sptr to s32.
Won't work on x86_64, but gets us compiling.
This commit is contained in:
Ryan Houdek 2014-07-30 18:18:10 -05:00
parent e726f82344
commit b4771030d3
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
{
public:
xAddressReg Base; // base register (no scale)
xAddressReg Index; // index reg gets multiplied by the scale
uint Scale; // scale applied to the index register, in scale/shift form
s32 Displacement; // offset applied to the Base/Index registers.
xAddressReg Base; // base register (no scale)
xAddressReg Index; // index reg gets multiplied by the scale
uint Scale; // scale applied to the index register, in scale/shift form
sptr Displacement; // offset applied to the Base/Index registers.
public:
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 )
{
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
{
pxAssertMsg( Id != -1, "Uninitialized x86 register." );
return xAddressVoid( *this, -(s32)right );
return xAddressVoid( *this, -(sptr)right );
}
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 )
{
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( 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 )
{
Base = xEmptyReg;
Index = index;
Factor = 0;
Displacement= 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;
Base = xEmptyReg;
Index = xEmptyReg;
Factor = 0;
Displacement = displacement;
}
xAddressVoid::xAddressVoid( const void* displacement )
{
Base = xEmptyReg;
Index = xEmptyReg;
Factor = 0;
Displacement= (s32)displacement;
Base = xEmptyReg;
Index = xEmptyReg;
Factor = 0;
Displacement = (sptr)displacement;
}
xAddressVoid& xAddressVoid::Add( const xAddressReg& src )