mirror of https://github.com/PCSX2/pcsx2.git
Reverted the emitter back to a c/cpp form from inl files (probably wasn't necessary, but I don't like having code in header/inl files when I can help it). Also:
* Fixed a couple potential bugs in some Rm forms of MMX instructions. * Improved compilation times by isolating BaseBlockEx.h to the files the needed it (it uses STL junks). * Removed some dead code form emitters and BaseBlockEx. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@921 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
1d9adee468
commit
5f354c3cee
|
@ -20,11 +20,11 @@
|
||||||
#define __PCSX2CONFIG_H__
|
#define __PCSX2CONFIG_H__
|
||||||
|
|
||||||
// Hack so that you can still use this file from C (not C++), or from a plugin without access to Paths.h.
|
// Hack so that you can still use this file from C (not C++), or from a plugin without access to Paths.h.
|
||||||
#ifdef PLUGIN_ONLY
|
// .. and removed in favor of a less hackish approach (air)
|
||||||
|
|
||||||
|
#ifndef g_MaxPath
|
||||||
#define g_MaxPath 255
|
#define g_MaxPath 255
|
||||||
#else
|
#endif
|
||||||
#include "Paths.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// Session Configuration Override Flags
|
// Session Configuration Override Flags
|
||||||
|
|
|
@ -29,8 +29,10 @@
|
||||||
|
|
||||||
#define PCSX2_VERSION "(beta)"
|
#define PCSX2_VERSION "(beta)"
|
||||||
|
|
||||||
#include "Plugins.h"
|
#include "System.h"
|
||||||
|
|
||||||
#include "SaveState.h"
|
#include "SaveState.h"
|
||||||
|
#include "Plugins.h"
|
||||||
|
|
||||||
#include "DebugTools/Debug.h"
|
#include "DebugTools/Debug.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
@ -40,7 +42,4 @@
|
||||||
#include "Elfheader.h"
|
#include "Elfheader.h"
|
||||||
#include "Patch.h"
|
#include "Patch.h"
|
||||||
|
|
||||||
#include "System.h"
|
|
||||||
#include "Pcsx2Config.h"
|
|
||||||
|
|
||||||
#endif /* __COMMON_H__ */
|
#endif /* __COMMON_H__ */
|
||||||
|
|
|
@ -16,11 +16,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PCSX2_EXCEPTIONS_H_
|
#pragma once
|
||||||
#define _PCSX2_EXCEPTIONS_H_
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "StringUtils.h"
|
|
||||||
|
|
||||||
// This class provides an easy and clean method for ensuring objects are not copyable.
|
// This class provides an easy and clean method for ensuring objects are not copyable.
|
||||||
class NoncopyableObject
|
class NoncopyableObject
|
||||||
|
@ -380,5 +376,3 @@ namespace Exception
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Include the STL junk that's actually handy.
|
// Include the STL junk that's actually handy.
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -69,7 +70,9 @@ typedef int BOOL;
|
||||||
|
|
||||||
#include "zlib/zlib.h"
|
#include "zlib/zlib.h"
|
||||||
#include "PS2Etypes.h"
|
#include "PS2Etypes.h"
|
||||||
|
#include "MemcpyFast.h"
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
|
#include "Exceptions.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Compiler/OS specific macros and defines -- Begin Section
|
// Compiler/OS specific macros and defines -- Begin Section
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#ifndef _R5900_OPCODETABLES_H
|
#ifndef _R5900_OPCODETABLES_H
|
||||||
#define _R5900_OPCODETABLES_H
|
#define _R5900_OPCODETABLES_H
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "PS2Etypes.h"
|
#include "PS2Etypes.h"
|
||||||
|
|
||||||
// TODO : Move these into the OpcodeTables namespace
|
// TODO : Move these into the OpcodeTables namespace
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
#define __SYSTEM_H__
|
#define __SYSTEM_H__
|
||||||
|
|
||||||
#include "PS2Etypes.h"
|
#include "PS2Etypes.h"
|
||||||
|
#include "Paths.h"
|
||||||
#include "Pcsx2Config.h"
|
#include "Pcsx2Config.h"
|
||||||
#include "Exceptions.h"
|
#include "Exceptions.h"
|
||||||
#include "Paths.h"
|
|
||||||
#include "MemcpyFast.h"
|
#include "MemcpyFast.h"
|
||||||
#include "SafeArray.h"
|
#include "SafeArray.h"
|
||||||
#include "Misc.h"
|
#include "Misc.h"
|
||||||
|
|
|
@ -947,7 +947,6 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
UsePrecompiledHeader="1"
|
UsePrecompiledHeader="1"
|
||||||
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
|
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -2912,149 +2911,36 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86.inl"
|
RelativePath="..\..\x86\ix86\ix86_3dnow.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\x86\ix86\ix86_3dnow.inl"
|
|
||||||
>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Devel vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Release vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_cpudetect.cpp"
|
RelativePath="..\..\x86\ix86\ix86_cpudetect.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_fpu.inl"
|
RelativePath="..\..\x86\ix86\ix86_fpu.cpp"
|
||||||
>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Devel vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Release vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\x86\ix86\ix86_group1.inl"
|
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_mmx.inl"
|
RelativePath="..\..\x86\ix86\ix86_group1.cpp"
|
||||||
>
|
>
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Devel vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Release vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_sse.inl"
|
RelativePath="..\..\x86\ix86\ix86_internal.h"
|
||||||
>
|
>
|
||||||
<FileConfiguration
|
</File>
|
||||||
Name="Debug|Win32"
|
<File
|
||||||
|
RelativePath="..\..\x86\ix86\ix86_legacy.cpp"
|
||||||
>
|
>
|
||||||
<Tool
|
</File>
|
||||||
Name="VCCustomBuildTool"
|
<File
|
||||||
/>
|
RelativePath="..\..\x86\ix86\ix86_mmx.cpp"
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Devel vm|Win32"
|
|
||||||
>
|
>
|
||||||
<Tool
|
</File>
|
||||||
Name="VCCLCompilerTool"
|
<File
|
||||||
UsePrecompiledHeader="0"
|
RelativePath="..\..\x86\ix86\ix86_sse.cpp"
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug vm|Win32"
|
|
||||||
>
|
>
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Release vm|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\x86\ix86\ix86_sse_helpers.h"
|
RelativePath="..\..\x86\ix86\ix86_sse_helpers.h"
|
||||||
|
|
|
@ -18,14 +18,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include <map> // used by BaseBlockEx
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
// used to keep block information
|
|
||||||
#define BLOCKTYPE_DELAYSLOT 1 // if bit set, delay slot
|
|
||||||
|
|
||||||
// Every potential jump point in the PS2's addressable memory has a BASEBLOCK
|
// Every potential jump point in the PS2's addressable memory has a BASEBLOCK
|
||||||
// associated with it. So that means a BASEBLOCK for every 4 bytes of PS2
|
// associated with it. So that means a BASEBLOCK for every 4 bytes of PS2
|
||||||
// addressable memory. Yay!
|
// addressable memory. Yay!
|
||||||
|
@ -119,7 +114,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GET_BLOCKTYPE(b) ((b)->Type)
|
|
||||||
#define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (x)*(sizeof(BASEBLOCK)/4)))
|
#define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (x)*(sizeof(BASEBLOCK)/4)))
|
||||||
|
|
||||||
static void recLUT_SetPage(uptr reclut[0x10000], uptr hwlut[0x10000],
|
static void recLUT_SetPage(uptr reclut[0x10000], uptr hwlut[0x10000],
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
#include "Misc.h"
|
#include "System.h"
|
||||||
#include "iR5900.h"
|
#include "iR5900.h"
|
||||||
#include "Vif.h"
|
#include "Vif.h"
|
||||||
#include "VU.h"
|
#include "VU.h"
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
#include "iR3000A.h"
|
#include "iR3000A.h"
|
||||||
|
#include "BaseblockEx.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
|
@ -18,12 +18,10 @@
|
||||||
#ifndef _R3000A_SUPERREC_
|
#ifndef _R3000A_SUPERREC_
|
||||||
#define _R3000A_SUPERREC_
|
#define _R3000A_SUPERREC_
|
||||||
|
|
||||||
#define _EmitterId_ EmitterId_R3000a
|
|
||||||
#include "ix86/ix86.h"
|
#include "ix86/ix86.h"
|
||||||
|
|
||||||
#include "R3000A.h"
|
#include "R3000A.h"
|
||||||
#include "iCore.h"
|
#include "iCore.h"
|
||||||
#include "BaseblockEx.h"
|
|
||||||
|
|
||||||
// Cycle penalties for particularly slow instructions.
|
// Cycle penalties for particularly slow instructions.
|
||||||
static const int psxInstCycles_Mult = 7;
|
static const int psxInstCycles_Mult = 7;
|
||||||
|
|
|
@ -19,13 +19,11 @@
|
||||||
#ifndef __IR5900_H__
|
#ifndef __IR5900_H__
|
||||||
#define __IR5900_H__
|
#define __IR5900_H__
|
||||||
|
|
||||||
#define _EmitterId_ EmitterId_R5900
|
|
||||||
#include "ix86/ix86.h"
|
#include "ix86/ix86.h"
|
||||||
#include "ix86/ix86_sse_helpers.h"
|
#include "ix86/ix86_sse_helpers.h"
|
||||||
#include "R5900.h"
|
#include "R5900.h"
|
||||||
#include "VU.h"
|
#include "VU.h"
|
||||||
#include "iCore.h"
|
#include "iCore.h"
|
||||||
#include "BaseblockEx.h" // needed for recClear and stuff
|
|
||||||
|
|
||||||
// Yay! These work now! (air) ... almost (air)
|
// Yay! These work now! (air) ... almost (air)
|
||||||
#define ARITHMETICIMM_RECOMPILE
|
#define ARITHMETICIMM_RECOMPILE
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
#include "Misc.h"
|
#include "System.h"
|
||||||
#include "iR5900.h"
|
#include "iR5900.h"
|
||||||
#include "Vif.h"
|
#include "Vif.h"
|
||||||
#include "VU.h"
|
#include "VU.h"
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#include "iR5900Jump.h"
|
#include "iR5900Jump.h"
|
||||||
#include "iR5900LoadStore.h"
|
#include "iR5900LoadStore.h"
|
||||||
#include "iR5900Move.h"
|
#include "iR5900Move.h"
|
||||||
|
|
||||||
|
#include "BaseblockEx.h"
|
||||||
|
|
||||||
#include "iMMI.h"
|
#include "iMMI.h"
|
||||||
#include "iFPU.h"
|
#include "iFPU.h"
|
||||||
#include "iCOP0.h"
|
#include "iCOP0.h"
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
#include "ix86.h"
|
#include "ix86_internal.h"
|
||||||
|
|
||||||
__threadlocal u8 *x86Ptr;
|
__threadlocal u8 *x86Ptr;
|
||||||
__threadlocal u8 *j8Ptr[32];
|
__threadlocal u8 *j8Ptr[32];
|
||||||
|
@ -39,69 +39,59 @@ PCSX2_ALIGNED16(float f[4]);
|
||||||
|
|
||||||
XMMSSEType g_xmmtypes[XMMREGS] = { XMMT_INT };
|
XMMSSEType g_xmmtypes[XMMREGS] = { XMMT_INT };
|
||||||
|
|
||||||
namespace x86Emitter
|
namespace x86Emitter {
|
||||||
|
|
||||||
|
x86IndexerType ptr;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
const x86Register x86Register::Empty( -1 );
|
||||||
|
|
||||||
|
const x86Register eax( 0 );
|
||||||
|
const x86Register ebx( 3 );
|
||||||
|
const x86Register ecx( 1 );
|
||||||
|
const x86Register edx( 2 );
|
||||||
|
const x86Register esi( 6 );
|
||||||
|
const x86Register edi( 7 );
|
||||||
|
const x86Register ebp( 5 );
|
||||||
|
const x86Register esp( 4 );
|
||||||
|
|
||||||
|
const x86Register16 ax( 0 );
|
||||||
|
const x86Register16 bx( 3 );
|
||||||
|
const x86Register16 cx( 1 );
|
||||||
|
const x86Register16 dx( 2 );
|
||||||
|
const x86Register16 si( 6 );
|
||||||
|
const x86Register16 di( 7 );
|
||||||
|
const x86Register16 bp( 5 );
|
||||||
|
const x86Register16 sp( 4 );
|
||||||
|
|
||||||
|
const x86Register8 al( 0 );
|
||||||
|
const x86Register8 cl( 1 );
|
||||||
|
const x86Register8 dl( 2 );
|
||||||
|
const x86Register8 bl( 3 );
|
||||||
|
const x86Register8 ah( 4 );
|
||||||
|
const x86Register8 ch( 5 );
|
||||||
|
const x86Register8 dh( 6 );
|
||||||
|
const x86Register8 bh( 7 );
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// x86Register Method Implementations
|
||||||
|
//
|
||||||
|
x86ModRm x86Register::operator+( const x86Register& right ) const
|
||||||
{
|
{
|
||||||
x86IndexerType ptr;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
const x86Register x86Register::Empty( -1 );
|
|
||||||
|
|
||||||
const x86Register eax( 0 );
|
|
||||||
const x86Register ebx( 3 );
|
|
||||||
const x86Register ecx( 1 );
|
|
||||||
const x86Register edx( 2 );
|
|
||||||
const x86Register esi( 6 );
|
|
||||||
const x86Register edi( 7 );
|
|
||||||
const x86Register ebp( 5 );
|
|
||||||
const x86Register esp( 4 );
|
|
||||||
|
|
||||||
const x86Register16 ax( 0 );
|
|
||||||
const x86Register16 bx( 3 );
|
|
||||||
const x86Register16 cx( 1 );
|
|
||||||
const x86Register16 dx( 2 );
|
|
||||||
const x86Register16 si( 6 );
|
|
||||||
const x86Register16 di( 7 );
|
|
||||||
const x86Register16 bp( 5 );
|
|
||||||
const x86Register16 sp( 4 );
|
|
||||||
|
|
||||||
const x86Register8 al( 0 );
|
|
||||||
const x86Register8 cl( 1 );
|
|
||||||
const x86Register8 dl( 2 );
|
|
||||||
const x86Register8 bl( 3 );
|
|
||||||
const x86Register8 ah( 4 );
|
|
||||||
const x86Register8 ch( 5 );
|
|
||||||
const x86Register8 dh( 6 );
|
|
||||||
const x86Register8 bh( 7 );
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// x86Register Method Implementations
|
|
||||||
//
|
|
||||||
x86ModRm x86Register::operator+( const x86Register& right ) const
|
|
||||||
{
|
|
||||||
return x86ModRm( *this, right );
|
return x86ModRm( *this, right );
|
||||||
}
|
}
|
||||||
|
|
||||||
x86ModRm x86Register::operator+( const x86ModRm& right ) const
|
x86ModRm x86Register::operator+( const x86ModRm& right ) const
|
||||||
{
|
{
|
||||||
return right + *this;
|
return right + *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ModSib Method Implementations
|
// x86ModRm Method Implementations
|
||||||
//
|
//
|
||||||
x86ModRm x86ModRm::FromIndexReg( x86Register index, int scale, int displacement )
|
x86ModRm& x86ModRm::Add( const x86Register& src )
|
||||||
{
|
{
|
||||||
return x86ModRm( x86Register::Empty, index, scale, displacement );
|
|
||||||
}
|
|
||||||
|
|
||||||
x86Register x86ModRm::GetEitherReg() const
|
|
||||||
{
|
|
||||||
return Base.IsEmpty() ? Base : Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
x86ModRm& x86ModRm::Add( const x86Register& src )
|
|
||||||
{
|
|
||||||
if( src == Index )
|
if( src == Index )
|
||||||
{
|
{
|
||||||
Factor++;
|
Factor++;
|
||||||
|
@ -128,10 +118,10 @@ namespace x86Emitter
|
||||||
assert( false ); // oops, only 2 regs allowed per ModRm!
|
assert( false ); // oops, only 2 regs allowed per ModRm!
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
x86ModRm& x86ModRm::Add( const x86ModRm& src )
|
x86ModRm& x86ModRm::Add( const x86ModRm& src )
|
||||||
{
|
{
|
||||||
Add( src.Base );
|
Add( src.Base );
|
||||||
Add( src.Displacement );
|
Add( src.Displacement );
|
||||||
|
|
||||||
|
@ -151,17 +141,18 @@ namespace x86Emitter
|
||||||
assert( false ); // oops, only 2 regs allowed!
|
assert( false ); // oops, only 2 regs allowed!
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ModSib Method Implementations
|
||||||
|
//
|
||||||
|
|
||||||
x86ModRm x86ptr( x86Register base ) { return x86ModRm( base ); }
|
// ------------------------------------------------------------------------
|
||||||
|
// Generates a 'reduced' ModSib form, which has valid Base, Index, and Scale values.
|
||||||
// ------------------------------------------------------------------------
|
// Necessary because by default ModSib compounds registers into Index when possible.
|
||||||
// Generates a 'reduced' ModSib form, which has valid Base, Index, and Scale values.
|
//
|
||||||
// Necessary because by default ModSib compounds registers into Index when possible.
|
void ModSib::Reduce()
|
||||||
//
|
{
|
||||||
void ModSib::Reduce()
|
|
||||||
{
|
|
||||||
// If no index reg, then nothing for us to do...
|
// If no index reg, then nothing for us to do...
|
||||||
if( Index.IsEmpty() || Scale == 0 ) return;
|
if( Index.IsEmpty() || Scale == 0 ) return;
|
||||||
|
|
||||||
|
@ -201,36 +192,113 @@ namespace x86Emitter
|
||||||
Scale = 3;
|
Scale = 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModSib::ModSib( const x86ModRm& src ) :
|
ModSib::ModSib( const x86ModRm& src ) :
|
||||||
Base( src.Base ),
|
Base( src.Base ),
|
||||||
Index( src.Index ),
|
Index( src.Index ),
|
||||||
Scale( src.Factor ),
|
Scale( src.Factor ),
|
||||||
Displacement( src.Displacement )
|
Displacement( src.Displacement )
|
||||||
{
|
{
|
||||||
Reduce();
|
Reduce();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModSib::ModSib( x86Register base, x86Register index, int scale, s32 displacement ) :
|
ModSib::ModSib( x86Register base, x86Register index, int scale, s32 displacement ) :
|
||||||
Base( base ),
|
Base( base ),
|
||||||
Index( index ),
|
Index( index ),
|
||||||
Scale( scale ),
|
Scale( scale ),
|
||||||
Displacement( displacement )
|
Displacement( displacement )
|
||||||
{
|
{
|
||||||
Reduce();
|
Reduce();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModSib::ModSib( s32 displacement ) :
|
ModSib::ModSib( s32 displacement ) :
|
||||||
Base(),
|
Base(),
|
||||||
Index(),
|
Index(),
|
||||||
Scale(0),
|
Scale(0),
|
||||||
Displacement( displacement )
|
Displacement( displacement )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
x86Register ModSib::GetEitherReg() const
|
||||||
|
{
|
||||||
|
return Base.IsEmpty() ? Base : Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// returns TRUE if this instruction requires SIB to be encoded, or FALSE if the
|
||||||
|
// instruction ca be encoded as ModRm alone.
|
||||||
|
emitterT bool NeedsSibMagic( const ModSib& info )
|
||||||
|
{
|
||||||
|
// no registers? no sibs!
|
||||||
|
if( info.Base.IsEmpty() && info.Index.IsEmpty() ) return false;
|
||||||
|
|
||||||
|
// A scaled register needs a SIB
|
||||||
|
if( info.Scale != 0 && !info.Index.IsEmpty() ) return true;
|
||||||
|
|
||||||
|
// two registers needs a SIB
|
||||||
|
if( !info.Base.IsEmpty() && !info.Index.IsEmpty() ) return true;
|
||||||
|
|
||||||
|
// If register is ESP, then we need a SIB:
|
||||||
|
if( info.Base == esp || info.Index == esp ) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Conditionally generates Sib encoding information!
|
||||||
|
//
|
||||||
|
// regfield - register field to be written to the ModRm. This is either a register specifier
|
||||||
|
// or an opcode extension. In either case, the instruction determines the value for us.
|
||||||
|
//
|
||||||
|
emitterT void EmitSibMagic( int regfield, const ModSib& info )
|
||||||
|
{
|
||||||
|
int displacement_size = (info.Displacement == 0) ? 0 :
|
||||||
|
( ( info.IsByteSizeDisp() ) ? 1 : 2 );
|
||||||
|
|
||||||
|
if( !NeedsSibMagic( info ) )
|
||||||
{
|
{
|
||||||
|
// Use ModRm-only encoding, with the rm field holding an index/base register, if
|
||||||
|
// one has been specified. If neither register is specified then use Disp32 form,
|
||||||
|
// which is encoded as "EBP w/o displacement" (which is why EBP must always be
|
||||||
|
// encoded *with* a displacement of 0, if it would otherwise not have one).
|
||||||
|
|
||||||
|
x86Register basereg = info.GetEitherReg();
|
||||||
|
|
||||||
|
if( basereg.IsEmpty() )
|
||||||
|
ModRM( 0, regfield, ModRm_UseDisp32 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( basereg == ebp && displacement_size == 0 )
|
||||||
|
displacement_size = 1; // forces [ebp] to be encoded as [ebp+0]!
|
||||||
|
|
||||||
|
ModRM( displacement_size, regfield, basereg.Id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ModRM( displacement_size, regfield, ModRm_UseSib );
|
||||||
|
SibSB( info.Index.Id, info.Scale, info.Base.Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
x86Register ModSib::GetEitherReg() const
|
switch( displacement_size )
|
||||||
{
|
{
|
||||||
return Base.IsEmpty() ? Base : Index;
|
case 0: break;
|
||||||
|
case 1: write8( info.Displacement ); break;
|
||||||
|
case 2: write32( info.Displacement ); break;
|
||||||
|
jNO_DEFAULT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Conditionally generates Sib encoding information!
|
||||||
|
//
|
||||||
|
// regfield - register field to be written to the ModRm. This is either a register specifier
|
||||||
|
// or an opcode extension. In either case, the instruction determines the value for us.
|
||||||
|
//
|
||||||
|
emitterT void EmitSibMagic( x86Register regfield, const ModSib& info )
|
||||||
|
{
|
||||||
|
EmitSibMagic( regfield.Id, info );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,7 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#include "PrecompiledHeader.h"
|
||||||
|
#include "ix86_internal.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// 3DNOW instructions
|
// 3DNOW instructions
|
|
@ -18,10 +18,8 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
#define _EmitterId_ 0
|
#include "ix86_internal.h"
|
||||||
|
#include "System.h"
|
||||||
#include "ix86.h"
|
|
||||||
#include "Misc.h"
|
|
||||||
#include "Threading.h"
|
#include "Threading.h"
|
||||||
|
|
||||||
#include "RedtapeWindows.h"
|
#include "RedtapeWindows.h"
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#include "PrecompiledHeader.h"
|
||||||
//#include "PrecompiledHeader.h"
|
#include "ix86_internal.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// FPU instructions
|
// FPU instructions
|
|
@ -16,7 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#include "PrecompiledHeader.h"
|
||||||
|
#include "ix86_internal.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// x86 Group 1 Instructions
|
// x86 Group 1 Instructions
|
||||||
|
@ -32,85 +33,6 @@
|
||||||
|
|
||||||
namespace x86Emitter {
|
namespace x86Emitter {
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// returns TRUE if this instruction requires SIB to be encoded, or FALSE if the
|
|
||||||
// instruction ca be encoded as ModRm alone.
|
|
||||||
emitterT bool NeedsSibMagic( const ModSib& info )
|
|
||||||
{
|
|
||||||
// no registers? no sibs!
|
|
||||||
if( info.Base.IsEmpty() && info.Index.IsEmpty() ) return false;
|
|
||||||
|
|
||||||
// A scaled register needs a SIB
|
|
||||||
if( info.Scale != 0 && !info.Index.IsEmpty() ) return true;
|
|
||||||
|
|
||||||
// two registers needs a SIB
|
|
||||||
if( !info.Base.IsEmpty() && !info.Index.IsEmpty() ) return true;
|
|
||||||
|
|
||||||
// If register is ESP, then we need a SIB:
|
|
||||||
if( info.Base == esp || info.Index == esp ) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// Conditionally generates Sib encoding information!
|
|
||||||
//
|
|
||||||
// regfield - register field to be written to the ModRm. This is either a register specifier
|
|
||||||
// or an opcode extension. In either case, the instruction determines the value for us.
|
|
||||||
//
|
|
||||||
emitterT void EmitSibMagic( int regfield, const ModSib& info )
|
|
||||||
{
|
|
||||||
int displacement_size = (info.Displacement == 0) ? 0 :
|
|
||||||
( ( info.IsByteSizeDisp() ) ? 1 : 2 );
|
|
||||||
|
|
||||||
if( !NeedsSibMagic( info ) )
|
|
||||||
{
|
|
||||||
// Use ModRm-only encoding, with the rm field holding an index/base register, if
|
|
||||||
// one has been specified. If neither register is specified then use Disp32 form,
|
|
||||||
// which is encoded as "EBP w/o displacement" (which is why EBP must always be
|
|
||||||
// encoded *with* a displacement of 0, if it would otherwise not have one).
|
|
||||||
|
|
||||||
x86Register basereg = info.GetEitherReg();
|
|
||||||
|
|
||||||
if( basereg.IsEmpty() )
|
|
||||||
ModRM( 0, regfield, ModRm_UseDisp32 );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( basereg == ebp && displacement_size == 0 )
|
|
||||||
displacement_size = 1; // forces [ebp] to be encoded as [ebp+0]!
|
|
||||||
|
|
||||||
ModRM( displacement_size, regfield, basereg.Id );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ModRM( displacement_size, regfield, ModRm_UseSib );
|
|
||||||
SibSB( info.Index.Id, info.Scale, info.Base.Id );
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( displacement_size )
|
|
||||||
{
|
|
||||||
case 0: break;
|
|
||||||
case 1: write8( info.Displacement ); break;
|
|
||||||
case 2: write32( info.Displacement ); break;
|
|
||||||
jNO_DEFAULT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// Conditionally generates Sib encoding information!
|
|
||||||
//
|
|
||||||
// regfield - register field to be written to the ModRm. This is either a register specifier
|
|
||||||
// or an opcode extension. In either case, the instruction determines the value for us.
|
|
||||||
//
|
|
||||||
emitterT void EmitSibMagic( x86Register regfield, const ModSib& info )
|
|
||||||
{
|
|
||||||
EmitSibMagic( regfield.Id, info );
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Group1InstructionType
|
enum Group1InstructionType
|
||||||
{
|
{
|
||||||
G1Type_ADD=0,
|
G1Type_ADD=0,
|
||||||
|
@ -245,9 +167,9 @@ static __forceinline x86Emitter::x86ModRm _mrmhlp( x86IntRegType src )
|
||||||
emitterT void cod##32MtoR( x86IntRegType to, uptr from ) { x86Emitter::lwr##32( _reghlp(to), (void*)from ); } \
|
emitterT void cod##32MtoR( x86IntRegType to, uptr from ) { x86Emitter::lwr##32( _reghlp(to), (void*)from ); } \
|
||||||
emitterT void cod##32RtoM( uptr to, x86IntRegType from ) { x86Emitter::lwr##32( (void*)to, _reghlp(from) ); } \
|
emitterT void cod##32RtoM( uptr to, x86IntRegType from ) { x86Emitter::lwr##32( (void*)to, _reghlp(from) ); } \
|
||||||
emitterT void cod##32ItoM( uptr to, u32 imm ) { x86Emitter::lwr##32( (void*)to, imm ); } \
|
emitterT void cod##32ItoM( uptr to, u32 imm ) { x86Emitter::lwr##32( (void*)to, imm ); } \
|
||||||
emitterT void cod##32ItoRm( x86IntRegType to, u32 imm, int offset=0 ){ x86Emitter::lwr##32( _mrmhlp(to) + offset, imm ); } \
|
emitterT void cod##32ItoRm( x86IntRegType to, u32 imm, int offset ){ x86Emitter::lwr##32( _mrmhlp(to) + offset, imm ); } \
|
||||||
emitterT void cod##32RmtoR( x86IntRegType to, x86IntRegType from, int offset=0 ) { x86Emitter::lwr##32( _reghlp(to), _mrmhlp(from) + offset ); } \
|
emitterT void cod##32RmtoR( x86IntRegType to, x86IntRegType from, int offset ) { x86Emitter::lwr##32( _reghlp(to), _mrmhlp(from) + offset ); } \
|
||||||
emitterT void cod##32RtoRm( x86IntRegType to, x86IntRegType from, int offset=0 ) { x86Emitter::lwr##32( _mrmhlp(to) + offset, _reghlp(from) ); }
|
emitterT void cod##32RtoRm( x86IntRegType to, x86IntRegType from, int offset ) { x86Emitter::lwr##32( _mrmhlp(to) + offset, _reghlp(from) ); }
|
||||||
|
|
||||||
DEFINE_GROUP1_OPCODE_LEGACY( add, ADD );
|
DEFINE_GROUP1_OPCODE_LEGACY( add, ADD );
|
||||||
DEFINE_GROUP1_OPCODE_LEGACY( cmp, CMP );
|
DEFINE_GROUP1_OPCODE_LEGACY( cmp, CMP );
|
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "ix86.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// Helper Macros
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define MEMADDR(addr, oplen) (addr)
|
||||||
|
|
||||||
|
#define Rex(w,r,x,b) assert(0)
|
||||||
|
#define RexR(w, reg) assert( !(w || (reg)>=8) )
|
||||||
|
#define RexB(w, base) assert( !(w || (base)>=8) )
|
||||||
|
#define RexRB(w, reg, base) assert( !(w || (reg) >= 8 || (base)>=8) )
|
||||||
|
#define RexRXB(w, reg, index, base) assert( !(w || (reg) >= 8 || (index) >= 8 || (base) >= 8) )
|
||||||
|
|
||||||
|
#define _MM_MK_INSERTPS_NDX(srcField, dstField, zeroMask) (((srcField)<<6) | ((dstField)<<4) | (zeroMask))
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// General Emitter Helper functions
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace x86Emitter
|
||||||
|
{
|
||||||
|
extern void EmitSibMagic( int regfield, const ModSib& info );
|
||||||
|
extern void EmitSibMagic( x86Register regfield, const ModSib& info );
|
||||||
|
extern bool NeedsSibMagic( const ModSib& info );
|
||||||
|
}
|
||||||
|
|
||||||
|
// From here out are the legacy (old) emitter functions...
|
||||||
|
|
||||||
|
extern void WriteRmOffsetFrom(x86IntRegType to, x86IntRegType from, int offset);
|
||||||
|
extern void ModRM( int mod, int reg, int rm );
|
||||||
|
extern void SibSB( int ss, int index, int base );
|
||||||
|
extern void SET8R( int cc, int to );
|
||||||
|
extern u8* J8Rel( int cc, int to );
|
||||||
|
extern u32* J32Rel( int cc, u32 to );
|
||||||
|
extern u64 GetCPUTick( void );
|
||||||
|
//------------------------------------------------------------------
|
|
@ -27,14 +27,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// ix86 instructions
|
// ix86 legacy emitter functions
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
#include "ix86.h"
|
#include "ix86_internal.h"
|
||||||
|
|
||||||
#include "ix86_group1.inl"
|
|
||||||
|
|
||||||
// Note: the 'to' field can either be a register or a special opcode extension specifier
|
// Note: the 'to' field can either be a register or a special opcode extension specifier
|
||||||
// depending on the opcode's encoding.
|
// depending on the opcode's encoding.
|
||||||
|
@ -46,7 +44,7 @@ emitterT void WriteRmOffsetFrom(x86IntRegType to, x86IntRegType from, int offset
|
||||||
ModRM( 0, to, 0x4 );
|
ModRM( 0, to, 0x4 );
|
||||||
SibSB( 0, 0x4, 0x4 );
|
SibSB( 0, 0x4, 0x4 );
|
||||||
}
|
}
|
||||||
else if( offset <= 127 && offset >= -128 ) {
|
else if( is_s8( offset ) ) {
|
||||||
ModRM( 1, to, 0x4 );
|
ModRM( 1, to, 0x4 );
|
||||||
SibSB( 0, 0x4, 0x4 );
|
SibSB( 0, 0x4, 0x4 );
|
||||||
write8(offset);
|
write8(offset);
|
||||||
|
@ -61,7 +59,7 @@ emitterT void WriteRmOffsetFrom(x86IntRegType to, x86IntRegType from, int offset
|
||||||
if( offset == 0 ) {
|
if( offset == 0 ) {
|
||||||
ModRM( 0, to, from );
|
ModRM( 0, to, from );
|
||||||
}
|
}
|
||||||
else if( offset <= 127 && offset >= -128 ) {
|
else if( is_s8( offset ) ) {
|
||||||
ModRM( 1, to, from );
|
ModRM( 1, to, from );
|
||||||
write8(offset);
|
write8(offset);
|
||||||
}
|
}
|
||||||
|
@ -136,8 +134,13 @@ emitterT void x86SetPtr( u8* ptr )
|
||||||
x86Ptr = ptr;
|
x86Ptr = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
emitterT void x86SetJ8( u8* j8 )
|
// Jump Label API (as rough as it might be)
|
||||||
|
//
|
||||||
|
// I don't auto-inline these because of the console logging in case of error, which tends
|
||||||
|
// to cause quite a bit of code bloat.
|
||||||
|
//
|
||||||
|
void x86SetJ8( u8* j8 )
|
||||||
{
|
{
|
||||||
u32 jump = ( x86Ptr - j8 ) - 1;
|
u32 jump = ( x86Ptr - j8 ) - 1;
|
||||||
|
|
||||||
|
@ -148,7 +151,7 @@ emitterT void x86SetJ8( u8* j8 )
|
||||||
*j8 = (u8)jump;
|
*j8 = (u8)jump;
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void x86SetJ8A( u8* j8 )
|
void x86SetJ8A( u8* j8 )
|
||||||
{
|
{
|
||||||
u32 jump = ( x86Ptr - j8 ) - 1;
|
u32 jump = ( x86Ptr - j8 ) - 1;
|
||||||
|
|
||||||
|
@ -169,26 +172,6 @@ emitterT void x86SetJ8A( u8* j8 )
|
||||||
*j8 = (u8)jump;
|
*j8 = (u8)jump;
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void x86SetJ16( u16 *j16 )
|
|
||||||
{
|
|
||||||
// doesn't work
|
|
||||||
u32 jump = ( x86Ptr - (u8*)j16 ) - 2;
|
|
||||||
|
|
||||||
if ( jump > 0x7fff ) {
|
|
||||||
Console::Error( "j16 greater than 0x7fff!!" );
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
*j16 = (u16)jump;
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void x86SetJ16A( u16 *j16 )
|
|
||||||
{
|
|
||||||
if( ((uptr)x86Ptr&0xf) > 4 ) {
|
|
||||||
while((uptr)x86Ptr&0xf) *x86Ptr++ = 0x90;
|
|
||||||
}
|
|
||||||
x86SetJ16(j16);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
emitterT void x86SetJ32( u32* j32 )
|
emitterT void x86SetJ32( u32* j32 )
|
||||||
{
|
{
|
||||||
|
@ -211,7 +194,11 @@ emitterT void x86Align( int bytes )
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
// Generates executable code to align to the given alignment (could be useful for the second leg
|
// Generates executable code to align to the given alignment (could be useful for the second leg
|
||||||
// of if/else conditionals, which usually fall through a jump target label).
|
// of if/else conditionals, which usually fall through a jump target label).
|
||||||
emitterT void x86AlignExecutable( int align )
|
//
|
||||||
|
// Note: Left in for now just in case, but usefulness is moot. Only K8's and older (non-Prescott)
|
||||||
|
// P4s benefit from this, and we don't optimize for those platforms anyway.
|
||||||
|
//
|
||||||
|
void x86AlignExecutable( int align )
|
||||||
{
|
{
|
||||||
uptr newx86 = ( (uptr)x86Ptr + align - 1) & ~( align - 1 );
|
uptr newx86 = ( (uptr)x86Ptr + align - 1) & ~( align - 1 );
|
||||||
uptr bytes = ( newx86 - (uptr)x86Ptr );
|
uptr bytes = ( newx86 - (uptr)x86Ptr );
|
||||||
|
@ -242,7 +229,7 @@ emitterT void x86AlignExecutable( int align )
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************/
|
/********************/
|
||||||
/* IX86 intructions */
|
/* IX86 instructions */
|
||||||
/********************/
|
/********************/
|
||||||
|
|
||||||
emitterT void STC( void )
|
emitterT void STC( void )
|
||||||
|
@ -300,7 +287,7 @@ emitterT void MOV32MtoR( x86IntRegType to, uptr from )
|
||||||
write32( MEMADDR(from, 4) );
|
write32( MEMADDR(from, 4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOV32RmtoR( x86IntRegType to, x86IntRegType from, int offset=0 )
|
emitterT void MOV32RmtoR( x86IntRegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, to, from);
|
RexRB(0, to, from);
|
||||||
write8( 0x8B );
|
write8( 0x8B );
|
||||||
|
@ -308,7 +295,7 @@ emitterT void MOV32RmtoR( x86IntRegType to, x86IntRegType from, int offset=0 )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mov [r32+r32*scale] to r32 */
|
/* mov [r32+r32*scale] to r32 */
|
||||||
emitterT void MOV32RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale=0 )
|
emitterT void MOV32RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
||||||
{
|
{
|
||||||
RexRXB(0,to,from2,from);
|
RexRXB(0,to,from2,from);
|
||||||
write8( 0x8B );
|
write8( 0x8B );
|
||||||
|
@ -317,7 +304,7 @@ emitterT void MOV32RmStoR( x86IntRegType to, x86IntRegType from, x86IntRegType f
|
||||||
}
|
}
|
||||||
|
|
||||||
// mov r32 to [r32<<scale+from2]
|
// mov r32 to [r32<<scale+from2]
|
||||||
emitterT void MOV32RmSOffsettoR( x86IntRegType to, x86IntRegType from1, int from2, int scale=0 )
|
emitterT void MOV32RmSOffsettoR( x86IntRegType to, x86IntRegType from1, int from2, int scale )
|
||||||
{
|
{
|
||||||
RexRXB(0,to,from1,0);
|
RexRXB(0,to,from1,0);
|
||||||
write8( 0x8B );
|
write8( 0x8B );
|
||||||
|
@ -327,7 +314,7 @@ emitterT void MOV32RmSOffsettoR( x86IntRegType to, x86IntRegType from1, int from
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mov r32 to [r32][r32*scale] */
|
/* mov r32 to [r32][r32*scale] */
|
||||||
emitterT void MOV32RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale=0 )
|
emitterT void MOV32RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
||||||
{
|
{
|
||||||
RexRXB(0, to, from2, from);
|
RexRXB(0, to, from2, from);
|
||||||
write8( 0x89 );
|
write8( 0x89 );
|
||||||
|
@ -353,7 +340,7 @@ emitterT void MOV32ItoM(uptr to, u32 from )
|
||||||
}
|
}
|
||||||
|
|
||||||
// mov imm32 to [r32+off]
|
// mov imm32 to [r32+off]
|
||||||
emitterT void MOV32ItoRm( x86IntRegType to, u32 from, int offset=0)
|
emitterT void MOV32ItoRm( x86IntRegType to, u32 from, int offset)
|
||||||
{
|
{
|
||||||
RexB(0,to);
|
RexB(0,to);
|
||||||
write8( 0xC7 );
|
write8( 0xC7 );
|
||||||
|
@ -362,7 +349,7 @@ emitterT void MOV32ItoRm( x86IntRegType to, u32 from, int offset=0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mov r32 to [r32+off]
|
// mov r32 to [r32+off]
|
||||||
emitterT void MOV32RtoRm( x86IntRegType to, x86IntRegType from, int offset=0)
|
emitterT void MOV32RtoRm( x86IntRegType to, x86IntRegType from, int offset)
|
||||||
{
|
{
|
||||||
RexRB(0,from,to);
|
RexRB(0,from,to);
|
||||||
write8( 0x89 );
|
write8( 0x89 );
|
||||||
|
@ -389,7 +376,7 @@ emitterT void MOV16MtoR( x86IntRegType to, uptr from )
|
||||||
write32( MEMADDR(from, 4) );
|
write32( MEMADDR(from, 4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOV16RmtoR( x86IntRegType to, x86IntRegType from, int offset=0 )
|
emitterT void MOV16RmtoR( x86IntRegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
write8( 0x66 );
|
write8( 0x66 );
|
||||||
RexRB(0,to,from);
|
RexRB(0,to,from);
|
||||||
|
@ -397,7 +384,7 @@ emitterT void MOV16RmtoR( x86IntRegType to, x86IntRegType from, int offset=0 )
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
WriteRmOffsetFrom(to, from, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOV16RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale=0 )
|
emitterT void MOV16RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale )
|
||||||
{
|
{
|
||||||
write8(0x66);
|
write8(0x66);
|
||||||
RexRXB(0,to,from1,0);
|
RexRXB(0,to,from1,0);
|
||||||
|
@ -418,7 +405,7 @@ emitterT void MOV16ItoM( uptr to, u16 from )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mov r16 to [r32][r32*scale] */
|
/* mov r16 to [r32][r32*scale] */
|
||||||
emitterT void MOV16RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale=0 )
|
emitterT void MOV16RtoRmS( x86IntRegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
||||||
{
|
{
|
||||||
write8( 0x66 );
|
write8( 0x66 );
|
||||||
RexRXB(0,to,from2,from);
|
RexRXB(0,to,from2,from);
|
||||||
|
@ -445,7 +432,7 @@ emitterT void MOV16ItoRm( x86IntRegType to, u16 from, u32 offset=0 )
|
||||||
}
|
}
|
||||||
|
|
||||||
// mov r16 to [r16+off]
|
// mov r16 to [r16+off]
|
||||||
emitterT void MOV16RtoRm( x86IntRegType to, x86IntRegType from, int offset=0 )
|
emitterT void MOV16RtoRm( x86IntRegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
write8(0x66);
|
write8(0x66);
|
||||||
RexRB(0,from,to);
|
RexRB(0,from,to);
|
||||||
|
@ -471,14 +458,14 @@ emitterT void MOV8MtoR( x86IntRegType to, uptr from )
|
||||||
write32( MEMADDR(from, 4) );
|
write32( MEMADDR(from, 4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOV8RmtoR(x86IntRegType to, x86IntRegType from, int offset=0)
|
emitterT void MOV8RmtoR(x86IntRegType to, x86IntRegType from, int offset)
|
||||||
{
|
{
|
||||||
RexRB(0,to,from);
|
RexRB(0,to,from);
|
||||||
write8( 0x8A );
|
write8( 0x8A );
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
WriteRmOffsetFrom(to, from, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOV8RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale=0 )
|
emitterT void MOV8RmSOffsettoR( x86IntRegType to, x86IntRegType from1, u32 from2, int scale )
|
||||||
{
|
{
|
||||||
RexRXB(0,to,from1,0);
|
RexRXB(0,to,from1,0);
|
||||||
write8( 0x8A );
|
write8( 0x8A );
|
||||||
|
@ -505,7 +492,7 @@ emitterT void MOV8ItoR( x86IntRegType to, u8 from )
|
||||||
}
|
}
|
||||||
|
|
||||||
// mov imm8 to [r8+off]
|
// mov imm8 to [r8+off]
|
||||||
emitterT void MOV8ItoRm( x86IntRegType to, u8 from, int offset=0)
|
emitterT void MOV8ItoRm( x86IntRegType to, u8 from, int offset)
|
||||||
{
|
{
|
||||||
assert( to != ESP );
|
assert( to != ESP );
|
||||||
RexB(0,to);
|
RexB(0,to);
|
||||||
|
@ -515,7 +502,7 @@ emitterT void MOV8ItoRm( x86IntRegType to, u8 from, int offset=0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mov r8 to [r8+off]
|
// mov r8 to [r8+off]
|
||||||
emitterT void MOV8RtoRm( x86IntRegType to, x86IntRegType from, int offset=0)
|
emitterT void MOV8RtoRm( x86IntRegType to, x86IntRegType from, int offset)
|
||||||
{
|
{
|
||||||
assert( to != ESP );
|
assert( to != ESP );
|
||||||
RexRB(0,from,to);
|
RexRB(0,from,to);
|
||||||
|
@ -531,14 +518,7 @@ emitterT void MOVSX32R8toR( x86IntRegType to, x86IntRegType from )
|
||||||
ModRM( 3, to, from );
|
ModRM( 3, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVSX32Rm8toR( x86IntRegType to, x86IntRegType from )
|
emitterT void MOVSX32Rm8toR( x86IntRegType to, x86IntRegType from, int offset )
|
||||||
{
|
|
||||||
RexRB(0,to,from);
|
|
||||||
write16( 0xBE0F );
|
|
||||||
ModRM( 0, to, from );
|
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void MOVSX32Rm8toROffset( x86IntRegType to, x86IntRegType from, int offset )
|
|
||||||
{
|
{
|
||||||
RexRB(0,to,from);
|
RexRB(0,to,from);
|
||||||
write16( 0xBE0F );
|
write16( 0xBE0F );
|
||||||
|
@ -562,7 +542,7 @@ emitterT void MOVSX32R16toR( x86IntRegType to, x86IntRegType from )
|
||||||
ModRM( 3, to, from );
|
ModRM( 3, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVSX32Rm16toR( x86IntRegType to, x86IntRegType from, int offset=0 )
|
emitterT void MOVSX32Rm16toR( x86IntRegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0,to,from);
|
RexRB(0,to,from);
|
||||||
write16( 0xBF0F );
|
write16( 0xBF0F );
|
||||||
|
@ -586,7 +566,7 @@ emitterT void MOVZX32R8toR( x86IntRegType to, x86IntRegType from )
|
||||||
ModRM( 3, to, from );
|
ModRM( 3, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVZX32Rm8toR( x86IntRegType to, x86IntRegType from, int offset=0 )
|
emitterT void MOVZX32Rm8toR( x86IntRegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0,to,from);
|
RexRB(0,to,from);
|
||||||
write16( 0xB60F );
|
write16( 0xB60F );
|
||||||
|
@ -610,7 +590,7 @@ emitterT void MOVZX32R16toR( x86IntRegType to, x86IntRegType from )
|
||||||
ModRM( 3, to, from );
|
ModRM( 3, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVZX32Rm16toR( x86IntRegType to, x86IntRegType from, int offset=0 )
|
emitterT void MOVZX32Rm16toR( x86IntRegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0,to,from);
|
RexRB(0,to,from);
|
||||||
write16( 0xB70F );
|
write16( 0xB70F );
|
||||||
|
@ -837,12 +817,12 @@ emitterT void ADD16ItoR( x86IntRegType to, s16 imm )
|
||||||
write8( 0x66 );
|
write8( 0x66 );
|
||||||
RexB(0,to);
|
RexB(0,to);
|
||||||
|
|
||||||
if ( to == EAX)
|
if (to == EAX)
|
||||||
{
|
{
|
||||||
write8( 0x05 );
|
write8( 0x05 );
|
||||||
write16( imm );
|
write16( imm );
|
||||||
}
|
}
|
||||||
else if(imm <= 127 && imm >= -128)
|
else if(is_s8(imm))
|
||||||
{
|
{
|
||||||
write8( 0x83 );
|
write8( 0x83 );
|
||||||
ModRM( 3, 0, to );
|
ModRM( 3, 0, to );
|
||||||
|
@ -860,7 +840,7 @@ emitterT void ADD16ItoR( x86IntRegType to, s16 imm )
|
||||||
emitterT void ADD16ItoM( uptr to, s16 imm )
|
emitterT void ADD16ItoM( uptr to, s16 imm )
|
||||||
{
|
{
|
||||||
write8( 0x66 );
|
write8( 0x66 );
|
||||||
if(imm <= 127 && imm >= -128)
|
if(is_s8(imm))
|
||||||
{
|
{
|
||||||
write8( 0x83 );
|
write8( 0x83 );
|
||||||
ModRM( 0, 0, DISP32 );
|
ModRM( 0, 0, DISP32 );
|
||||||
|
@ -1776,31 +1756,6 @@ emitterT u8* JNO8( u8 to )
|
||||||
{
|
{
|
||||||
return J8Rel( 0x71, to );
|
return J8Rel( 0x71, to );
|
||||||
}
|
}
|
||||||
/* Untested and slower, use 32bit versions instead
|
|
||||||
// ja rel16
|
|
||||||
emitterT u16* eJA16( u16 to )
|
|
||||||
{
|
|
||||||
return J16Rel( 0x87, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
// jb rel16
|
|
||||||
emitterT u16* eJB16( u16 to )
|
|
||||||
{
|
|
||||||
return J16Rel( 0x82, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
// je rel16
|
|
||||||
emitterT u16* eJE16( u16 to )
|
|
||||||
{
|
|
||||||
return J16Rel( 0x84, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
// jz rel16
|
|
||||||
emitterT u16* eJZ16( u16 to )
|
|
||||||
{
|
|
||||||
return J16Rel( 0x84, to );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// jb rel32
|
// jb rel32
|
||||||
emitterT u32* JB32( u32 to )
|
emitterT u32* JB32( u32 to )
|
||||||
{
|
{
|
||||||
|
@ -2271,7 +2226,7 @@ emitterT void LEA32RtoR(x86IntRegType to, x86IntRegType from, s32 offset)
|
||||||
ModRM(1, to, from);
|
ModRM(1, to, from);
|
||||||
write8(0x24);
|
write8(0x24);
|
||||||
}
|
}
|
||||||
else if( offset <= 127 && offset >= -128 ) {
|
else if( is_s8(offset) ) {
|
||||||
ModRM(1, to, from);
|
ModRM(1, to, from);
|
||||||
write8(0x24);
|
write8(0x24);
|
||||||
write8(offset);
|
write8(offset);
|
||||||
|
@ -2286,7 +2241,7 @@ emitterT void LEA32RtoR(x86IntRegType to, x86IntRegType from, s32 offset)
|
||||||
if( offset == 0 && from != EBP && from!=ESP ) {
|
if( offset == 0 && from != EBP && from!=ESP ) {
|
||||||
ModRM(0, to, from);
|
ModRM(0, to, from);
|
||||||
}
|
}
|
||||||
else if( offset <= 127 && offset >= -128 ) {
|
else if( is_s8(offset) ) {
|
||||||
ModRM(1, to, from);
|
ModRM(1, to, from);
|
||||||
write8(offset);
|
write8(offset);
|
||||||
}
|
}
|
||||||
|
@ -2298,7 +2253,7 @@ emitterT void LEA32RtoR(x86IntRegType to, x86IntRegType from, s32 offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// to = from + offset
|
// to = from + offset
|
||||||
emitterT void LEA16RtoR(x86IntRegType to, x86IntRegType from, u16 offset)
|
emitterT void LEA16RtoR(x86IntRegType to, x86IntRegType from, s16 offset)
|
||||||
{
|
{
|
||||||
write8(0x66);
|
write8(0x66);
|
||||||
LEA32RtoR(to, from, offset);
|
LEA32RtoR(to, from, offset);
|
|
@ -16,7 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#include "PrecompiledHeader.h"
|
||||||
|
#include "ix86_internal.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// MMX instructions
|
// MMX instructions
|
||||||
|
@ -482,32 +483,16 @@ emitterT void MOVQRtoR( x86MMXRegType to, x86MMXRegType from )
|
||||||
ModRM( 3, to, from );
|
ModRM( 3, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVQRmtoR( x86MMXRegType to, x86IntRegType from, int offset=0 )
|
emitterT void MOVQRmtoR( x86MMXRegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
write16( 0x6F0F );
|
write16( 0x6F0F );
|
||||||
|
WriteRmOffsetFrom( to, from, offset );
|
||||||
if( offset < 128 && offset >= -128) {
|
|
||||||
ModRM( 1, to, from );
|
|
||||||
write8(offset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ModRM( 2, to, from );
|
|
||||||
write32(offset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVQRtoRm( x86IntRegType to, x86MMXRegType from, int offset=0 )
|
emitterT void MOVQRtoRm( x86IntRegType to, x86MMXRegType from, int offset )
|
||||||
{
|
{
|
||||||
write16( 0x7F0F );
|
write16( 0x7F0F );
|
||||||
|
WriteRmOffsetFrom( from, to, offset );
|
||||||
if( offset < 128 && offset >= -128) {
|
|
||||||
ModRM( 1, from , to );
|
|
||||||
write8(offset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ModRM( 2, from, to );
|
|
||||||
write32(offset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* movd m32 to r64 */
|
/* movd m32 to r64 */
|
||||||
|
@ -532,24 +517,10 @@ emitterT void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from )
|
||||||
ModRM( 3, to, from );
|
ModRM( 3, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from )
|
emitterT void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
write16( 0x6E0F );
|
write16( 0x6E0F );
|
||||||
ModRM( 0, to, from );
|
WriteRmOffsetFrom( to, from, offset );
|
||||||
}
|
|
||||||
|
|
||||||
emitterT void MOVD32RmOffsettoMMX( x86MMXRegType to, x86IntRegType from, u32 offset )
|
|
||||||
{
|
|
||||||
write16( 0x6E0F );
|
|
||||||
|
|
||||||
if( offset < 128 ) {
|
|
||||||
ModRM( 1, to, from );
|
|
||||||
write8(offset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ModRM( 2, to, from );
|
|
||||||
write32(offset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from )
|
emitterT void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from )
|
||||||
|
@ -558,46 +529,12 @@ emitterT void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from )
|
||||||
ModRM( 3, from, to );
|
ModRM( 3, from, to );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from )
|
emitterT void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from, int offset )
|
||||||
{
|
{
|
||||||
write16( 0x7E0F );
|
write16( 0x7E0F );
|
||||||
ModRM( 0, from, to );
|
WriteRmOffsetFrom( from, to, offset );
|
||||||
if( to >= 4 ) {
|
|
||||||
// no idea why
|
|
||||||
assert( to == ESP );
|
|
||||||
write8(0x24);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void MOVD32MMXtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
|
|
||||||
{
|
|
||||||
write16( 0x7E0F );
|
|
||||||
|
|
||||||
if( offset < 128 ) {
|
|
||||||
ModRM( 1, from, to );
|
|
||||||
write8(offset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ModRM( 2, from, to );
|
|
||||||
write32(offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///* movd r32 to r64 */
|
|
||||||
//emitterT void MOVD32MMXtoMMX( x86MMXRegType to, x86MMXRegType from )
|
|
||||||
//{
|
|
||||||
// write16( 0x6E0F );
|
|
||||||
// ModRM( 3, to, from );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
///* movq r64 to r32 */
|
|
||||||
//emitterT void MOVD64MMXtoMMX( x86MMXRegType to, x86MMXRegType from )
|
|
||||||
//{
|
|
||||||
// write16( 0x7E0F );
|
|
||||||
// ModRM( 3, from, to );
|
|
||||||
//}
|
|
||||||
|
|
||||||
// untested
|
// untested
|
||||||
emitterT void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
|
emitterT void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
|
||||||
{
|
{
|
|
@ -16,7 +16,9 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#include "PrecompiledHeader.h"
|
||||||
|
#include "ix86_internal.h"
|
||||||
|
#include "ix86_sse_helpers.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// AlwaysUseMovaps [const]
|
// AlwaysUseMovaps [const]
|
||||||
|
@ -144,7 +146,7 @@ static const bool AlwaysUseMovaps = true;
|
||||||
write8( op )
|
write8( op )
|
||||||
|
|
||||||
/* movups [r32][r32*scale] to xmm1 */
|
/* movups [r32][r32*scale] to xmm1 */
|
||||||
emitterT void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 )
|
emitterT void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
||||||
{
|
{
|
||||||
RexRXB(0, to, from2, from);
|
RexRXB(0, to, from2, from);
|
||||||
write16( 0x100f );
|
write16( 0x100f );
|
||||||
|
@ -153,7 +155,7 @@ emitterT void SSE_MOVUPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegT
|
||||||
}
|
}
|
||||||
|
|
||||||
/* movups xmm1 to [r32][r32*scale] */
|
/* movups xmm1 to [r32][r32*scale] */
|
||||||
emitterT void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 )
|
emitterT void SSE_MOVUPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
||||||
{
|
{
|
||||||
RexRXB(1, to, from2, from);
|
RexRXB(1, to, from2, from);
|
||||||
write16( 0x110f );
|
write16( 0x110f );
|
||||||
|
@ -185,7 +187,7 @@ emitterT void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from )
|
||||||
ModRM( 0, to, from );
|
ModRM( 0, to, from );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE_MOVLPSRmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, to, from);
|
RexRB(0, to, from);
|
||||||
write16( 0x120f );
|
write16( 0x120f );
|
||||||
|
@ -200,7 +202,7 @@ emitterT void SSE_MOVLPSRtoRm( x86IntRegType to, x86IntRegType from )
|
||||||
ModRM( 0, from, to );
|
ModRM( 0, from, to );
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, from, to);
|
RexRB(0, from, to);
|
||||||
write16( 0x130f );
|
write16( 0x130f );
|
||||||
|
@ -208,7 +210,7 @@ emitterT void SSE_MOVLPSRtoRm( x86SSERegType to, x86IntRegType from, int offset=
|
||||||
}
|
}
|
||||||
|
|
||||||
/* movaps [r32][r32*scale] to xmm1 */
|
/* movaps [r32][r32*scale] to xmm1 */
|
||||||
emitterT void SSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 )
|
emitterT void SSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
||||||
{
|
{
|
||||||
assert( from != EBP );
|
assert( from != EBP );
|
||||||
RexRXB(0, to, from2, from);
|
RexRXB(0, to, from2, from);
|
||||||
|
@ -218,7 +220,7 @@ emitterT void SSE_MOVAPSRmStoR( x86SSERegType to, x86IntRegType from, x86IntRegT
|
||||||
}
|
}
|
||||||
|
|
||||||
/* movaps xmm1 to [r32][r32*scale] */
|
/* movaps xmm1 to [r32][r32*scale] */
|
||||||
emitterT void SSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale=0 )
|
emitterT void SSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegType from2, int scale )
|
||||||
{
|
{
|
||||||
assert( from != EBP );
|
assert( from != EBP );
|
||||||
RexRXB(0, to, from2, from);
|
RexRXB(0, to, from2, from);
|
||||||
|
@ -228,7 +230,7 @@ emitterT void SSE_MOVAPSRtoRmS( x86SSERegType to, x86IntRegType from, x86IntRegT
|
||||||
}
|
}
|
||||||
|
|
||||||
// movaps [r32+offset] to r32
|
// movaps [r32+offset] to r32
|
||||||
emitterT void SSE_MOVAPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE_MOVAPSRmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, to, from);
|
RexRB(0, to, from);
|
||||||
write16( 0x280f );
|
write16( 0x280f );
|
||||||
|
@ -236,7 +238,7 @@ emitterT void SSE_MOVAPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=
|
||||||
}
|
}
|
||||||
|
|
||||||
// movaps r32 to [r32+offset]
|
// movaps r32 to [r32+offset]
|
||||||
emitterT void SSE_MOVAPSRtoRm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
emitterT void SSE_MOVAPSRtoRm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, from, to);
|
RexRB(0, from, to);
|
||||||
write16( 0x290f );
|
write16( 0x290f );
|
||||||
|
@ -244,7 +246,7 @@ emitterT void SSE_MOVAPSRtoRm( x86IntRegType to, x86SSERegType from, int offset=
|
||||||
}
|
}
|
||||||
|
|
||||||
// movdqa [r32+offset] to r32
|
// movdqa [r32+offset] to r32
|
||||||
emitterT void SSE2_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE2_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
if( AlwaysUseMovaps )
|
if( AlwaysUseMovaps )
|
||||||
SSE_MOVAPSRmtoR( to, from, offset );
|
SSE_MOVAPSRmtoR( to, from, offset );
|
||||||
|
@ -258,7 +260,7 @@ emitterT void SSE2_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset
|
||||||
}
|
}
|
||||||
|
|
||||||
// movdqa r32 to [r32+offset]
|
// movdqa r32 to [r32+offset]
|
||||||
emitterT void SSE2_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
emitterT void SSE2_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
{
|
{
|
||||||
if( AlwaysUseMovaps )
|
if( AlwaysUseMovaps )
|
||||||
SSE_MOVAPSRtoRm( to, from, offset );
|
SSE_MOVAPSRtoRm( to, from, offset );
|
||||||
|
@ -272,7 +274,7 @@ emitterT void SSE2_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset
|
||||||
}
|
}
|
||||||
|
|
||||||
// movups [r32+offset] to r32
|
// movups [r32+offset] to r32
|
||||||
emitterT void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, to, from);
|
RexRB(0, to, from);
|
||||||
write16( 0x100f );
|
write16( 0x100f );
|
||||||
|
@ -280,7 +282,7 @@ emitterT void SSE_MOVUPSRmtoR( x86SSERegType to, x86IntRegType from, int offset=
|
||||||
}
|
}
|
||||||
|
|
||||||
// movups r32 to [r32+offset]
|
// movups r32 to [r32+offset]
|
||||||
emitterT void SSE_MOVUPSRtoRm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
emitterT void SSE_MOVUPSRtoRm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, from, to);
|
RexRB(0, from, to);
|
||||||
write16( 0x110f );
|
write16( 0x110f );
|
||||||
|
@ -335,7 +337,7 @@ emitterT void SSE_MOVSS_XMM_to_M32( u32 to, x86SSERegType from ) { SSE_SS_RtoM
|
||||||
|
|
||||||
emitterT void SSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { if (to != from) { SSE_SS_RtoR( 0x100f ); } }
|
emitterT void SSE_MOVSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { if (to != from) { SSE_SS_RtoR( 0x100f ); } }
|
||||||
|
|
||||||
emitterT void SSE_MOVSS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE_MOVSS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
write8(0xf3);
|
write8(0xf3);
|
||||||
RexRB(0, to, from);
|
RexRB(0, to, from);
|
||||||
|
@ -343,7 +345,7 @@ emitterT void SSE_MOVSS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int off
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
WriteRmOffsetFrom(to, from, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void SSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
emitterT void SSE_MOVSS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
{
|
{
|
||||||
write8(0xf3);
|
write8(0xf3);
|
||||||
RexRB(0, from, to);
|
RexRB(0, from, to);
|
||||||
|
@ -358,14 +360,14 @@ emitterT void SSE_MASKMOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
||||||
emitterT void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x120f, 0 ); }
|
emitterT void SSE_MOVLPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x120f, 0 ); }
|
||||||
emitterT void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x130f, 0 ); }
|
emitterT void SSE_MOVLPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x130f, 0 ); }
|
||||||
|
|
||||||
emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE_MOVLPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, to, from);
|
RexRB(0, to, from);
|
||||||
write16( 0x120f );
|
write16( 0x120f );
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
WriteRmOffsetFrom(to, from, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, from, to);
|
RexRB(0, from, to);
|
||||||
write16(0x130f);
|
write16(0x130f);
|
||||||
|
@ -379,14 +381,14 @@ emitterT void SSE_MOVLPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int of
|
||||||
emitterT void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x160f, 0 ); }
|
emitterT void SSE_MOVHPS_M64_to_XMM( x86SSERegType to, uptr from ) { SSEMtoR( 0x160f, 0 ); }
|
||||||
emitterT void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x170f, 0 ); }
|
emitterT void SSE_MOVHPS_XMM_to_M64( u32 to, x86SSERegType from ) { SSERtoM( 0x170f, 0 ); }
|
||||||
|
|
||||||
emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE_MOVHPS_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, to, from);
|
RexRB(0, to, from);
|
||||||
write16( 0x160f );
|
write16( 0x160f );
|
||||||
WriteRmOffsetFrom(to, from, offset);
|
WriteRmOffsetFrom(to, from, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
emitterT void SSE_MOVHPS_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
{
|
{
|
||||||
RexRB(0, from, to);
|
RexRB(0, from, to);
|
||||||
write16(0x170f);
|
write16(0x170f);
|
||||||
|
@ -900,7 +902,7 @@ emitterT void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from )
|
||||||
ModRM( 0, to, from);
|
ModRM( 0, to, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitterT void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset=0 )
|
emitterT void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
{
|
{
|
||||||
write8(0x66);
|
write8(0x66);
|
||||||
RexRB(0, to, from);
|
RexRB(0, to, from);
|
||||||
|
@ -911,7 +913,7 @@ emitterT void SSE2_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int off
|
||||||
emitterT void SSE2_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) { SSERtoM66(0x7E0F); }
|
emitterT void SSE2_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) { SSERtoM66(0x7E0F); }
|
||||||
emitterT void SSE2_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) { _SSERtoR66(0x7E0F); }
|
emitterT void SSE2_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) { _SSERtoR66(0x7E0F); }
|
||||||
|
|
||||||
emitterT void SSE2_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
emitterT void SSE2_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
{
|
{
|
||||||
write8(0x66);
|
write8(0x66);
|
||||||
RexRB(0, from, to);
|
RexRB(0, from, to);
|
||||||
|
@ -1400,3 +1402,160 @@ emitterT void SSE4_PMULDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
|
||||||
write24(0x28380F);
|
write24(0x28380F);
|
||||||
ModRM(3, to, from);
|
ModRM(3, to, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// SSE-X Helpers (generates either INT or FLOAT versions of certain SSE instructions)
|
||||||
|
// This header should always be included *after* ix86.h.
|
||||||
|
|
||||||
|
// Added AlwaysUseMovaps check to the relevant functions here, which helps reduce the
|
||||||
|
// overhead of dynarec instructions that use these, even thought the same check would
|
||||||
|
// have been done redundantly by the emitter function.
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from )
|
||||||
|
{
|
||||||
|
if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQA_M128_to_XMM(to, from);
|
||||||
|
else SSE_MOVAPS_M128_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_M128(to, from);
|
||||||
|
else SSE_MOVAPS_XMM_to_M128(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_XMM(to, from);
|
||||||
|
else SSE_MOVAPS_XMM_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
|
{
|
||||||
|
if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQARmtoR(to, from, offset);
|
||||||
|
else SSE_MOVAPSRmtoR(to, from, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
|
{
|
||||||
|
if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQARtoRm(to, from, offset);
|
||||||
|
else SSE_MOVAPSRtoRm(to, from, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from )
|
||||||
|
{
|
||||||
|
if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQU_M128_to_XMM(to, from);
|
||||||
|
else SSE_MOVUPS_M128_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQU_XMM_to_M128(to, from);
|
||||||
|
else SSE_MOVUPS_XMM_to_M128(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_M32_to_XMM(to, from);
|
||||||
|
else SSE_MOVSS_M32_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_M32(to, from);
|
||||||
|
else SSE_MOVSS_XMM_to_M32(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_Rm_to_XMM(to, from, offset);
|
||||||
|
else SSE_MOVSS_Rm_to_XMM(to, from, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_Rm(to, from, offset);
|
||||||
|
else SSE_MOVSS_XMM_to_Rm(to, from, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[to] == XMMT_INT ) SSE2_POR_M128_to_XMM(to, from);
|
||||||
|
else SSE_ORPS_M128_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) SSE2_POR_XMM_to_XMM(to, from);
|
||||||
|
else SSE_ORPS_XMM_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PXOR_M128_to_XMM(to, from);
|
||||||
|
else SSE_XORPS_M128_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PXOR_XMM_to_XMM(to, from);
|
||||||
|
else SSE_XORPS_XMM_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PAND_M128_to_XMM(to, from);
|
||||||
|
else SSE_ANDPS_M128_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PAND_XMM_to_XMM(to, from);
|
||||||
|
else SSE_ANDPS_XMM_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PANDN_M128_to_XMM(to, from);
|
||||||
|
else SSE_ANDNPS_M128_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PANDN_XMM_to_XMM(to, from);
|
||||||
|
else SSE_ANDNPS_XMM_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from)
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKLDQ_M128_to_XMM(to, from);
|
||||||
|
else SSE_UNPCKLPS_M128_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKLDQ_XMM_to_XMM(to, from);
|
||||||
|
else SSE_UNPCKLPS_XMM_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from)
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKHDQ_M128_to_XMM(to, from);
|
||||||
|
else SSE_UNPCKHPS_M128_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKHDQ_XMM_to_XMM(to, from);
|
||||||
|
else SSE_UNPCKHPS_XMM_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitterT void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
||||||
|
{
|
||||||
|
if( g_xmmtypes[from] == XMMT_INT ) {
|
||||||
|
SSE2_PUNPCKHQDQ_XMM_to_XMM(to, from);
|
||||||
|
if( to != from ) SSE2_PSHUFD_XMM_to_XMM(to, to, 0x4e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SSE_MOVHLPS_XMM_to_XMM(to, from);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,158 +22,30 @@
|
||||||
// SSE-X Helpers (generates either INT or FLOAT versions of certain SSE instructions)
|
// SSE-X Helpers (generates either INT or FLOAT versions of certain SSE instructions)
|
||||||
// This header should always be included *after* ix86.h.
|
// This header should always be included *after* ix86.h.
|
||||||
|
|
||||||
#ifndef _ix86_included_
|
|
||||||
#error Dependency fail: Please define _EmitterId_ and include ix86.h first.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Added AlwaysUseMovaps check to the relevant functions here, which helps reduce the
|
// Added AlwaysUseMovaps check to the relevant functions here, which helps reduce the
|
||||||
// overhead of dynarec instructions that use these.
|
// overhead of dynarec instructions that use these.
|
||||||
|
|
||||||
static __forceinline void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from )
|
extern void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from );
|
||||||
{
|
extern void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from );
|
||||||
if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQA_M128_to_XMM(to, from);
|
extern void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
||||||
else SSE_MOVAPS_M128_to_XMM(to, from);
|
extern void SSEX_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset=0 );
|
||||||
}
|
extern void SSEX_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset=0 );
|
||||||
|
extern void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from );
|
||||||
static __forceinline void SSEX_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from )
|
extern void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from );
|
||||||
{
|
extern void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from );
|
||||||
if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_M128(to, from);
|
extern void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from );
|
||||||
else SSE_MOVAPS_XMM_to_M128(to, from);
|
extern void SSEX_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset=0 );
|
||||||
}
|
extern void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset=0 );
|
||||||
|
extern void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from );
|
||||||
static __forceinline void SSEX_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
extern void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
||||||
{
|
extern void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from );
|
||||||
if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQA_XMM_to_XMM(to, from);
|
extern void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
||||||
else SSE_MOVAPS_XMM_to_XMM(to, from);
|
extern void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from );
|
||||||
}
|
extern void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
||||||
|
extern void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from );
|
||||||
static __forceinline void SSEX_MOVDQARmtoR( x86SSERegType to, x86IntRegType from, int offset=0 )
|
extern void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
||||||
{
|
extern void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from );
|
||||||
if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQARmtoR(to, from, offset);
|
extern void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
|
||||||
else SSE_MOVAPSRmtoR(to, from, offset);
|
extern void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from );
|
||||||
}
|
extern void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from );
|
||||||
|
extern void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
|
||||||
static __forceinline void SSEX_MOVDQARtoRm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
|
||||||
{
|
|
||||||
if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQARtoRm(to, from, offset);
|
|
||||||
else SSE_MOVAPSRtoRm(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_MOVDQU_M128_to_XMM( x86SSERegType to, uptr from )
|
|
||||||
{
|
|
||||||
if( !AlwaysUseMovaps && g_xmmtypes[to] == XMMT_INT ) SSE2_MOVDQU_M128_to_XMM(to, from);
|
|
||||||
else SSE_MOVUPS_M128_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from )
|
|
||||||
{
|
|
||||||
if( !AlwaysUseMovaps && g_xmmtypes[from] == XMMT_INT ) SSE2_MOVDQU_XMM_to_M128(to, from);
|
|
||||||
else SSE_MOVUPS_XMM_to_M128(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_MOVD_M32_to_XMM( x86SSERegType to, uptr from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_M32_to_XMM(to, from);
|
|
||||||
else SSE_MOVSS_M32_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_MOVD_XMM_to_M32( u32 to, x86SSERegType from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_M32(to, from);
|
|
||||||
else SSE_MOVSS_XMM_to_M32(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_MOVD_Rm_to_XMM( x86SSERegType to, x86IntRegType from, int offset=0 )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[to] == XMMT_INT ) SSE2_MOVD_Rm_to_XMM(to, from, offset);
|
|
||||||
else SSE_MOVSS_Rm_to_XMM(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_MOVD_XMM_to_Rm( x86IntRegType to, x86SSERegType from, int offset=0 )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) SSE2_MOVD_XMM_to_Rm(to, from, offset);
|
|
||||||
else SSE_MOVSS_XMM_to_Rm(to, from, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_POR_M128_to_XMM( x86SSERegType to, uptr from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[to] == XMMT_INT ) SSE2_POR_M128_to_XMM(to, from);
|
|
||||||
else SSE_ORPS_M128_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_POR_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) SSE2_POR_XMM_to_XMM(to, from);
|
|
||||||
else SSE_ORPS_XMM_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PXOR_M128_to_XMM( x86SSERegType to, uptr from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PXOR_M128_to_XMM(to, from);
|
|
||||||
else SSE_XORPS_M128_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PXOR_XMM_to_XMM(to, from);
|
|
||||||
else SSE_XORPS_XMM_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PAND_M128_to_XMM( x86SSERegType to, uptr from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PAND_M128_to_XMM(to, from);
|
|
||||||
else SSE_ANDPS_M128_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PAND_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PAND_XMM_to_XMM(to, from);
|
|
||||||
else SSE_ANDPS_XMM_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PANDN_M128_to_XMM( x86SSERegType to, uptr from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PANDN_M128_to_XMM(to, from);
|
|
||||||
else SSE_ANDNPS_M128_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PANDN_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PANDN_XMM_to_XMM(to, from);
|
|
||||||
else SSE_ANDNPS_XMM_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PUNPCKLDQ_M128_to_XMM(x86SSERegType to, uptr from)
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKLDQ_M128_to_XMM(to, from);
|
|
||||||
else SSE_UNPCKLPS_M128_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PUNPCKLDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKLDQ_XMM_to_XMM(to, from);
|
|
||||||
else SSE_UNPCKLPS_XMM_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PUNPCKHDQ_M128_to_XMM(x86SSERegType to, uptr from)
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[to] == XMMT_INT ) SSE2_PUNPCKHDQ_M128_to_XMM(to, from);
|
|
||||||
else SSE_UNPCKHPS_M128_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_PUNPCKHDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) SSE2_PUNPCKHDQ_XMM_to_XMM(to, from);
|
|
||||||
else SSE_UNPCKHPS_XMM_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __forceinline void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
|
|
||||||
{
|
|
||||||
if( g_xmmtypes[from] == XMMT_INT ) {
|
|
||||||
SSE2_PUNPCKHQDQ_XMM_to_XMM(to, from);
|
|
||||||
if( to != from ) SSE2_PSHUFD_XMM_to_XMM(to, to, 0x4e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SSE_MOVHLPS_XMM_to_XMM(to, from);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
#include "Misc.h"
|
#include "System.h"
|
||||||
#include "ix86/ix86.h"
|
#include "ix86/ix86.h"
|
||||||
|
|
||||||
// used to make sure regs don't get changed while in recompiler
|
// used to make sure regs don't get changed while in recompiler
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#define mVUdebug // Prints Extra Info to Console
|
#define mVUdebug // Prints Extra Info to Console
|
||||||
#define _EmitterId_ (vuIndex+1)
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "VU.h"
|
#include "VU.h"
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
|
|
Loading…
Reference in New Issue