From be0b8cf2f52840db3189955fd19648dedd4cd078 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sat, 16 Jan 2016 20:47:13 +0100 Subject: [PATCH] x86emitter: implement some function to emit the REX prefix Same fashion as EmitSibMagic --- common/include/x86emitter/internal.h | 6 ++++ common/src/x86emitter/x86emitter.cpp | 50 +++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/common/include/x86emitter/internal.h b/common/include/x86emitter/internal.h index c8e555ae27..6bf573ead8 100644 --- a/common/include/x86emitter/internal.h +++ b/common/include/x86emitter/internal.h @@ -31,6 +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 _xMovRtoR( const xRegisterInt& to, const xRegisterInt& from ); template< typename T > inline diff --git a/common/src/x86emitter/x86emitter.cpp b/common/src/x86emitter/x86emitter.cpp index fc2f906c1b..2717c04e40 100644 --- a/common/src/x86emitter/x86emitter.cpp +++ b/common/src/x86emitter/x86emitter.cpp @@ -321,8 +321,9 @@ static __fi bool NeedsSibMagic( const xIndirectVoid& info ) // void EmitSibMagic( uint regfield, const xIndirectVoid& info ) { + // 3 bits also on x86_64 (so max is 8) + // We might need to mask it on x86_64 pxAssertDev( regfield < 8, "Invalid x86 register identifier." ); - int displacement_size = (info.Displacement == 0) ? 0 : ( ( info.IsByteSizeDisp() ) ? 1 : 2 ); @@ -404,6 +405,53 @@ void EmitSibMagic( const xRegisterBase& reg1, const xIndirectVoid& sib ) EmitSibMagic( reg1.Id, sib ); } +////////////////////////////////////////////////////////////////////////////////////////// +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 ); +} + +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 ); +} + +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 b = sib.Base.IsExtended(); + xWrite8( 0x40 | 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 // --------------------------------------------------------------------------------------