diff --git a/.gitignore b/.gitignore index c6680231f..5d49ecb85 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ src/CMakeCache.txt src/cmake_install.cmake src/Makefile src/lib* +src/Build/* \ No newline at end of file diff --git a/addons/source-python/packages/source-python/_core/commands.py b/addons/source-python/packages/source-python/_core/commands.py index 81154e2cf..1f2d7f7f5 100644 --- a/addons/source-python/packages/source-python/_core/commands.py +++ b/addons/source-python/packages/source-python/_core/commands.py @@ -26,6 +26,8 @@ from tick.delays import TickDelays # Translations from translations.strings import LangStrings +# Paths +from paths import SP_DATA_PATH # ============================================================================= @@ -341,7 +343,7 @@ def _print_credits(): # Get the credits information groups = ConfigObj( - DATA_PATH.joinpath('credits.ini'), encoding='unicode_escape') + SP_DATA_PATH.joinpath('credits.ini'), encoding='unicode_escape') # Loop through all groups in the credits for group in groups: diff --git a/addons/source-python/packages/source-python/dyncall/dictionary.py b/addons/source-python/packages/source-python/dyncall/dictionary.py index db66db8ca..401e74a3a 100644 --- a/addons/source-python/packages/source-python/dyncall/dictionary.py +++ b/addons/source-python/packages/source-python/dyncall/dictionary.py @@ -9,7 +9,7 @@ # Source.Python Imports from core import GAME_NAME -from paths import DATA_PATH +from paths import SP_DATA_PATH # DynCall from dyncall.signature import Signature @@ -18,7 +18,7 @@ # >> GLOBAL VARIABLES # ============================================================================= # Store the game's ini file's path -_inipath = DATA_PATH.joinpath('dyncall', GAME_NAME) +_inipath = SP_DATA_PATH.joinpath('dyncall', GAME_NAME) # ============================================================================= diff --git a/addons/source-python/packages/source-python/entities/constants.py b/addons/source-python/packages/source-python/entities/constants.py index ba0fddc31..2f395a9f0 100644 --- a/addons/source-python/packages/source-python/entities/constants.py +++ b/addons/source-python/packages/source-python/entities/constants.py @@ -9,7 +9,7 @@ # Source.Python Imports from core import GAME_NAME -from paths import DATA_PATH +from paths import SP_DATA_PATH from public import public @@ -17,7 +17,7 @@ # >> GLOBAL VARIABLES # ============================================================================= _entity_values = ConfigObj( - DATA_PATH.joinpath('entities', GAME_NAME + '.ini'), unrepr=True) + SP_DATA_PATH.joinpath('entities', GAME_NAME + '.ini'), unrepr=True) # ============================================================================= diff --git a/addons/source-python/packages/source-python/entities/functions.py b/addons/source-python/packages/source-python/entities/functions.py index f509aab1a..dcba72bff 100644 --- a/addons/source-python/packages/source-python/entities/functions.py +++ b/addons/source-python/packages/source-python/entities/functions.py @@ -9,7 +9,7 @@ # Source.Python Imports from core import GAME_NAME -from paths import DATA_PATH +from paths import SP_DATA_PATH # DynCall from dyncall.dictionary import SignatureDictionary @@ -25,7 +25,7 @@ # >> GLOBAL VARIABLES # ============================================================================= # Store the base "functions" path -_basepath = DATA_PATH.joinpath('functions') +_basepath = SP_DATA_PATH.joinpath('functions') # ============================================================================= diff --git a/addons/source-python/packages/source-python/entities/keyvalues.py b/addons/source-python/packages/source-python/entities/keyvalues.py index 6df7e4955..c6b3a8196 100644 --- a/addons/source-python/packages/source-python/entities/keyvalues.py +++ b/addons/source-python/packages/source-python/entities/keyvalues.py @@ -9,7 +9,7 @@ # Source.Python Imports from core import GAME_NAME -from paths import DATA_PATH +from paths import SP_DATA_PATH # ============================================================================= @@ -23,7 +23,7 @@ # >> GLOBAL VARIABLES # ============================================================================= # Store the base "keyvalues" path -_basepath = DATA_PATH.joinpath('keyvalues') +_basepath = SP_DATA_PATH.joinpath('keyvalues') # ============================================================================= diff --git a/addons/source-python/packages/source-python/entities/offsets.py b/addons/source-python/packages/source-python/entities/offsets.py index a56ee25ec..2ce2849f9 100644 --- a/addons/source-python/packages/source-python/entities/offsets.py +++ b/addons/source-python/packages/source-python/entities/offsets.py @@ -13,7 +13,7 @@ # Source.Python Imports from core import GAME_NAME -from paths import DATA_PATH +from paths import SP_DATA_PATH # ============================================================================= @@ -27,7 +27,7 @@ # >> GLOBAL VARIABLES # ============================================================================= # Store the base "offsets" path -_basepath = DATA_PATH.joinpath('offsets') +_basepath = SP_DATA_PATH.joinpath('offsets') # ============================================================================= diff --git a/addons/source-python/packages/source-python/entities/properties.py b/addons/source-python/packages/source-python/entities/properties.py index 83b1dee4c..33a029af7 100644 --- a/addons/source-python/packages/source-python/entities/properties.py +++ b/addons/source-python/packages/source-python/entities/properties.py @@ -9,7 +9,7 @@ # Source.Python Imports from core import GAME_NAME -from paths import DATA_PATH +from paths import SP_DATA_PATH # ============================================================================= @@ -23,7 +23,7 @@ # >> GLOBAL VARIABLES # ============================================================================= # Store the base "properties" path -_basepath = DATA_PATH.joinpath('properties') +_basepath = SP_DATA_PATH.joinpath('properties') # ============================================================================= diff --git a/addons/source-python/packages/source-python/filters/players.py b/addons/source-python/packages/source-python/filters/players.py index fe3289b29..7dd8e021d 100644 --- a/addons/source-python/packages/source-python/filters/players.py +++ b/addons/source-python/packages/source-python/filters/players.py @@ -11,7 +11,7 @@ from player_c import CPlayerGenerator from core import GameEngine from core import GAME_NAME -from paths import DATA_PATH +from paths import SP_DATA_PATH from public import public # Filters from filters.iterator import _IterObject @@ -33,7 +33,7 @@ # ============================================================================= # Get the team's file for the current game _game_teams = ConfigObj( - DATA_PATH.joinpath('players', 'teams', GAME_NAME + '.ini'), unrepr=True) + SP_DATA_PATH.joinpath('players', 'teams', GAME_NAME + '.ini'), unrepr=True) # ============================================================================= diff --git a/addons/source-python/packages/source-python/messages/__init__.py b/addons/source-python/packages/source-python/messages/__init__.py index 2f4f182fa..1d2ee09c2 100644 --- a/addons/source-python/packages/source-python/messages/__init__.py +++ b/addons/source-python/packages/source-python/messages/__init__.py @@ -6,7 +6,7 @@ # Source.Python Imports from core import GAME_NAME from loggers import _SPLogger -from paths import DATA_PATH +from paths import SP_DATA_PATH # Messages from messages.base import _UserMessages @@ -22,8 +22,8 @@ # >> INITIALIZATION # ============================================================================ # Loop trough all message classes -for message_name, message_class in _UserMessages(DATA_PATH.joinpath( - 'messages', 'usermessages.ini'), DATA_PATH.joinpath('messages', +for message_name, message_class in _UserMessages(SP_DATA_PATH.joinpath( + 'messages', 'usermessages.ini'), SP_DATA_PATH.joinpath('messages', 'games', GAME_NAME + '.ini')).items(): # Globalize the current message class diff --git a/addons/source-python/packages/source-python/weapons/manager.py b/addons/source-python/packages/source-python/weapons/manager.py index eafc06b8d..95648d844 100644 --- a/addons/source-python/packages/source-python/weapons/manager.py +++ b/addons/source-python/packages/source-python/weapons/manager.py @@ -10,7 +10,7 @@ # Source.Python Imports from core import GAME_NAME from cvars import ServerVar -from paths import DATA_PATH +from paths import SP_DATA_PATH from public import public # Weapons from weapons.default import NoWeaponManager @@ -20,7 +20,7 @@ # >> GLOBAL VARIABLES # ============================================================================= # Get the game's ini path -_gamepath = DATA_PATH.joinpath('weapons', GAME_NAME + '.ini') +_gamepath = SP_DATA_PATH.joinpath('weapons', GAME_NAME + '.ini') # ============================================================================= diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 615135693..80915372d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -403,6 +403,12 @@ Add_Library(source-python SHARED ${SOURCEPYTHON_LOADER_FILES} ) +# ------------------------------------------------------------------ +# Remove prefixes for core and source-python +# ------------------------------------------------------------------ +Set_Target_Properties(core PROPERTIES PREFIX "") +Set_Target_Properties(source-python PROPERTIES PREFIX "") + # ------------------------------------------------------------------ # Include the base makefile. # ------------------------------------------------------------------ diff --git a/src/configure-csgo-debug.sh b/src/configure-csgo-debug.sh old mode 100644 new mode 100755 index 721a76827..2d0b7af39 --- a/src/configure-csgo-debug.sh +++ b/src/configure-csgo-debug.sh @@ -1 +1,3 @@ -cmake -DGAME=csgo -DCMAKE_BUILD_TYPE=Debug \ No newline at end of file +mkdir Build +cd Build +cmake .. -DGAME=csgo -DCMAKE_BUILD_TYPE=Debug diff --git a/src/configure-csgo-release.sh b/src/configure-csgo-release.sh old mode 100644 new mode 100755 index 5bfacd395..aec1daa9a --- a/src/configure-csgo-release.sh +++ b/src/configure-csgo-release.sh @@ -1 +1,3 @@ -cmake -DGAME=csgo \ No newline at end of file +mkdir Build +cd Build +cmake .. -DGAME=csgo diff --git a/src/configure-csgo.bat b/src/configure-csgo.bat index b98a6c12a..e9a76d7c0 100644 --- a/src/configure-csgo.bat +++ b/src/configure-csgo.bat @@ -1,2 +1,4 @@ -cmake -G"Visual Studio 10" -DGAME=csgo +mkdir Build +cd Build +cmake .. -G"Visual Studio 10" -DGAME=csgo pause \ No newline at end of file diff --git a/src/configure-ob-debug.sh b/src/configure-ob-debug.sh old mode 100644 new mode 100755 index 4a17d881a..56ebde936 --- a/src/configure-ob-debug.sh +++ b/src/configure-ob-debug.sh @@ -1 +1,3 @@ -cmake -DGAME=ob-valve -DCMAKE_BUILD_TYPE=Debug \ No newline at end of file +mkdir Build +cd Build +cmake .. -DGAME=ob-valve -DCMAKE_BUILD_TYPE=Debug diff --git a/src/configure-ob-release.sh b/src/configure-ob-release.sh old mode 100644 new mode 100755 index 09a504fe1..3e29bac3e --- a/src/configure-ob-release.sh +++ b/src/configure-ob-release.sh @@ -1 +1,3 @@ -cmake -DGAME=ob-valve \ No newline at end of file +mkdir Build +cd Build +cmake .. -DGAME=ob-valve diff --git a/src/configure-ob.bat b/src/configure-ob.bat index c91a55b8c..80478c938 100644 --- a/src/configure-ob.bat +++ b/src/configure-ob.bat @@ -1,3 +1,4 @@ -cmake -G"Visual Studio 10" -DGAME=ob-valve - +mkdir Build +cd Build +cmake .. -G"Visual Studio 10" -DGAME=ob-valve pause \ No newline at end of file diff --git a/src/core/core/sp_main.cpp b/src/core/core/sp_main.cpp index 4092b28ac..2de5a2eff 100644 --- a/src/core/core/sp_main.cpp +++ b/src/core/core/sp_main.cpp @@ -52,6 +52,9 @@ #include "edict.h" #include "convar.h" +#include "DynamicHooks.h" +extern DynamicHooks::CHookManager* g_pHookMngr; + //--------------------------------------------------------------------------------- // Disable warnings. //--------------------------------------------------------------------------------- @@ -241,6 +244,8 @@ void CSourcePython::Unload( void ) DisconnectTier2Libraries( ); DisconnectTier1Libraries( ); #endif + + g_pHookMngr->UnhookAllFunctions(); } //--------------------------------------------------------------------------------- diff --git a/src/core/modules/memory/memory_hooks.cpp b/src/core/modules/memory/memory_hooks.cpp index d8cdabbc8..7c0228706 100644 --- a/src/core/modules/memory/memory_hooks.cpp +++ b/src/core/modules/memory/memory_hooks.cpp @@ -1,13 +1,6 @@ // ============================================================================ // >> INCLUDES // ============================================================================ -#include "conv_interface.h" -#include "detour_class.h" -#include "func_class.h" -#include "func_stack.h" -#include "func_types.h" -#include "register_class.h" - #include "memory_hooks.h" #include "memory_tools.h" #include "utility/wrap_macros.h" @@ -19,193 +12,134 @@ using namespace boost::python; // ============================================================================ -// >> Helper functions to read, set and convert addresses +// >> GLOBAL VARIABLES +// ============================================================================ +// g_mapCallbacks[][] -> [, , ...] +std::map > > g_mapCallbacks; + + +// ============================================================================ +// >> HELPER FUNCTIONS // ============================================================================ template -object ReadAddr(void* pAddr) +void SetReturnValue(CHook* pHook, object value) { - return object(*(T *) pAddr); + T val = extract(value); + pHook->SetReturnValue(val); } template -void SetAddr(void* pAddr, object value) +object GetReturnValue(CHook* pHook) { - *(T *) pAddr = extract(value); + return object(pHook->GetReturnValue()); } -// ============================================================================ -// >> CCallbackManager -// ============================================================================ -void CCallbackManager::Add(void* pFunc, eHookType type) +template +void SetArgument(CHook* pHook, int iIndex, object value) { - if (!pFunc) - return; - - PyObject* callable = (PyObject *) pFunc; - switch (type) - { - case TYPE_PRE: m_PreCalls.push_front(callable); break; - case TYPE_POST: m_PostCalls.push_front(callable); break; - } + T val = extract(value); + pHook->SetArgument(iIndex, val); } -void CCallbackManager::Remove(void* pFunc, eHookType type) +template +object GetArgument(CHook* pHook, int iIndex) { - if (!pFunc) - return; - - PyObject* callable = (PyObject *) pFunc; - switch (type) - { - case TYPE_PRE: m_PreCalls.remove(callable); break; - case TYPE_POST: m_PostCalls.remove(callable); break; - } + return object(pHook->GetArgument(iIndex)); } -HookRetBuf_t* CCallbackManager::DoPreCalls(CDetour* pDetour) -{ - if (!pDetour) - return NULL; - HookRetBuf_t* buffer = new HookRetBuf_t; - buffer->eRes = HOOKRES_NONE; - buffer->pRetBuf = NULL; - - CStackData stackdata = CStackData(pDetour); - void* pRetReg = pDetour->GetAsmBridge()->GetConv()->GetRegisters()->r_retreg; - for (std::list::iterator iter=m_PreCalls.begin(); iter != m_PreCalls.end(); iter++) - { - BEGIN_BOOST_PY() - - object retval = CALL_PY_FUNC(*iter, stackdata); - if (!retval.is_none()) - { - buffer->eRes = HOOKRES_OVERRIDE; - switch(pDetour->GetFuncObj()->GetRetType()->GetType()) - { - case TYPE_BOOL: SetAddr(pRetReg, retval); break; - case TYPE_CHAR: SetAddr(pRetReg, retval); break; - case TYPE_UCHAR: SetAddr(pRetReg, retval); break; - case TYPE_SHORT: SetAddr(pRetReg, retval); break; - case TYPE_USHORT: SetAddr(pRetReg, retval); break; - case TYPE_INT: SetAddr(pRetReg, retval); break; - case TYPE_UINT: SetAddr(pRetReg, retval); break; - case TYPE_LONG: SetAddr(pRetReg, retval); break; - case TYPE_ULONG: SetAddr(pRetReg, retval); break; - case TYPE_LONGLONG: SetAddr(pRetReg, retval); break; - case TYPE_ULONGLONG: SetAddr(pRetReg, retval); break; - case TYPE_FLOAT: SetAddr(pRetReg, retval); break; - case TYPE_DOUBLE: SetAddr(pRetReg, retval); break; - case TYPE_POINTER: - { - unsigned long retptr = ExtractPyPtr(retval); - memcpy(pRetReg, &retptr, sizeof(unsigned long)); - } break; - case TYPE_STRING: SetAddr(pRetReg, retval); break; - default: BOOST_RAISE_EXCEPTION(PyExc_TypeError, "Unknown type.") - } - } - - END_BOOST_PY_NORET() - } - return buffer; -} - -HookRetBuf_t* CCallbackManager::DoPostCalls(CDetour* pDetour) +// ============================================================================ +// >> SP_HookHandler +// ============================================================================ +bool SP_HookHandler(DynamicHooks::HookType_t eHookType, CHook* pHook) { - if (!pDetour) - return NULL; - - HookRetBuf_t* buffer = new HookRetBuf_t; - buffer->eRes = HOOKRES_NONE; - buffer->pRetBuf = NULL; + std::list callbacks = g_mapCallbacks[pHook][eHookType]; - CStackData stackdata = CStackData(pDetour); + // No need to do all this stuff, if there is no callback registered + if (callbacks.empty()) + return false; - void* pRetReg = pDetour->GetAsmBridge()->GetConv()->GetRegisters()->r_retreg; object retval; - switch(pDetour->GetFuncObj()->GetRetType()->GetType()) + if (eHookType == HOOKTYPE_POST) { - case TYPE_VOID: retval = object(); break; - case TYPE_BOOL: retval = ReadAddr(pRetReg); break; - case TYPE_CHAR: retval = ReadAddr(pRetReg); break; - case TYPE_UCHAR: retval = ReadAddr(pRetReg); break; - case TYPE_SHORT: retval = ReadAddr(pRetReg); break; - case TYPE_USHORT: retval = ReadAddr(pRetReg); break; - case TYPE_INT: retval = ReadAddr(pRetReg); break; - case TYPE_UINT: retval = ReadAddr(pRetReg); break; - case TYPE_LONG: retval = ReadAddr(pRetReg); break; - case TYPE_ULONG: retval = ReadAddr(pRetReg); break; - case TYPE_LONGLONG: retval = ReadAddr(pRetReg); break; - case TYPE_ULONGLONG: retval = ReadAddr(pRetReg); break; - case TYPE_FLOAT: retval = ReadAddr(pRetReg); break; - case TYPE_DOUBLE: retval = ReadAddr(pRetReg); break; - case TYPE_POINTER: retval = object(CPointer(*(unsigned long *) pRetReg)); break; - case TYPE_STRING: retval = ReadAddr(pRetReg); break; - default: BOOST_RAISE_EXCEPTION(PyExc_TypeError, "Unknown type."); + switch(pHook->m_pRetParam->m_cParam) + { + case SIGCHAR_VOID: retval = object(); break; + case SIGCHAR_BOOL: retval = GetReturnValue(pHook); break; + case SIGCHAR_CHAR: retval = GetReturnValue(pHook); break; + case SIGCHAR_UCHAR: retval = GetReturnValue(pHook); break; + case SIGCHAR_SHORT: retval = GetReturnValue(pHook); break; + case SIGCHAR_USHORT: retval = GetReturnValue(pHook); break; + case SIGCHAR_INT: retval = GetReturnValue(pHook); break; + case SIGCHAR_UINT: retval = GetReturnValue(pHook); break; + case SIGCHAR_LONG: retval = GetReturnValue(pHook); break; + case SIGCHAR_ULONG: retval = GetReturnValue(pHook); break; + case SIGCHAR_LONGLONG: retval = GetReturnValue(pHook); break; + case SIGCHAR_ULONGLONG: retval = GetReturnValue(pHook); break; + case SIGCHAR_FLOAT: retval = GetReturnValue(pHook); break; + case SIGCHAR_DOUBLE: retval = GetReturnValue(pHook); break; + case SIGCHAR_POINTER: retval = object(CPointer(pHook->GetReturnValue())); break; + case SIGCHAR_STRING: retval = GetReturnValue(pHook); break; + default: BOOST_RAISE_EXCEPTION(PyExc_TypeError, "Unknown type."); + } } - for (std::list::iterator iter=m_PostCalls.begin(); iter != m_PostCalls.end(); iter++) + CStackData stackdata = CStackData(pHook); + bool bOverride = false; + for (std::list::iterator it=callbacks.begin(); it != callbacks.end(); it++) { BEGIN_BOOST_PY() + object pyretval; + if (eHookType == HOOKTYPE_PRE) + pyretval = CALL_PY_FUNC(*it, stackdata); + else + pyretval = CALL_PY_FUNC(*it, stackdata, retval); - object pyretval = CALL_PY_FUNC(*iter, stackdata, retval); - if (!pyretval.is_none()) - { - buffer->eRes = HOOKRES_OVERRIDE; - switch(pDetour->GetFuncObj()->GetRetType()->GetType()) + if (!pyretval.is_none()) { - case TYPE_BOOL: SetAddr(pRetReg, pyretval); break; - case TYPE_CHAR: SetAddr(pRetReg, pyretval); break; - case TYPE_UCHAR: SetAddr(pRetReg, pyretval); break; - case TYPE_SHORT: SetAddr(pRetReg, pyretval); break; - case TYPE_USHORT: SetAddr(pRetReg, pyretval); break; - case TYPE_INT: SetAddr(pRetReg, pyretval); break; - case TYPE_UINT: SetAddr(pRetReg, pyretval); break; - case TYPE_LONG: SetAddr(pRetReg, pyretval); break; - case TYPE_ULONG: SetAddr(pRetReg, pyretval); break; - case TYPE_LONGLONG: SetAddr(pRetReg, pyretval); break; - case TYPE_ULONGLONG: SetAddr(pRetReg, pyretval); break; - case TYPE_FLOAT: SetAddr(pRetReg, pyretval); break; - case TYPE_DOUBLE: SetAddr(pRetReg, pyretval); break; - case TYPE_POINTER: + bOverride = true; + switch(pHook->m_pRetParam->m_cParam) { - unsigned long retptr = ExtractPyPtr(pyretval); - memcpy(pRetReg, &retptr, sizeof(unsigned long)); - } break; - case TYPE_STRING: SetAddr(pRetReg, pyretval); break; - default: BOOST_RAISE_EXCEPTION(PyExc_TypeError, "Unknown type.") + case SIGCHAR_VOID: break; + case SIGCHAR_BOOL: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_CHAR: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_UCHAR: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_SHORT: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_USHORT: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_INT: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_UINT: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_LONG: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_ULONG: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_LONGLONG: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_ULONGLONG: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_FLOAT: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_DOUBLE: SetReturnValue(pHook, pyretval); break; + case SIGCHAR_POINTER: + { + unsigned long retptr = ExtractPyPtr(pyretval); + pHook->SetReturnValue(retptr); + } break; + case SIGCHAR_STRING: SetReturnValue(pHook, pyretval); break; + default: BOOST_RAISE_EXCEPTION(PyExc_TypeError, "Unknown type.") + } } - } - END_BOOST_PY_NORET() } - return buffer; + return bOverride; } // ============================================================================ // >> CStackData // ============================================================================ -CStackData::CStackData(CDetour* pDetour) +CStackData::CStackData(CHook* pHook) { - m_pRegisters = pDetour->GetAsmBridge()->GetConv()->GetRegisters(); - m_pFunction = pDetour->GetFuncObj(); - m_pStack = m_pFunction->GetStack(); -} - -unsigned int CStackData::get_arg_num() -{ - int argnum = m_pFunction->GetNumArgs(); - if (m_pFunction->GetConvention() == CONV_THISCALL) - argnum++; - - return argnum; + m_pHook = pHook; } object CStackData::get_item(unsigned int iIndex) { - if (iIndex >= get_arg_num()) + if (iIndex >= (unsigned int) m_pHook->GetArgumentCount()) BOOST_RAISE_EXCEPTION(PyExc_IndexError, "Index out of range.") // Argument already cached? @@ -213,103 +147,58 @@ object CStackData::get_item(unsigned int iIndex) if (retval) return retval; - if (m_pFunction->GetConvention() == CONV_THISCALL) - { - if (iIndex == 0) - { - #ifdef __linux__ - unsigned long thisptr = *(unsigned long *) (m_pRegisters->r_esp + 4); - #else - unsigned long thisptr = m_pRegisters->r_ecx; - #endif - retval = m_mapCache[0] = object(CPointer(thisptr)); - return retval; - } - } - - ArgNode_t* pArgNode = m_pStack->GetArgument(m_pFunction->GetConvention() == CONV_THISCALL ? iIndex-1 : iIndex); - int offset = pArgNode->m_nOffset; - - #ifdef __linux__ - if (m_pFunction->GetConvention() == CONV_THISCALL) - // Add size of "this" pointer - offset += 4; - #endif - - void* pAddr = (void *) (m_pRegisters->r_esp + 4 + offset); - switch(pArgNode->m_pArg->GetType()) + switch(m_pHook->GetArgument(iIndex)->m_cParam) { - case TYPE_BOOL: retval = ReadAddr(pAddr); break; - case TYPE_CHAR: retval = ReadAddr(pAddr); break; - case TYPE_UCHAR: retval = ReadAddr(pAddr); break; - case TYPE_SHORT: retval = ReadAddr(pAddr); break; - case TYPE_USHORT: retval = ReadAddr(pAddr); break; - case TYPE_INT: retval = ReadAddr(pAddr); break; - case TYPE_UINT: retval = ReadAddr(pAddr); break; - case TYPE_LONG: retval = ReadAddr(pAddr); break; - case TYPE_ULONG: retval = ReadAddr(pAddr); break; - case TYPE_LONGLONG: retval = ReadAddr(pAddr); break; - case TYPE_ULONGLONG: retval = ReadAddr(pAddr); break; - case TYPE_FLOAT: retval = ReadAddr(pAddr); break; - case TYPE_DOUBLE: retval = ReadAddr(pAddr); break; - case TYPE_POINTER: retval = object(CPointer(*(unsigned long *) pAddr)); break; - case TYPE_STRING: retval = ReadAddr(pAddr); break; + case SIGCHAR_BOOL: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_CHAR: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_UCHAR: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_SHORT: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_USHORT: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_INT: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_UINT: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_LONG: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_ULONG: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_LONGLONG: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_ULONGLONG: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_FLOAT: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_DOUBLE: retval = GetArgument(m_pHook, iIndex); break; + case SIGCHAR_POINTER: retval = object(CPointer(m_pHook->GetArgument(iIndex))); break; + case SIGCHAR_STRING: retval = GetArgument(m_pHook, iIndex); break; default: BOOST_RAISE_EXCEPTION(PyExc_TypeError, "Unknown type.") break; } - m_mapCache[iIndex] = retval; return retval; } void CStackData::set_item(unsigned int iIndex, object value) { - if (iIndex >= get_arg_num()) + if (iIndex >= (unsigned int) m_pHook->GetArgumentCount()) BOOST_RAISE_EXCEPTION(PyExc_IndexError, "Index out of range.") // Update cache m_mapCache[iIndex] = value; - - // Update address - if (m_pFunction->GetConvention() == CONV_THISCALL) + switch(m_pHook->GetArgument(iIndex)->m_cParam) { - if (iIndex == 0) - { - #ifdef __linux__ - SetAddr((void *) (m_pRegisters->r_esp + 4), value); - #else - m_pRegisters->r_ecx = extract(value); - #endif - return; - } - } - - ArgNode_t* pArgNode = m_pStack->GetArgument(m_pFunction->GetConvention() == CONV_THISCALL ? iIndex-1 : iIndex); - int offset = pArgNode->m_nOffset; - - #ifdef __linux__ - if (m_pFunction->GetConvention() == CONV_THISCALL) - // Add size of "this" pointer - offset += 4; - #endif - - void* ulAddr = (void*)(m_pRegisters->r_esp + 4 + offset); - switch(pArgNode->m_pArg->GetType()) - { - case TYPE_BOOL: SetAddr(ulAddr, value); break; - case TYPE_CHAR: SetAddr(ulAddr, value); break; - case TYPE_UCHAR: SetAddr(ulAddr, value); break; - case TYPE_SHORT: SetAddr(ulAddr, value); break; - case TYPE_USHORT: SetAddr(ulAddr, value); break; - case TYPE_INT: SetAddr(ulAddr, value); break; - case TYPE_UINT: SetAddr(ulAddr, value); break; - case TYPE_LONG: SetAddr(ulAddr, value); break; - case TYPE_ULONG: SetAddr(ulAddr, value); break; - case TYPE_LONGLONG: SetAddr(ulAddr, value); break; - case TYPE_ULONGLONG: SetAddr(ulAddr, value); break; - case TYPE_FLOAT: SetAddr(ulAddr, value); break; - case TYPE_DOUBLE: SetAddr(ulAddr, value); break; - case TYPE_POINTER: *(unsigned long *) ulAddr = ExtractPyPtr(value); break; - case TYPE_STRING: SetAddr(ulAddr, value); break; + case SIGCHAR_BOOL: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_CHAR: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_UCHAR: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_SHORT: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_USHORT: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_INT: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_UINT: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_LONG: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_ULONG: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_LONGLONG: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_ULONGLONG: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_FLOAT: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_DOUBLE: SetArgument(m_pHook, iIndex, value); break; + case SIGCHAR_POINTER: SetArgument(m_pHook, iIndex, object(ExtractPyPtr(value))); break; + case SIGCHAR_STRING: SetArgument(m_pHook, iIndex, value); break; default: BOOST_RAISE_EXCEPTION(PyExc_TypeError, "Unknown type.") } +} + +CPointer* CStackData::get_esp() +{ + return new CPointer((unsigned long) m_pHook->m_pESP); } \ No newline at end of file diff --git a/src/core/modules/memory/memory_hooks.h b/src/core/modules/memory/memory_hooks.h index f6d8d5e35..10f70c1bc 100644 --- a/src/core/modules/memory/memory_hooks.h +++ b/src/core/modules/memory/memory_hooks.h @@ -2,57 +2,30 @@ #define MEMORY_HOOKS_H #include - -#include "callback_manager.h" -#include "func_class.h" -#include "func_stack.h" -#include "register_class.h" - -#include "boost/python.hpp" - -#include "memory_tools.h" - #include +#include "boost/python.hpp" using namespace boost::python; - -class CCallbackManager: public ICallbackManager -{ -private: - std::list m_PreCalls; - std::list m_PostCalls; - -public: - virtual void Add(void* pFunc, eHookType type); - virtual void Remove(void* pFunc, eHookType type); - - virtual HookRetBuf_t* DoPreCalls(CDetour* pDetour); - virtual HookRetBuf_t* DoPostCalls(CDetour* pDetour); - - virtual const char* GetLang() { return "Python"; } -}; +#include "memory_tools.h" +#include "DynamicHooks.h" class CStackData { public: - CStackData(CDetour* pDetour); - - CPointer* get_esp() { return new CPointer(m_pRegisters->r_esp); } - CPointer* get_ecx() { return new CPointer(m_pRegisters->r_ecx); } - CPointer* get_ebp() { return new CPointer(m_pRegisters->r_ebp); } - CPointer* get_edx() { return new CPointer(m_pRegisters->r_edx); } + CStackData(CHook* pHook); object get_item(unsigned int iIndex); void set_item(unsigned int iIndex, object value); - unsigned int get_arg_num(); + CPointer* get_esp(); private: - CRegisterObj* m_pRegisters; - CFuncObj* m_pFunction; - CFuncStack* m_pStack; - map m_mapCache; + CHook* m_pHook; + std::map m_mapCache; }; + +bool SP_HookHandler(DynamicHooks::HookType_t eHookType, CHook* pHook); + #endif // MEMORY_HOOKS_H diff --git a/src/core/modules/memory/memory_tools.cpp b/src/core/modules/memory/memory_tools.cpp index 6db5b7150..268e8dd4f 100644 --- a/src/core/modules/memory/memory_tools.cpp +++ b/src/core/modules/memory/memory_tools.cpp @@ -33,17 +33,16 @@ #include "dyncall.h" #include "dyncall_signature.h" -#include "detour_class.h" -#include "detourman_class.h" #include "memory_hooks.h" -#include "dd_utils.h" - #include "memory_tools.h" #include "utility/wrap_macros.h" #include "utility/sp_util.h" DCCallVM* g_pCallVM = dcNewCallVM(4096); +extern std::map > > g_mapCallbacks; + +CHookManager* g_pHookMngr = new CHookManager; //----------------------------------------------------------------------------- // CPointer class @@ -128,7 +127,7 @@ CPointer* CPointer::get_virtual_func(int iIndex, bool bPlatformCheck /* = true * return new CPointer((unsigned long) vtable[iIndex]); } -CFunction* CPointer::make_function(Convention eConv, char* szParams) +CFunction* CPointer::make_function(Convention_t eConv, char* szParams) { if (!is_valid()) BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Pointer is NULL.") @@ -306,7 +305,7 @@ const char* CPointer::call_string() //----------------------------------------------------------------------------- // CFunction class //----------------------------------------------------------------------------- -CFunction::CFunction(unsigned long ulAddr, Convention eConv, char* szParams) +CFunction::CFunction(unsigned long ulAddr, Convention_t eConv, char* szParams) { m_ulAddr = ulAddr; m_eConv = eConv; @@ -319,8 +318,8 @@ object CFunction::__call__(object args) BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function pointer is NULL.") dcReset(g_pCallVM); - dcMode(g_pCallVM, m_eConv); - char* ptr = (char *) m_szParams.data(); + dcMode(g_pCallVM, GetDynCallConvention(m_eConv)); + char* ptr = (char *) m_szParams; int pos = 0; char ch; while ((ch = *ptr) != '\0' && ch != ')') @@ -388,64 +387,53 @@ object CFunction::call_trampoline(object args) if (!is_valid()) BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function pointer is NULL.") - CDetour* pDetour = g_DetourManager.Find_Detour((void *) m_ulAddr); - if (!pDetour) + CHook* pHook = g_pHookMngr->FindHook((void *) m_ulAddr); + if (!pHook) BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function was not hooked.") - return CFunction((unsigned long) pDetour->GetTrampoline(), m_eConv, (char *) m_szParams.data()).__call__(args); + return CFunction((unsigned long) pHook->m_pTrampoline, m_eConv, m_szParams).__call__(args); } -void CFunction::hook(eHookType eType, PyObject* pCallable) +void CFunction::add_hook(DynamicHooks::HookType_t eType, PyObject* pCallable) { if (!is_valid()) BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function pointer is NULL.") - CDetour* pDetour = g_DetourManager.Add_Detour((void*) m_ulAddr, m_szParams.data(), (eCallConv) m_eConv); - if (!pDetour) - BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Failed to hook function.") - - ICallbackManager* mngr = pDetour->GetManager("Python", eType); - if (!mngr) - { - mngr = new CCallbackManager; - pDetour->AddManager(mngr, eType); - } - - mngr->Add((void *) pCallable, eType); + CHook* pHook = g_pHookMngr->HookFunction((void *) m_ulAddr, m_eConv, m_szParams); + pHook->AddCallback(eType, (void *) &SP_HookHandler); + g_mapCallbacks[pHook][eType].push_back(pCallable); } -void CFunction::unhook(eHookType eType, PyObject* pCallable) +void CFunction::remove_hook(DynamicHooks::HookType_t eType, PyObject* pCallable) { if (!is_valid()) BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function pointer is NULL.") - - CDetour* pDetour = g_DetourManager.Find_Detour((void *) m_ulAddr); - if (!pDetour) + + CHook* pHook = g_pHookMngr->FindHook((void *) m_ulAddr); + if (!pHook) return; - ICallbackManager* mngr = pDetour->GetManager("Python", eType); - if (mngr) - mngr->Remove((void *) pCallable, eType); + g_mapCallbacks[pHook][eType].remove(pCallable); } void CFunction::add_pre_hook(PyObject* pCallable) { - hook(TYPE_PRE, pCallable); + add_hook(HOOKTYPE_PRE, pCallable); } void CFunction::add_post_hook(PyObject* pCallable) { - hook(TYPE_POST, pCallable); + add_hook(HOOKTYPE_POST, pCallable); } void CFunction::remove_pre_hook(PyObject* pCallable) { - unhook(TYPE_PRE, pCallable); + remove_hook(HOOKTYPE_PRE, pCallable); } void CFunction::remove_post_hook(PyObject* pCallable) { - unhook(TYPE_POST, pCallable); + remove_hook(HOOKTYPE_POST, pCallable); } //----------------------------------------------------------------------------- diff --git a/src/core/modules/memory/memory_tools.h b/src/core/modules/memory/memory_tools.h index c163f3254..872da7eb6 100644 --- a/src/core/modules/memory/memory_tools.h +++ b/src/core/modules/memory/memory_tools.h @@ -29,9 +29,12 @@ #include #include "memalloc.h" -#include "utility/wrap_macros.h" -#include "hook_types.h" #include "dyncall.h" + +#include "utility/wrap_macros.h" +#include "DynamicHooks.h" +using namespace DynamicHooks; + #include "boost/python.hpp" using namespace boost::python; @@ -86,18 +89,23 @@ inline void UTIL_Dealloc(void* ptr) //----------------------------------------------------------------------------- // Convention enum //----------------------------------------------------------------------------- -enum Convention +inline int GetDynCallConvention(Convention_t eConv) { - _CONV_CDECL = DC_CALL_C_DEFAULT, -#ifdef _WIN32 - _CONV_STDCALL = DC_CALL_C_X86_WIN32_STD, - _CONV_FASTCALL = DC_CALL_C_X86_WIN32_FAST_MS, - _CONV_THISCALL = DC_CALL_C_X86_WIN32_THIS_MS -#else - _CONV_FASTCALL = DC_CALL_C_X86_WIN32_FAST_GNU, - _CONV_THISCALL = DC_CALL_C_X86_WIN32_THIS_GNU -#endif -}; + switch (eConv) + { + case CONV_CDECL: return DC_CALL_C_DEFAULT; + case CONV_THISCALL: + #ifdef _WIN32 + return DC_CALL_C_X86_WIN32_THIS_MS; + #else + return DC_CALL_C_X86_WIN32_THIS_GNU; + #endif + case CONV_STDCALL: return DC_CALL_C_X86_WIN32_STD; + } + + // TODO: Throw exception + return 0; +} //----------------------------------------------------------------------------- // CPointer class @@ -145,43 +153,43 @@ class CPointer void realloc(int iSize) { m_ulAddr = (unsigned long) UTIL_Realloc((void *) m_ulAddr, iSize); } void dealloc() { UTIL_Dealloc((void *) m_ulAddr); m_ulAddr = 0; } - CFunction* make_function(Convention eConv, char* szParams); - - void reset_vm(); - void set_mode(int iMode); - - void set_arg_bool(bool value); - void set_arg_char(char value); - void set_arg_uchar(unsigned char value); - void set_arg_short(short value); - void set_arg_ushort(unsigned short value); - void set_arg_int(int value); - void set_arg_uint(unsigned int value); - void set_arg_long(long value); - void set_arg_ulong(unsigned long value); - void set_arg_long_long(long long value); - void set_arg_ulong_long(unsigned long long value); - void set_arg_float(float value); - void set_arg_double(double value); - void set_arg_pointer(object value); - void set_arg_string(char* value); - - void call_void(); - bool call_bool(); - char call_char(); - unsigned char call_uchar(); - short call_short(); - unsigned short call_ushort(); - int call_int(); - unsigned int call_uint(); - long call_long(); - unsigned long call_ulong(); - long long call_long_long(); - unsigned long long call_ulong_long(); - float call_float(); - double call_double(); - CPointer* call_pointer(); - const char* call_string(); + CFunction* make_function(Convention_t eConv, char* szParams); + + void reset_vm(); + void set_mode(int iMode); + + void set_arg_bool(bool value); + void set_arg_char(char value); + void set_arg_uchar(unsigned char value); + void set_arg_short(short value); + void set_arg_ushort(unsigned short value); + void set_arg_int(int value); + void set_arg_uint(unsigned int value); + void set_arg_long(long value); + void set_arg_ulong(unsigned long value); + void set_arg_long_long(long long value); + void set_arg_ulong_long(unsigned long long value); + void set_arg_float(float value); + void set_arg_double(double value); + void set_arg_pointer(object value); + void set_arg_string(char* value); + + void call_void(); + bool call_bool(); + char call_char(); + unsigned char call_uchar(); + short call_short(); + unsigned short call_ushort(); + int call_int(); + unsigned int call_uint(); + long call_long(); + unsigned long call_ulong(); + long long call_long_long(); + unsigned long long call_ulong_long(); + float call_float(); + double call_double(); + CPointer* call_pointer(); + const char* call_string(); protected: unsigned long m_ulAddr; @@ -190,13 +198,13 @@ class CPointer class CFunction: public CPointer { public: - CFunction(unsigned long ulAddr, Convention eConv, char* szParams); + CFunction(unsigned long ulAddr, Convention_t eConv, char* szParams); object __call__(object args); object call_trampoline(object args); - void hook(eHookType eType, PyObject* pCallable); - void unhook(eHookType eType, PyObject* pCallable); + void add_hook(DynamicHooks::HookType_t eType, PyObject* pCallable); + void remove_hook(DynamicHooks::HookType_t eType, PyObject* pCallable); void add_pre_hook(PyObject* pCallable); void add_post_hook(PyObject* pCallable); @@ -205,8 +213,8 @@ class CFunction: public CPointer void remove_post_hook(PyObject* pCallable); private: - std::string m_szParams; - Convention m_eConv; + char* m_szParams; + Convention_t m_eConv; }; int get_error(); diff --git a/src/core/modules/memory/memory_wrap_python.cpp b/src/core/modules/memory/memory_wrap_python.cpp index ed6c04b2d..a027487de 100644 --- a/src/core/modules/memory/memory_wrap_python.cpp +++ b/src/core/modules/memory/memory_wrap_python.cpp @@ -34,13 +34,10 @@ #include "dyncall.h" -#include "hook_types.h" -#include "detour_class.h" - void export_binaryfile(); void export_memtools(); void export_dyncall(); -void export_dyndetours(); +void export_dynamichooks(); //----------------------------------------------------------------------------- // Exposes the memory_c module. @@ -50,7 +47,7 @@ DECLARE_SP_MODULE(memory_c) export_binaryfile(); export_memtools(); export_dyncall(); - export_dyndetours(); + export_dynamichooks(); } //----------------------------------------------------------------------------- @@ -629,7 +626,7 @@ void export_memtools() manage_new_object_policy() ); - BOOST_INHERITED_CLASS_CONSTRUCTOR(CFunction, CPointer, unsigned long, Convention, char*) + BOOST_INHERITED_CLASS_CONSTRUCTOR(CFunction, CPointer, unsigned long, Convention_t, char*) CLASS_METHOD_VARIADIC(CFunction, __call__, @@ -641,6 +638,18 @@ void export_memtools() "Calls the trampoline function dynamically." ) + CLASS_METHOD(CFunction, + add_hook, + "Adds a hook callback.", + args("hook_type", "callback") + ) + + CLASS_METHOD(CFunction, + remove_hook, + "Removes a hook callback.", + args("hook_type", "callback") + ) + CLASS_METHOD(CFunction, add_pre_hook, "Adds a pre-hook callback." @@ -672,13 +681,10 @@ void export_memtools() //----------------------------------------------------------------------------- void export_dyncall() { - BOOST_ENUM(Convention) - ENUM_VALUE("CDECL", _CONV_CDECL) - #ifdef _WIN32 - ENUM_VALUE("STDCALL", _CONV_STDCALL) - #endif - ENUM_VALUE("FASTCALL", _CONV_FASTCALL) - ENUM_VALUE("THISCALL", _CONV_THISCALL) + enum_("Convention") + ENUM_VALUE("CDECL", CONV_CDECL) + ENUM_VALUE("STDCALL", CONV_STDCALL) + ENUM_VALUE("THISCALL", CONV_THISCALL) BOOST_END_CLASS() // Other constants that are very useful. @@ -690,9 +696,9 @@ void export_dyncall() ); } -void export_dyndetours() +void export_dynamichooks() { - BOOST_CLASS_CONSTRUCTOR(CStackData, CDetour*) + BOOST_CLASS_CONSTRUCTOR(CStackData, CHook*) // Special methods CLASS_METHOD_SPECIAL(CStackData, @@ -716,29 +722,5 @@ void export_dyndetours() "Stack pointer register." ) - .add_property("ecx", - make_function( - &CStackData::get_ecx, - manage_new_object_policy() - ), - "Counter register." - ) - - .add_property("ebp", - make_function( - &CStackData::get_ebp, - manage_new_object_policy() - ), - "Base pointer register." - ) - - .add_property("edx", - make_function( - &CStackData::get_edx, - manage_new_object_policy() - ), - "Data register." - ) - BOOST_END_CLASS() } \ No newline at end of file diff --git a/src/makefiles/linux/linux.base.cmake b/src/makefiles/linux/linux.base.cmake index 0bc70b56b..63efcbbcb 100644 --- a/src/makefiles/linux/linux.base.cmake +++ b/src/makefiles/linux/linux.base.cmake @@ -41,8 +41,6 @@ Set(SOURCEPYTHON_LINK_LIBRARIES ${DYNCALLSDK_LIB}/libdyncall_s.a ${DYNCALLSDK_LIB}/libdyncallback_s.a ${DYNCALLSDK_LIB}/libdynload_s.a - ${DYNDETOURSSDK_LIB}/libDynDetours.a - ${DYNDETOURSSDK_LIB}/libAsmJit.a ) # ------------------------------------------------------------------ @@ -74,7 +72,7 @@ EndIf() # Linux compiler flags. # ------------------------------------------------------------------ Set(CMAKE_CXX_FLAGS "-D_LINUX -DPOSIX -DLINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp") -Set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp") +Set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp") Set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca") Set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dstrcmpi=strcasecmp -Wall -Wno-uninitialized -Wno-switch -Wno-unused") Set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -msse -m32 -DCOMPILER_GCC -fno-strict-aliasing -std=c++0x") @@ -96,11 +94,15 @@ EndIf() Set(SOURCEPYTHON_LINK_LIBRARIES_RELEASE ${PYTHONSDK_LIB}/libpython3.3m.a ${BOOSTSDK_LIB}/libboost_python.a - ${PYTHONSDK_LIB}/libpython3.3m.so.1.0 + ${PYTHONSDK_LIB}/libpython3.3m.so.1.0 + ${DYNAMICHOOKSSDK_LIB}/libAsmJit.a + ${DYNAMICHOOKSSDK_LIB}/libDynamicHooks.a ) Set(SOURCEPYTHON_LINK_LIBRARIES_DEBUG ${PYTHONSDK_LIB}/libpython3.3dm.a ${BOOSTSDK_LIB}/libboost_python_d.a ${PYTHONSDK_LIB}/libpython3.3dm.so.1.0 + ${DYNAMICHOOKSSDK_LIB}/libAsmJit_d.a + ${DYNAMICHOOKSSDK_LIB}/libDynamicHooks_d.a ) \ No newline at end of file diff --git a/src/makefiles/shared.cmake b/src/makefiles/shared.cmake index 6dcdac798..0a0ef24a9 100644 --- a/src/makefiles/shared.cmake +++ b/src/makefiles/shared.cmake @@ -46,10 +46,11 @@ Set(PROTOBUF ${THIRDPARTY_DIR}/protobuf/protobuf-2.3.0) Set(PROTOBUF_INCLUDE ${PROTOBUF}/src) # ------------------------------------------------------------------ -# DynDetours specific. +# DynamicHooks specific. # ------------------------------------------------------------------ -Set(DYNDETOURSSDK ${THIRDPARTY_DIR}/dyndetours) -Set(DYNDETOURSSDK_LIB ${DYNDETOURSSDK}/lib) +Set(DYNAMICHOOKSSDK ${THIRDPARTY_DIR}/DynamicHooks) +Set(DYNAMICHOOKSSDK_INCLUDE ${DYNAMICHOOKSSDK}/include) +Set(DYNAMICHOOKSSDK_LIB ${DYNAMICHOOKSSDK}/lib) # ------------------------------------------------------------------ # Include directories @@ -66,7 +67,7 @@ Include_Directories( ${DYNCALLSDK_INCLUDE} ${BOOSTSDK_INCLUDE} ${PROTOBUF_INCLUDE} - ${DYNDETOURSSDK} + ${DYNAMICHOOKSSDK_INCLUDE} ${CMAKE_CURRENT_SOURCE_DIR}/core # Hack but required. ) @@ -82,9 +83,4 @@ Add_Definitions( # ------------------------------------------------------------------ # The project. # ------------------------------------------------------------------ -Project(source-python C CXX) - -# ------------------------------------------------------------------ -# Get rid of the library prefix for all distributions. -# ------------------------------------------------------------------ -# Set(CMAKE_SHARED_LIBRARY_PREFIX "") \ No newline at end of file +Project(source-python C CXX) \ No newline at end of file diff --git a/src/makefiles/win32/win32.base.cmake b/src/makefiles/win32/win32.base.cmake index 5cb2ec8e3..939389c1c 100644 --- a/src/makefiles/win32/win32.base.cmake +++ b/src/makefiles/win32/win32.base.cmake @@ -62,8 +62,10 @@ Set(SOURCEPYTHON_LINK_LIBRARIES ${DYNCALLSDK_LIB}/libdyncall_s.lib ${DYNCALLSDK_LIB}/libdyncallback_s.lib ${DYNCALLSDK_LIB}/libdynload_s.lib - ${DYNDETOURSSDK_LIB}/DynDetours.lib - ${DYNDETOURSSDK_LIB}/AsmJit.lib + optimized ${DYNAMICHOOKSSDK_LIB}/AsmJit.lib + optimized ${DYNAMICHOOKSSDK_LIB}/DynamicHooks.lib + debug ${DYNAMICHOOKSSDK_LIB}/AsmJit_d.lib + debug ${DYNAMICHOOKSSDK_LIB}/DynamicHooks_d.lib ) # CSGO Engine adds in interfaces.lib @@ -77,8 +79,8 @@ Endif() # ------------------------------------------------------------------ # Debug link libraries # ------------------------------------------------------------------ -Set(SOURCEPYTHON_LINK_LIBRARIES_DEBUG - debug ${PYTHONSDK_LIB}/python33_d.lib +Set(SOURCEPYTHON_LINK_LIBRARIES_DEBUG + debug ${PYTHONSDK_LIB}/python33_d.lib debug ${BOOSTSDK_LIB}/libboost_python-vc100-mt-gyd-1_53.lib ) @@ -92,8 +94,8 @@ Endif() # ------------------------------------------------------------------ # Release link libraries # ------------------------------------------------------------------ -Set(SOURCEPYTHON_LINK_LIBRARIES_RELEASE - optimized ${PYTHONSDK_LIB}/python33.lib +Set(SOURCEPYTHON_LINK_LIBRARIES_RELEASE + optimized ${PYTHONSDK_LIB}/python33.lib optimized ${BOOSTSDK_LIB}/libboost_python-vc100-mt-1_53.lib ) diff --git a/src/thirdparty/DynamicHooks/include/DynamicHooks.h b/src/thirdparty/DynamicHooks/include/DynamicHooks.h new file mode 100644 index 000000000..c0038cde9 --- /dev/null +++ b/src/thirdparty/DynamicHooks/include/DynamicHooks.h @@ -0,0 +1,282 @@ +/** +* ============================================================================= +* DynamicHooks +* Copyright (C) 2013 Robin Gohmert. All rights reserved. +* ============================================================================= +* +* This software is provided 'as-is', without any express or implied warranty. +* In no event will the authors be held liable for any damages arising from +* the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software in a +* product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +* asm.h/cpp from devmaster.net (thanks cybermind) edited by pRED* to handle gcc +* -fPIC thunks correctly +* +* Idea and trampoline code taken from DynDetours (thanks your-name-here). +*/ + +#ifndef _DYNAMIC_HOOKS_H +#define _DYNAMIC_HOOKS_H + +// ============================================================================ +// >> INCLUDES +// ============================================================================ +#include +#include + +namespace DynamicHooks { + +// ============================================================================ +// >> TYPE DEFINITIONS +// ============================================================================ +#define SIGCHAR_VOID 'v' +#define SIGCHAR_BOOL 'b' +#define SIGCHAR_CHAR 'c' +#define SIGCHAR_UCHAR 'C' +#define SIGCHAR_SHORT 's' +#define SIGCHAR_USHORT 'S' +#define SIGCHAR_INT 'i' +#define SIGCHAR_UINT 'I' +#define SIGCHAR_LONG 'j' +#define SIGCHAR_ULONG 'J' +#define SIGCHAR_LONGLONG 'l' +#define SIGCHAR_ULONGLONG 'L' +#define SIGCHAR_FLOAT 'f' +#define SIGCHAR_DOUBLE 'd' +#define SIGCHAR_POINTER 'p' +#define SIGCHAR_STRING 'Z' + + +// ============================================================================ +// >> HookType_t +// ============================================================================ +enum HookType_t +{ + // Callback will be executed before the original function. + HOOKTYPE_PRE, + + // Callback will be executed after the original function. + HOOKTYPE_POST +}; + + +// ============================================================================ +// >> Convention_t +// ============================================================================ +enum Convention_t +{ + CONV_CDECL, + CONV_THISCALL, + CONV_STDCALL +}; + + +// ============================================================================ +// >> Param_t +// ============================================================================ +struct Param_t +{ + char m_cParam; + int m_iOffset; + int m_iSize; + Param_t* m_pNext; +}; + + +// ============================================================================ +// >> CHook +// ============================================================================ +class CHook +{ +public: + CHook(void* pFunc, Convention_t eConvention, char* szParams); + ~CHook(); + + /* + Returns the return value of the trampoline. Returns only valid data in + a post-hook callback. + */ + template + T GetReturnValue() + { + return *(T *) m_pRetReg; + } + + /* + Sets a new return value. + */ + template + void SetReturnValue(T value) + { + *(T *) m_pRetReg = value; + } + + /* + Returns the argument at the given index. + 0 = 1st argument or this pointer + 1 = 2nd argument + etc... + */ + template + T GetArgument(int iIndex) + { +#ifdef _WIN32 + if (m_eConvention == CONV_THISCALL && iIndex == 0) + return *(T *) &m_pECX; +#endif + + unsigned long reg = ((unsigned long) m_pESP) + GetArgument(iIndex)->m_iOffset + 4; + return *(T *) reg; + } + + /* + Overrides an argument at the given index. + 0 = 1st argument or this pointer + 1 = 2nd argument + etc... + */ + template + void SetArgument(int iIndex, T value) + { +#ifdef _WIN32 + if (m_eConvention == CONV_THISCALL && iIndex == 0) + { + m_pECX = *(void **) &value; + return; + } +#endif + + unsigned long reg = ((unsigned long) m_pESP) + GetArgument(iIndex)->m_iOffset + 4; + *(T *) reg = value; + } + + /* + Adds a new callback to the callback list. + */ + void AddCallback(HookType_t eHookType, void* pCallback); + + /* + Removes an existing callback from the callback list. + */ + void RemoveCallback(HookType_t eHookType, void* pCallback); + + /* + Returns true if the callback is in the callback list. + */ + bool IsCallbackRegistered(HookType_t eHookType, void* pCallback); + + /* + Returns the size you have to pop off from stack as a callee. + */ + int GetPopSize(); + + /* + Returns the number of arguments + this pointer (if it's a thiscall). + */ + int GetArgumentCount(); + + /* + Returns a Param_t pointer for the given argument index. + */ + Param_t* GetArgument(int iIndex); + +public: + // This is the return register buffer (eax and st0) + void* m_pRetReg; + + // Stack pointer register buffer + void* m_pESP; + + // Counter register. This will only be set on Windows + void* m_pECX; + + // Contains the original return address + void* m_pRetAddr; + + + // Parameter struct + Param_t* m_pParams; + + // Return type struct + Param_t* m_pRetParam; + + + // Address of the trampoline + void* m_pTrampoline; + + // Address of the bridge + void* m_pBridge; + + // Address of the hooked function + void* m_pFunc; + + + // Calling convention of the original function + Convention_t m_eConvention; + + // Stringified parameter list + char* m_szParams; + + + // A map for all callbacks + std::map< HookType_t, std::list > m_Callbacks; +}; + + +// ============================================================================ +// >> CHookManager +// ============================================================================ +class CHookManager +{ +public: + /* + Hooks the given function and returns a new CHook instance. If the + function was already hooked, the existing CHook instance will be + returned. + */ + CHook* HookFunction(void* pFunc, Convention_t eConvention, char* szParams); + + /* + Removes all callbacks and restores the original function. + */ + void UnhookFunction(void* pFunc); + + /* + Returns either NULL or the found CHook instance. + */ + CHook* FindHook(void* pFunc); + + /* + Removes all callbacks and restores all functions. + */ + void UnhookAllFunctions(); + +public: + std::list m_Hooks; +}; + + +// ============================================================================ +// >> GetHookManager +// ============================================================================ +/* + Returns a pointer to a static CHookManager object. +*/ +CHookManager* GetHookManager(); + +} // namespace DynamicHooks + +#endif // _DYNAMIC_HOOKS_H \ No newline at end of file diff --git a/src/thirdparty/dyndetours/asm.h b/src/thirdparty/DynamicHooks/include/asm.h similarity index 82% rename from src/thirdparty/dyndetours/asm.h rename to src/thirdparty/DynamicHooks/include/asm.h index 731423327..30327071f 100644 --- a/src/thirdparty/dyndetours/asm.h +++ b/src/thirdparty/DynamicHooks/include/asm.h @@ -1,9 +1,8 @@ /** -* ====================================================== -* DynDetours -* Copyright (C) 2009 Deniz Sezen -* All rights reserved. -* ====================================================== +* ============================================================================= +* DynamicHooks +* Copyright (C) 2013 Robin Gohmert. All rights reserved. +* ============================================================================= * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from @@ -23,8 +22,10 @@ * * 3. This notice may not be removed or altered from any source distribution. * -* asm.h/c from devmaster.net (thanks cybermind) edited by pRED* to handle gcc +* asm.h/cpp from devmaster.net (thanks cybermind) edited by pRED* to handle gcc * -fPIC thunks correctly +* +* Idea and trampoline code taken from DynDetours (thanks your-name-here). */ #ifndef __ASM_H__ diff --git a/src/thirdparty/dyndetours/memutils.h b/src/thirdparty/DynamicHooks/include/utilities.h similarity index 55% rename from src/thirdparty/dyndetours/memutils.h rename to src/thirdparty/DynamicHooks/include/utilities.h index 8f632f02a..1896e9f08 100644 --- a/src/thirdparty/dyndetours/memutils.h +++ b/src/thirdparty/DynamicHooks/include/utilities.h @@ -1,9 +1,8 @@ /** -* ====================================================== -* DynDetours -* Copyright (C) 2009 Deniz Sezen -* All rights reserved. -* ====================================================== +* ============================================================================= +* DynamicHooks +* Copyright (C) 2013 Robin Gohmert. All rights reserved. +* ============================================================================= * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from @@ -23,30 +22,33 @@ * * 3. This notice may not be removed or altered from any source distribution. * -* SetMemPatchable and ProtectMemory taken entirely from CSSDM by -* David "BAILOPAN" Anderson. +* asm.h/cpp from devmaster.net (thanks cybermind) edited by pRED* to handle gcc +* -fPIC thunks correctly +* +* Idea and trampoline code taken from DynDetours (thanks your-name-here). */ -#ifndef _MEMUTILS_H -#define _MEMUTILS_H +#ifndef _UTILITIES_H +#define _UTILITIES_H + +// ============================================================================ +// >> INCLUDES +// ============================================================================ +#include "DynamicHooks.h" + -// ================================================================== -// Includes -// ================================================================== -#ifdef _WIN32 -#include -#endif -#include +// ============================================================================ +// >> DEFINITIONS +// ============================================================================ +typedef bool (*HookFn)(DynamicHooks::HookType_t, DynamicHooks::CHook*); -// ================================================================== -// Memory functions. -// ================================================================== -extern void ProtectMemory(void *addr, int length, int prot); -extern void SetMemPatchable(void *address, size_t size); -// ================================================================== -// Misc detour functions. -// ================================================================== -extern void WriteJMP(unsigned char* src, void* dest); +// ============================================================================ +// >> FUNCTIONS +// ============================================================================ +int GetTypeSize(char cType); +void ParseParams(DynamicHooks::Convention_t eConvention, char* szParams, DynamicHooks::Param_t* pParams, DynamicHooks::Param_t* pRetParam); +void SetMemPatchable(void* pAddr, size_t size); +void WriteJMP(unsigned char* src, void* dest); -#endif +#endif // _UTILITIES_H \ No newline at end of file diff --git a/src/thirdparty/DynamicHooks/lib/AsmJit.lib b/src/thirdparty/DynamicHooks/lib/AsmJit.lib new file mode 100644 index 000000000..27a5544e3 Binary files /dev/null and b/src/thirdparty/DynamicHooks/lib/AsmJit.lib differ diff --git a/src/thirdparty/DynamicHooks/lib/AsmJit_d.lib b/src/thirdparty/DynamicHooks/lib/AsmJit_d.lib new file mode 100644 index 000000000..28c777086 Binary files /dev/null and b/src/thirdparty/DynamicHooks/lib/AsmJit_d.lib differ diff --git a/src/thirdparty/DynamicHooks/lib/DynamicHooks.lib b/src/thirdparty/DynamicHooks/lib/DynamicHooks.lib new file mode 100644 index 000000000..4e0919a66 Binary files /dev/null and b/src/thirdparty/DynamicHooks/lib/DynamicHooks.lib differ diff --git a/src/thirdparty/DynamicHooks/lib/DynamicHooks_d.lib b/src/thirdparty/DynamicHooks/lib/DynamicHooks_d.lib new file mode 100644 index 000000000..499a459d6 Binary files /dev/null and b/src/thirdparty/DynamicHooks/lib/DynamicHooks_d.lib differ diff --git a/src/thirdparty/DynamicHooks/lib/libAsmJit.a b/src/thirdparty/DynamicHooks/lib/libAsmJit.a new file mode 100644 index 000000000..a6e5465ac Binary files /dev/null and b/src/thirdparty/DynamicHooks/lib/libAsmJit.a differ diff --git a/src/thirdparty/DynamicHooks/lib/libAsmJit_d.a b/src/thirdparty/DynamicHooks/lib/libAsmJit_d.a new file mode 100644 index 000000000..9ebcb644e Binary files /dev/null and b/src/thirdparty/DynamicHooks/lib/libAsmJit_d.a differ diff --git a/src/thirdparty/DynamicHooks/lib/libDynamicHooks.a b/src/thirdparty/DynamicHooks/lib/libDynamicHooks.a new file mode 100644 index 000000000..730cdc2d4 Binary files /dev/null and b/src/thirdparty/DynamicHooks/lib/libDynamicHooks.a differ diff --git a/src/thirdparty/DynamicHooks/lib/libDynamicHooks_d.a b/src/thirdparty/DynamicHooks/lib/libDynamicHooks_d.a new file mode 100644 index 000000000..77e3bcc76 Binary files /dev/null and b/src/thirdparty/DynamicHooks/lib/libDynamicHooks_d.a differ diff --git a/src/thirdparty/dyncall/include/dyncall_signature.h b/src/thirdparty/dyncall/include/dyncall_signature.h index 1b0b207a9..45a9187ad 100644 --- a/src/thirdparty/dyncall/include/dyncall_signature.h +++ b/src/thirdparty/dyncall/include/dyncall_signature.h @@ -40,7 +40,7 @@ typedef char DCsigchar; #define DC_SIGCHAR_VOID 'v' -#define DC_SIGCHAR_BOOL 'B' +#define DC_SIGCHAR_BOOL 'b' #define DC_SIGCHAR_CHAR 'c' #define DC_SIGCHAR_UCHAR 'C' #define DC_SIGCHAR_SHORT 's' diff --git a/src/thirdparty/dyndetours/AsmJit/AsmJit.h b/src/thirdparty/dyndetours/AsmJit/AsmJit.h deleted file mode 100644 index f3fd4f28c..000000000 --- a/src/thirdparty/dyndetours/AsmJit/AsmJit.h +++ /dev/null @@ -1,386 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_H -#define _ASMJIT_H - -//! @mainpage -//! -//! @brief AsmJit is complete x86/x64 JIT Assembler for C++ language -//! -//! It supports FPU, MMX, 3dNow, SSE, SSE2, SSE3 and SSE4 intrinsics, powerful -//! compiler that helps to write portable functions for 32-bit (x86) and 64-bit -//! (x64) architectures. AsmJit can be used to create functions at runtime that -//! can be called from existing (but also generated) C/C++ code. -//! -//! AsmJit is crossplatform library that supports various compilers and -//! operating systems. Currently only limitation is x86 (32-bit) or x64 (64-bit) -//! processor. Currently tested operating systems are Windows (32 bit and 64 bit), -//! Linux (32 bit and 64 bit) and MacOSX (32 bit). -//! -//! Introduction -//! -//! AsmJit library contains two main classes for code generation with different -//! goals. First main code generation class is called @c AsmJit::Assembler and -//! contains low level API that can be used to generate JIT binary code. It -//! directly emits binary stream that represents encoded x86/x64 assembler -//! opcodes. Together with operands and labels it can be used to generate -//! complete code. For details look to @ref AsmJit_Serializer and -//! @ref AsmJit_Assembler sections. -//! -//! There is also class named @c AsmJit::Compiler that allows to develop -//! crossplatform assembler code without worring about function calling -//! conventions and registers allocation. It can be also used to write 32 -//! bit and 64 bit portable code. Compiler is recommended class to use for -//! code generation. If you want to use pure @c AsmJit::Compiler solution, -//! it's needed also to look at @c AsmJit::Assembler and @c AsmJit::Serializer -//! classes to understand how AsmJit library works and how you should use -//! its API. -//! -//! Everything in AsmJit library is in @c AsmJit namespace. -//! -//! Code generation sections: -//! -//! - @ref AsmJit_Serializer "Serializer" - Intrinsics, operands and labels. -//! - @ref AsmJit_Assembler "Assembler" - Low level code generation. -//! - @ref AsmJit_Compiler "Compiler" - High level code generation. -//! - @ref AsmJit_CpuInfo "Cpu Informations" - Get informations about host processor. -//! - @ref AsmJit_Logging "Logging" - Logging and error handling. -//! - @ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management. -//! -//! Configuration, definitions and utilities: -//! -//! - @ref AsmJit_Config "Configuration" - Macros used to configure AsmJit. -//! - @ref AsmJit_Defs "Definitions" - Constants and macros. -//! - @ref AsmJit_Util "Utilities" - Utilities and helper classes. -//! -//! AsmJit homepage: -//! - http://code.google.com/p/asmjit/ -//! -//! External resources: -//! - http://www.agner.org/optimize/ -//! - http://www.mark.masmcode.com/ (Assembler Tips) -//! - http://avisynth.org/mediawiki/Filter_SDK/Assembler_optimizing (Optimizing) -//! - http://www.ragestorm.net/distorm/ (Disassembling) - - -//! @defgroup AsmJit_Assembler Assembler - low level code generation. -//! -//! Contains classes related to @c AsmJit::Assembler that is directly used -//! to generate machine code stream. It's one of oldest and fastest method -//! to generate machine code through AsmJit library. -//! -//! - See @c AsmJit::Serializer class for intrinsics and operands -//! documentation. -//! - See @c AsmJit::Assembler class for low level code generation -//! documentation. - - -//! @defgroup AsmJit_Compiler Compiler - high level code generation. -//! -//! Contains classes related to @c AsmJit::Compiler that is high level code -//! generation class. -//! -//! - See @c AsmJit::Serializer class for intrinsics and operands -//! documentation. -//! - See @c AsmJit::Assembler class for low level code generation -//! and documentation for assembler operands. -//! - See @c AsmJit::Compiler class for high level code generation -//! documentation - calling conventions, function declaration -//! and variables management. - -//! @defgroup AsmJit_Config Configuration - macros used to configure AsmJit. -//! library. -//! -//! Contains macros that can be redefined to fit into any project. - - -//! @defgroup AsmJit_CpuInfo Cpu informations - Get informations about host -//! processor. -//! -//! X86 or x64 cpuid instruction allows to get information about processor -//! vendor and it's features. It's always used to detect features like MMX, -//! SSE and other newer ones. -//! -//! AsmJit library supports low level cpuid call implemented internally as -//! C++ function using inline assembler or intrinsics and also higher level -//! CPU features detection. The low level function (also used by higher level -//! one) is @c AsmJit::cpuid(). -//! -//! AsmJit library also contains higher level function @c AsmJit::cpuInfo() -//! that returns features detected by the library. The detection process is -//! done only once and it's cached for all next calls. @c AsmJit::CpuInfo -//! structure not contains only informations through @c AsmJit::cpuid(), but -//! there is also small multiplatform code to detect number of processors -//! (or cores) throught operating system API. -//! -//! It's recommended to use @c AsmJit::cpuInfo to detect and check for -//! host processor features. -//! -//! Example how to use AsmJit::cpuid(): -//! -//! @code -//! // All functions and structures are in AsmJit namesapce. -//! using namespace AsmJit; -//! -//! // Here will be retrieved result of cpuid call. -//! CpuId out; -//! -//! // Use cpuid function to do the job. -//! cpuid(0 /* eax */, &out /* eax, ebx, ecx, edx */); -//! -//! // Id eax argument to cpuid is 0, ebx, ecx and edx registers -//! // are filled with cpu vendor. -//! char vendor[13]; -//! memcpy(i->vendor, &out.ebx, 4); -//! memcpy(i->vendor + 4, &out.edx, 4); -//! memcpy(i->vendor + 8, &out.ecx, 4); -//! vendor[12] = '\0'; -//! -//! // Print vendor -//! puts(vendor); -//! @endcode -//! -//! If you want to use AsmJit::cpuid() function instead of higher level -//! @c AsmJit::cpuInfo(), please read processor manuals provided by Intel, -//! AMD or other manufacturers for cpuid instruction details. -//! -//! Example of using @c AsmJit::cpuInfo(): -//! -//! @code -//! // All functions and structures are in AsmJit namesapce. -//! using namespace AsmJit; -//! -//! // Call to cpuInfo return CpuInfo structure that shouldn't be modified. -//! // Make it const by default. -//! const CpuInfo *i = cpuInfo(); -//! -//! // Now you are able to get specific features -//! -//! // Processor has SSE2 -//! if (i->features & CpuInfo::Feature_SSE2) -//! { -//! // your code... -//! } -//! // Processor has MMX -//! else if (i->features & CpuInfo::Feature_MMX) -//! { -//! // your code... -//! } -//! // Processor is old, no SSE2 or MMX support -//! else -//! { -//! // your code... -//! } -//! @endcode -//! -//! Better example is in AsmJit/test/testcpu.cpp file. -//! -//! @sa AsmJit::cpuid, @c AsmJit::cpuInfo. - - -//! @defgroup AsmJit_Defs Definitions - registers and instructions constants. -//! -//! Contains constants used in AsmJit library. - - -//! @defgroup AsmJit_Logging Logging - logging and error handling. -//! -//! Contains classes related to loging assembler output. Currently logging -//! is implemented in @c AsmJit::Logger class.You can override -//! @c AsmJit::Logger::log() to log messages into your stream. There is also -//! @c FILE based logger implemented in @c AsmJit::FileLogger class. -//! -//! To log your assembler output to FILE stream use this code: -//! -//! @code -//! // Create assembler -//! Assembler a; -//! -//! // Create and set file based logger -//! FileLogger logger(stderr); -//! a.setLogger(&logger); -//! @endcode -//! -//! You can see that logging goes through @c AsmJit::Assembler. If you are -//! using @c AsmJit::Compiler and you want to log messages in correct assembler -//! order, you should look at @c AsmJit::Compiler::comment() method. It allows -//! you to insert text message into @c AsmJit::Emittable list and -//! @c AsmJit::Compiler will send your message to @c AsmJit::Assembler in -//! correct order. -//! -//! @sa @c AsmJit::Logger, @c AsmJit::FileLogger. - - -//! @defgroup AsmJit_Serializer Serializer - code generation intrinsics. -//! -//! Serializer implements assembler intrinsics that's used by @c Assembler -//! and @c Compiler classes. Intrinsics are implemented as overloaded methods -//! of @c AsmJit::Serializer class. This section also contains all assembler -//! primitives used to generate machine code. -//! -//! Registers -//! -//! There are static objects that represents X86 and X64 registers. They can -//! be used directly (like @c eax, @c mm, @c xmm, ...) or created through -//! these functions: -//! -//! - @c AsmJit::mk_gpb() - make general purpose byte register -//! - @c AsmJit::mk_gpw() - make general purpose word register -//! - @c AsmJit::mk_gpd() - make general purpose dword register -//! - @c AsmJit::mk_gpq() - make general purpose qword register -//! - @c AsmJit::mk_mm() - make mmx register -//! - @c AsmJit::mk_xmm() - make sse register -//! - @c AsmJit::st() - make x87 register -//! -//! Addressing -//! -//! X86 and x64 architectures contains several addressing modes and most ones -//! are possible with AsmJit library. Memory represents are represented by -//! @c AsmJit::Mem class. These functions are used to make operands that -//! represents memory addresses: -//! -//! - @c AsmJit::ptr() -//! - @c AsmJit::byte_ptr() -//! - @c AsmJit::word_ptr() -//! - @c AsmJit::dword_ptr() -//! - @c AsmJit::qword_ptr() -//! - @c AsmJit::tword_ptr() -//! - @c AsmJit::dqword_ptr() -//! - @c AsmJit::mmword_ptr() -//! - @c AsmJit::xmmword_ptr() -//! - @c AsmJit::sysint_ptr() -//! -//! Most useful function to make pointer should be @c AsmJit::ptr(). It creates -//! pointer to the target with unspecified size. Unspecified size works in all -//! intrinsics where are used registers (this means that size is specified by -//! register operand or by instruction itself). For example @c AsmJit::ptr() -//! can't be used with @c AsmJit::Serializer::inc() instruction. In this case -//! size must be specified and it's also reason to make difference between -//! pointer sizes. -//! -//! Supported are simple address forms (register + displacement) and complex -//! address forms (register + (register << shift) + displacement). -//! -//! Immediates -//! -//! Immediate values are constants thats passed directly after instruction -//! opcode. To create such value use @c AsmJit::imm() or @c AsmJit::uimm() -//! methods to create signed or unsigned immediate value. -//! -//! @sa @c AsmJit::Serializer. - - -//! @defgroup AsmJit_Util Utilities - Utilities and helper classes. -//! -//! Contains some helper classes that's used by AsmJit library. - - -//! @defgroup AsmJit_MemoryManagement Virtual memory management. -//! -//! Using @c AsmJit::Assembler or @c AsmJit::Compiler to generate machine -//! code is not final step. Each generated code needs to run in memory -//! that is not protected against code execution. To alloc this code it's -//! needed to use operating system functions provided to enable execution -//! code in specified memory block or to allocate memory that is not -//! protected. The solution is always to use @c See AsmJit::Assembler::make() -//! and @c AsmJit::Compiler::make() functions that can allocate memory and -//! relocate code for you. But AsmJit also contains classes for manual memory -//! management thats internally used by AsmJit but can be used by programmers -//! too. -//! -//! Memory management contains low level and high level classes related to -//! allocating and freeing virtual memory. Low level class is -//! @c AsmJit::VirtualMemory that can allocate and free full pages of -//! virtual memory provided by operating system. Higher level class is -//! @c AsmJit::MemoryManager that is able to manage complete allocation and -//! free mechanism. It internally uses larger chunks of memory to make -//! allocation fast and effective. -//! -//! Using @c AsmJit::VirtualMemory::alloc() is crossplatform way how to -//! allocate this kind of memory without worrying about operating system -//! and it's API. Each memory block that is no longer needed should be -//! freed by @c AsmJit::VirtualMemory::free() method. If you want better -//! comfort and malloc()/free() interface, look at the -//! @c AsmJit::MemoryManager class. -//! -//! @sa @c AsmJit::VirtualMemory, @ AsmJit::MemoryManager. - - -//! @addtogroup AsmJit_Config -//! @{ - -//! @def ASMJIT_WINDOWS -//! @brief Macro that is declared if AsmJit is compiled for Windows. - -//! @def ASMJIT_POSIX -//! @brief Macro that is declared if AsmJit is compiled for unix like -//! operating system. - -//! @def ASMJIT_API -//! @brief Attribute that's added to classes that can be exported if AsmJit -//! is compiled as a dll library. - -//! @def ASMJIT_MALLOC -//! @brief Function to call to allocate dynamic memory. - -//! @def ASMJIT_REALLOC -//! @brief Function to call to reallocate dynamic memory. - -//! @def ASMJIT_FREE -//! @brief Function to call to free dynamic memory. - -//! @def ASMJIT_CRASH -//! @brief Code that is execute if an one or more operands are invalid. - -//! @def ASMJIT_ASSERT -//! @brief Assertion macro. Default implementation calls @c ASMJIT_CRASH -//! if assert fails. - -//! @} - - -//! @namespace AsmJit -//! @brief Main AsmJit library namespace. -//! -//! There are not other namespaces used in AsmJit library. - - -// [Includes] -#include "Build.h" -#include "Assembler.h" -#include "Compiler.h" -#include "CpuInfo.h" -#include "Defs.h" -#include "Logger.h" -#include "MemoryManager.h" -#include "Serializer.h" -#include "Util.h" -#include "VirtualMemory.h" - - -// [Guard] -#endif // _ASMJIT_H diff --git a/src/thirdparty/dyndetours/AsmJit/Assembler.h b/src/thirdparty/dyndetours/AsmJit/Assembler.h deleted file mode 100644 index bd72f3182..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Assembler.h +++ /dev/null @@ -1,43 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_ASSEMBLER_H -#define _ASMJIT_ASSEMBLER_H - -// [Dependencies] -#include "Build.h" - -// ============================================================================ -// [Platform Specific] -// ============================================================================ - -// [X86 / X64] -#if defined(ASMJIT_X86) || defined(ASMJIT_X64) -#include "AssemblerX86X64.h" -#endif // ASMJIT_X86 || ASMJIT_X64 - -// [Guard] -#endif // _ASMJIT_ASSEMBLER_H diff --git a/src/thirdparty/dyndetours/AsmJit/AssemblerX86X64.h b/src/thirdparty/dyndetours/AsmJit/AssemblerX86X64.h deleted file mode 100644 index 85f901784..000000000 --- a/src/thirdparty/dyndetours/AsmJit/AssemblerX86X64.h +++ /dev/null @@ -1,755 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_ASSEMBLERX86X64_H -#define _ASMJIT_ASSEMBLERX86X64_H - -#if !defined(_ASMJIT_ASSEMBLER_H) -#warning "AsmJit/AssemblerX86X64 can be only included by AsmJit/Assembler.h" -#endif // _ASMJIT_ASSEMBLER_H - -// [Dependencies] -#include "Build.h" -#include "Serializer.h" -#include "Util.h" - -// [Warnings-Push] -#include "WarningsPush.h" - -// [AsmJit::] -namespace AsmJit { - -//! @addtogroup AsmJit_Assembler -//! @{ - -//! @brief Assembler - low level code generation. -//! -//! @c Assembler is the main class in AsmJit for generating low level x86/x64 -//! binary. It creates internal buffer, where opcodes are stored and contains -//! methods that mimics x86/x64 assembler instructions. Because -//! @c AsmJit::Assembler is based on @c AsmJit::Serializer it supports also -//! type checking by C++ compiler. It's nearly impossible to create invalid -//! instruction (for example mov [eax], [eax]). -//! -//! Each call to assembler intrinsics directly emits instruction to internal -//! binary stream. Instruction emitting also contains runtime checks so it's -//! impossible to create instruction that is not valid. -//! -//! @c AsmJit::Assembler contains internal buffer where all emitted -//! instructions are stored. Look at @c AsmJit::Buffer for buffer -//! implementation. To generate and allocate memory for function use -//! @c AsmJit::Assembler::make() method that will allocate memory using -//! provided memory manager ( see @c AsmJit::MemoryManager::global() ) and -//! relocates code to provided address. If you want to create your function -//! manually, you should look at @c AsmJit::VirtualMemory and use -//! @c AsmJit::Assembler::relocCode() method to relocate emitted code into -//! provided memory location. You can also take emitted buffer by @c take() -//! method to do something else with it. If you take buffer, you must free it -//! manually by @c ASMJIT_FREE() macro. -//! -//! Code Generation -//! -//! To generate code is only needed to create instance of @c AsmJit::Assembler -//! and to use intrinsics. See example how to do that: -//! -//! @code -//! // Use AsmJit namespace -//! using namespace AsmJit; -//! -//! // Create Assembler instance -//! Assembler a; -//! -//! // Prolog -//! a.push(ebp); -//! a.mov(ebp, esp); -//! -//! // Mov 1024 to EAX, EAX is also return value. -//! a.mov(eax, imm(1024)); -//! -//! // Epilog -//! a.mov(esp, ebp); -//! a.pop(ebp); -//! a.ret(); -//! @endcode -//! -//! You can see that syntax is very close to Intel one. Only difference is that -//! you are calling functions that emits the binary code for you. All registers -//! are in @c AsmJit namespace, so it's very comfortable to use it (look at -//! first line). There is also used method @c AsmJit::imm() to create immediate -//! value. Use @c AsmJit::uimm() to create unsigned immediate value. -//! -//! There is also possibility for use memory addresses and immediates. To build -//! memory address use @c ptr(), @c byte_ptr(), @c word_ptr(), @c dword_ptr() -//! and similar methods. In most cases you needs only @c ptr() method, but -//! there are instructions where you must specify address size. -//! -//! for example (a is @c AsmJit::Assembler instance): -//! -//! @code -//! a.mov(ptr(eax), imm(0)); // mov ptr [eax], 0 -//! a.mov(ptr(eax), edx); // mov ptr [eax], edx -//! @endcode -//! -//! But it's also possible to create complex addresses: -//! -//! @code -//! // eax + ecx*x addresses -//! a.mov(ptr(eax, ecx, TIMES_1), imm(0)); // mov ptr [eax + ecx], 0 -//! a.mov(ptr(eax, ecx, TIMES_2), imm(0)); // mov ptr [eax + ecx * 2], 0 -//! a.mov(ptr(eax, ecx, TIMES_4), imm(0)); // mov ptr [eax + ecx * 4], 0 -//! a.mov(ptr(eax, ecx, TIMES_8), imm(0)); // mov ptr [eax + ecx * 8], 0 -//! // eax + ecx*x + disp addresses -//! a.mov(ptr(eax, ecx, TIMES_1, 4), imm(0)); // mov ptr [eax + ecx + 4], 0 -//! a.mov(ptr(eax, ecx, TIMES_2, 8), imm(0)); // mov ptr [eax + ecx * 2 + 8], 0 -//! a.mov(ptr(eax, ecx, TIMES_4, 12), imm(0)); // mov ptr [eax + ecx * 4 + 12], 0 -//! a.mov(ptr(eax, ecx, TIMES_8, 16), imm(0)); // mov ptr [eax + ecx * 8 + 16], 0 -//! @endcode -//! -//! All addresses shown are using @c AsmJit::ptr() to make memory operand. -//! Some assembler instructions (single operand ones) needs to specify memory -//! operand size. For example calling a.inc(ptr(eax)) can't be -//! used. @c AsmJit::Assembler::inc(), @c AsmJit::Assembler::dec() and similar -//! instructions can't be serialized without specifying how bytes they are -//! operating on. See next code how assembler works: -//! -//! @code -//! // [byte] address -//! a.inc(byte_ptr(eax)); // inc byte ptr [eax] -//! a.dec(byte_ptr(eax)); // dec byte ptr [eax] -//! // [word] address -//! a.inc(word_ptr(eax)); // inc word ptr [eax] -//! a.dec(word_ptr(eax)); // dec word ptr [eax] -//! // [dword] address -//! a.inc(dword_ptr(eax)); // inc dword ptr [eax] -//! a.dec(dword_ptr(eax)); // dec dword ptr [eax] -//! @endcode -//! -//! Calling Code -//! -//! While you are over from emitting instructions, you can make your function -//! using @c AsmJit::Assembler::make() method. This method will use memory -//! manager to allocate virtual memory and relocates generated code to it. For -//! memory allocation is used global memory manager by default and memory is -//! freeable, but of course this default behavior can be overriden specifying -//! your memory manager and allocation type. If you want to do with code -//! something else you can always override make() method and do what you want. -//! -//! You can get size of generated code by @c codeSize() or @c offset() methods. -//! These methods returns you code size (or more precisely current code offset) -//! in bytes. Use takeCode() to take internal buffer (all pointers in -//! @c AsmJit::Assembler instance will be zeroed and current buffer returned) -//! to use it. If you don't take it, @c AsmJit::Assembler destructor will -//! free it automatically. To alloc and run code manually don't use -//! @c malloc()'ed memory, but instead use @c AsmJit::VirtualMemory::alloc() -//! to get memory for executing (specify @c canExecute to @c true) or -//! @c AsmJit::MemoryManager that provides more effective and comfortable way -//! to allocate virtual memory. -//! -//! See next example how to allocate memory where you can execute code created -//! by @c AsmJit::Assembler: -//! -//! @code -//! using namespace AsmJit; -//! -//! Assembler a; -//! -//! // ... your code generation -//! -//! // your function prototype -//! typedef void (*MyFn)(); -//! -//! // make your function -//! MyFn fn = function_cast(a.make()); -//! -//! // call your function -//! fn(); -//! -//! // If you don't need your function again, free it. -//! MemoryManager::global()->free(fn); -//! @endcode -//! -//! There is also low level alternative how to allocate virtual memory and -//! relocate code to it: -//! -//! @code -//! using namespace AsmJit; -//! -//! Assembler a; -//! -//! // ... your code generation -//! -//! // your function prototype -//! typedef void (*MyFn)(); -//! -//! // alloc memory for your function -//! MyFn fn = function_cast( -//! MemoryManager::global()->alloc(a.codeSize()); -//! -//! // relocate code (will make the function) -//! a.relocCode(fn); -//! -//! // call your function -//! fn(); -//! -//! // If you don't need your function again, free it. -//! MemoryManager::global()->free(fn); -//! @endcode -//! -//! @c note This was very primitive example how to call generated code. -//! In real production code you will never alloc and free code for one run, -//! you will usually use generated code many times. -//! -//! Using labels -//! -//! While generating assembler code, you will usually need to create complex -//! code with labels. Labels are fully supported and you can call @c jmp or -//! @c je (and similar) instructions to initialized or yet uninitialized label. -//! Each label expects to be bound into offset. To bind label to specific -//! offset, use @c bind() method. -//! -//! See next example that contains complete code that creates simple memory -//! copy function (in DWORD entities). -//! -//! @code -//! // Example: Usage of Label (32 bit code) -//! // -//! // Create simple DWORD memory copy function: -//! // ASMJIT_STDCALL void copy32(UInt32* dst, const UInt32* src, sysuint_t count); -//! using namespace AsmJit; -//! -//! // Assembler instance -//! Assembler a; -//! -//! // Constants -//! const int arg_offset = 8; // Arguments offset (STDCALL EBP) -//! const int arg_size = 12; // Arguments size -//! -//! // Labels -//! Label L_Loop; -//! -//! // Prolog -//! a.push(ebp); -//! a.mov(ebp, esp); -//! a.push(esi); -//! a.push(edi); -//! -//! // Fetch arguments -//! a.mov(esi, dword_ptr(ebp, arg_offset + 0)); // get dst -//! a.mov(edi, dword_ptr(ebp, arg_offset + 4)); // get src -//! a.mov(ecx, dword_ptr(ebp, arg_offset + 8)); // get count -//! -//! // Bind L_Loop label to here -//! a.bind(&L_Loop); -//! -//! Copy 4 bytes -//! a.mov(eax, dword_ptr(esi)); -//! a.mov(dword_ptr(edi), eax); -//! -//! // Increment pointers -//! a.add(esi, 4); -//! a.add(edi, 4); -//! -//! // Repeat loop until ecx != 0 -//! a.dec(ecx); -//! a.jz(&L_Loop); -//! -//! // Epilog -//! a.pop(edi); -//! a.pop(esi); -//! a.mov(esp, ebp); -//! a.pop(ebp); -//! -//! // Return: STDCALL convention is to pop stack in called function -//! a.ret(arg_size); -//! @endcode -//! -//! If you need more abstraction for generating assembler code and you want -//! to hide calling conventions between 32 bit and 64 bit operating systems, -//! look at @c Compiler class that is designed for higher level code -//! generation. -//! -//! @sa @c Compiler. -struct ASMJIT_API Assembler : public Serializer -{ - // ------------------------------------------------------------------------- - // [Structures] - // ------------------------------------------------------------------------- - - //! @brief Data structure used to link linked-labels. - struct LinkData - { - //! @brief Previous link. - LinkData* prev; - //! @brief Offset. - SysInt offset; - //! @brief Inlined displacement. - SysInt displacement; - //! @brief RelocId if link must be absolute when relocated. - SysInt relocId; - }; - - // 32 bit x86 architecture uses absolute addressing model in memory operands - // while 64 bit mode uses relative addressing model (RIP + displacement). In - // code we are always using relative addressing model for referencing labels - // and embedded data. In 32 bit mode we must patch all references to absolute - // address before we can call generated function. We are patching only memory - // operands. - - //! @brief Reloc to absolute address data - struct RelocData - { - enum Type - { - ABSOLUTE_TO_ABSOLUTE = 0, - RELATIVE_TO_ABSOLUTE = 1, - ABSOLUTE_TO_RELATIVE = 2, - ABSOLUTE_TO_RELATIVE_TRAMPOLINE = 3 - }; - - //! @brief Type of relocation. - UInt32 type; - - //! @brief Size of relocation (4 or 8 bytes). - UInt32 size; - - //! @brief Offset from code begin address. - SysInt offset; - - //! @brief Relative displacement or absolute address. - union - { - //! @brief Relative displacement from code begin address (not to @c offset). - SysInt destination; - //! @brief Absolute address where to jump; - void* address; - }; - }; - - // ------------------------------------------------------------------------- - // [Construction / Destruction] - // ------------------------------------------------------------------------- - - //! @brief Creates Assembler instance. - Assembler() ASMJIT_NOTHROW; - //! @brief Destroys Assembler instance - virtual ~Assembler() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Buffer Getters / Setters] - // ------------------------------------------------------------------------- - - //! @brief Return start of assembler code buffer. - //! - //! Note that buffer address can change if you emit instruction or something - //! else. Use this pointer only when you finished or make sure you do not - //! use returned pointer after emitting. - inline UInt8* code() const ASMJIT_NOTHROW - { return _buffer.data(); } - - //! @brief Ensure space for next instruction. - //! - //! Note that this method can return false. It's rare and probably you never - //! get this, but in some situations it's still possible. - inline bool ensureSpace() ASMJIT_NOTHROW - { return _buffer.ensureSpace(); } - - //! @brief Return current offset in buffer). - inline SysInt offset() const ASMJIT_NOTHROW - { return _buffer.offset(); } - - //! @brief Return current offset in buffer (same as offset() + tramplineSize()). - inline SysInt codeSize() const ASMJIT_NOTHROW - { return _buffer.offset() + trampolineSize(); } - - //! @brief Return size of all possible trampolines needed to successfuly generate - //! relative jumps to absolute addresses. This value is only non-zero if jmp - //! of call instructions were used with immediate operand (this means jump or - //! call absolute address directly). - //! - //! Currently only _emitJmpOrCallReloc() method can increase trampoline size - //! value. - inline SysInt trampolineSize() const ASMJIT_NOTHROW - { return _trampolineSize; } - - //! @brief Sets offset to @a o and returns previous offset. - //! - //! This method can be used to truncate code (previous offset is not - //! recorded) or to overwrite instruction stream at position @a o. - //! - //! @return Previous offset value that can be uset to set offset back later. - inline SysInt toOffset(SysInt o) ASMJIT_NOTHROW - { return _buffer.toOffset(o); } - - //! @brief Return capacity of internal code buffer. - inline SysInt capacity() const ASMJIT_NOTHROW - { return _buffer.capacity(); } - - //! @brief Reallocate internal buffer. - //! - //! It's only used for growing, buffer is never reallocated to smaller - //! number than current capacity() is. - bool realloc(SysInt to) ASMJIT_NOTHROW; - - //! @brief Used to grow the buffer. - //! - //! It will typically realloc to twice size of capacity(), but if capacity() - //! is large, it will use smaller steps. - bool grow() ASMJIT_NOTHROW; - - //! @brief Clear everything, but not deallocate buffers. - void clear() ASMJIT_NOTHROW; - - //! @brief Free internal buffer and NULL all pointers. - void free() ASMJIT_NOTHROW; - - //! @brief Return internal buffer and NULL all pointers. - UInt8* takeCode() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Stream Setters / Getters] - // ------------------------------------------------------------------------- - - //! @brief Set byte at position @a pos. - inline UInt8 getByteAt(SysInt pos) const ASMJIT_NOTHROW - { return _buffer.getByteAt(pos); } - - //! @brief Set word at position @a pos. - inline UInt16 getWordAt(SysInt pos) const ASMJIT_NOTHROW - { return _buffer.getWordAt(pos); } - - //! @brief Set word at position @a pos. - inline UInt32 getDWordAt(SysInt pos) const ASMJIT_NOTHROW - { return _buffer.getDWordAt(pos); } - - //! @brief Set word at position @a pos. - inline UInt64 getQWordAt(SysInt pos) const ASMJIT_NOTHROW - { return _buffer.getQWordAt(pos); } - - //! @brief Set byte at position @a pos. - inline void setByteAt(SysInt pos, UInt8 x) ASMJIT_NOTHROW - { _buffer.setByteAt(pos, x); } - - //! @brief Set word at position @a pos. - inline void setWordAt(SysInt pos, UInt16 x) ASMJIT_NOTHROW - { _buffer.setWordAt(pos, x); } - - //! @brief Set word at position @a pos. - inline void setDWordAt(SysInt pos, UInt32 x) ASMJIT_NOTHROW - { _buffer.setDWordAt(pos, x); } - - //! @brief Set word at position @a pos. - inline void setQWordAt(SysInt pos, UInt64 x) ASMJIT_NOTHROW - { _buffer.setQWordAt(pos, x); } - - //! @brief Set word at position @a pos. - inline Int32 getInt32At(SysInt pos) const ASMJIT_NOTHROW - { return (Int32)_buffer.getDWordAt(pos); } - - //! @brief Set int32 at position @a pos. - inline void setInt32At(SysInt pos, Int32 x) ASMJIT_NOTHROW - { _buffer.setDWordAt(pos, (Int32)x); } - - //! @brief Set custom variable @a imm at position @a pos. - //! - //! @note This function is used to patch existing code. - void setVarAt(SysInt pos, SysInt i, UInt8 isUnsigned, UInt32 size) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Assembler Emitters] - // - // These emitters are not protecting buffer from overrun, this must be - // done is _emitX86() methods by: - // if (!canEmit()) return; - // ------------------------------------------------------------------------- - - //! @brief Return @c true if next instruction can be emitted. - //! - //! This function behaves like @c ensureSpace(), but it also checks if - //! assembler is in error state and in that case returns @c false. - //! Assembler must internally always use this function. - //! - //! It's implemented like: - //! return ensureSpace() && !error(); - bool canEmit() ASMJIT_NOTHROW; - - //! @brief Emit Byte to internal buffer. - inline void _emitByte(UInt8 x) ASMJIT_NOTHROW - { _buffer.emitByte(x); } - - //! @brief Emit Word (2 bytes) to internal buffer. - inline void _emitWord(UInt16 x) ASMJIT_NOTHROW - { _buffer.emitWord(x); } - - //! @brief Emit DWord (4 bytes) to internal buffer. - inline void _emitDWord(UInt32 x) ASMJIT_NOTHROW - { _buffer.emitDWord(x); } - - //! @brief Emit QWord (8 bytes) to internal buffer. - inline void _emitQWord(UInt64 x) ASMJIT_NOTHROW - { _buffer.emitQWord(x); } - - //! @brief Emit Int32 (4 bytes) to internal buffer. - inline void _emitInt32(Int32 x) ASMJIT_NOTHROW - { _buffer.emitDWord((UInt32)x); } - - //! @brief Emit system signed integer (4 or 8 bytes) to internal buffer. - inline void _emitSysInt(SysInt x) ASMJIT_NOTHROW - { _buffer.emitSysInt(x); } - - //! @brief Emit system unsigned integer (4 or 8 bytes) to internal buffer. - inline void _emitSysUInt(SysUInt x) ASMJIT_NOTHROW - { _buffer.emitSysUInt(x); } - - //! @brief Emit immediate value of specified @a size. - void _emitImmediate(const Immediate& imm, UInt32 size) ASMJIT_NOTHROW; - - //! @brief Emit single @a opCode without operands. - inline void _emitOpCode(UInt32 opCode) ASMJIT_NOTHROW - { - // instruction prefix - if (opCode & 0xFF000000) _emitByte((UInt8)((opCode & 0xFF000000) >> 24)); - // instruction opcodes - if (opCode & 0x00FF0000) _emitByte((UInt8)((opCode & 0x00FF0000) >> 16)); - if (opCode & 0x0000FF00) _emitByte((UInt8)((opCode & 0x0000FF00) >> 8)); - // last opcode is always emitted (can be also 0x00) - _emitByte((UInt8)(opCode & 0x000000FF)); - } - - //! @brief Emit CS (code segmend) prefix. - //! - //! Behavior of this function is to emit code prefix only if memory operand - //! address uses code segment. Code segment is used through memory operand - //! with attached @c AsmJit::Label. - void _emitSegmentPrefix(const Operand& rm) ASMJIT_NOTHROW; - - //! @brief Emit MODR/M byte. - //! @internal - inline void _emitMod(UInt8 m, UInt8 o, UInt8 r) ASMJIT_NOTHROW - { _emitByte(((m & 0x03) << 6) | ((o & 0x07) << 3) | (r & 0x07)); } - - //! @brief Emit SIB byte. - inline void _emitSib(UInt8 s, UInt8 i, UInt8 b) ASMJIT_NOTHROW - { _emitByte(((s & 0x03) << 6) | ((i & 0x07) << 3) | (b & 0x07)); } - - //! @brief Emit REX prefix (64 bit mode only). - inline void _emitRexR(UInt8 w, UInt8 opReg, UInt8 regCode) ASMJIT_NOTHROW - { -#if defined(ASMJIT_X64) - UInt8 r = (opReg & 0x8) != 0; - UInt8 b = (regCode & 0x8) != 0; - - // w Default operand size(0=Default, 1=64 bits). - // r Register field (1=high bit extension of the ModR/M REG field). - // x Index field not used in RexR - // b Base field (1=high bit extension of the ModR/M or SIB Base field). - if (w || r || b || (_properties & (1 << PROPERTY_X86_FORCE_REX))) - { - _emitByte(0x40 | (w << 3) | (r << 2) | b); - } -#else - ASMJIT_USE(w); - ASMJIT_USE(opReg); - ASMJIT_USE(regCode); -#endif // ASMJIT_X64 - } - - //! @brief Emit REX prefix (64 bit mode only). - inline void _emitRexRM(UInt8 w, UInt8 opReg, const Operand& rm) ASMJIT_NOTHROW - { -#if defined(ASMJIT_X64) - UInt8 r = (opReg & 0x8) != 0; - UInt8 x = 0; - UInt8 b = 0; - - if (rm.isReg()) - { - b = (reinterpret_cast(rm).code() & 0x8) != 0; - } - else if (rm.isMem()) - { - x = ((reinterpret_cast(rm).index() & 0x8) != 0) & (reinterpret_cast(rm).index() != NO_REG); - b = ((reinterpret_cast(rm).base() & 0x8) != 0) & (reinterpret_cast(rm).base() != NO_REG); - } - - // w Default operand size(0=Default, 1=64 bits). - // r Register field (1=high bit extension of the ModR/M REG field). - // x Index field (1=high bit extension of the SIB Index field). - // b Base field (1=high bit extension of the ModR/M or SIB Base field). - if (w || r || x || b || (_properties & (1 << PROPERTY_X86_FORCE_REX))) - { - _emitByte(0x40 | (w << 3) | (r << 2) | (x << 1) | b); - } -#else - ASMJIT_USE(w); - ASMJIT_USE(opReg); - ASMJIT_USE(rm); -#endif // ASMJIT_X64 - } - - //! @brief Emit Register / Register - calls _emitMod(3, opReg, r) - inline void _emitModR(UInt8 opReg, UInt8 r) ASMJIT_NOTHROW - { _emitMod(3, opReg, r); } - - //! @brief Emit Register / Register - calls _emitMod(3, opReg, r.code()) - inline void _emitModR(UInt8 opReg, const BaseReg& r) ASMJIT_NOTHROW - { _emitMod(3, opReg, r.code()); } - - //! @brief Emit register / memory address combination to buffer. - //! - //! This method can hangle addresses from simple to complex ones with - //! index and displacement. - void _emitModM(UInt8 opReg, const Mem& mem, SysInt immSize) ASMJIT_NOTHROW; - - //! @brief Emit Reg<-Reg or Reg<-Reg|Mem ModRM (can be followed by SIB - //! and displacement) to buffer. - //! - //! This function internally calls @c _emitModM() or _emitModR() that depends - //! to @a op type. - //! - //! @note @a opReg is usually real register ID (see @c R) but some instructions - //! have specific format and in that cases @a opReg is part of opcode. - void _emitModRM(UInt8 opReg, const Operand& op, SysInt immSize) ASMJIT_NOTHROW; - - //! @brief Emit instruction where register is inlined to opcode. - void _emitX86Inl(UInt32 opCode, UInt8 i16bit, UInt8 rexw, UInt8 reg) ASMJIT_NOTHROW; - - //! @brief Emit instruction with reg/memory operand. - void _emitX86RM(UInt32 opCode, UInt8 i16bit, UInt8 rexw, UInt8 o, - const Operand& op, SysInt immSize) ASMJIT_NOTHROW; - - //! @brief Emit FPU instruction with no operands. - void _emitFpu(UInt32 opCode) ASMJIT_NOTHROW; - - //! @brief Emit FPU instruction with one operand @a sti (index of FPU register). - void _emitFpuSTI(UInt32 opCode, UInt32 sti) ASMJIT_NOTHROW; - - //! @brief Emit FPU instruction with one operand @a opReg and memory operand @a mem. - void _emitFpuMEM(UInt32 opCode, UInt8 opReg, const Mem& mem) ASMJIT_NOTHROW; - - //! @brief Emit MMX/SSE instruction. - void _emitMmu(UInt32 opCode, UInt8 rexw, UInt8 opReg, const Operand& src, - SysInt immSize) ASMJIT_NOTHROW; - - //! @brief Emit displacement. - LinkData* _emitDisplacement(Label* label, SysInt inlinedDisplacement, int size) ASMJIT_NOTHROW; - - //! @brief Emit relative relocation to absolute pointer @a target. It's needed - //! to add what instruction is emitting this, because in x64 mode the relative - //! displacement can be impossible to calculate and in this case the trampoline - //! is used. - void _emitJmpOrCallReloc(UInt32 instruction, void* target) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Relocation helpers] - // ------------------------------------------------------------------------- - - //! @brief Relocate code to a given address @a dst. - //! - //! A given buffer will be overwritten, to get number of bytes required use - //! @c codeSize() or @c offset() methods. - virtual void relocCode(void* dst) const ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [EmitX86] - // ------------------------------------------------------------------------- - - virtual void _inlineComment(const char* text, SysInt len = -1) ASMJIT_NOTHROW; - virtual void _emitX86(UInt32 code, const Operand* o1, const Operand* o2, const Operand* o3) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Embed] - // ------------------------------------------------------------------------- - - virtual void _embed(const void* dataPtr, SysUInt dataLen) ASMJIT_NOTHROW; - virtual void _embedLabel(Label* label) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Align] - // ------------------------------------------------------------------------- - - virtual void align(SysInt m) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Labels] - // ------------------------------------------------------------------------- - - //! @brief Create and return new @a Label managed by assembler. - //! - //! Note that if you create labels by this way they are not checked like - //! Labels statically allocated on the stack!. - Label* newLabel() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Bind] - // ------------------------------------------------------------------------- - - virtual void bind(Label* label) ASMJIT_NOTHROW; - - //! @brief Bind label to pos - called from bind(Label* label). - void bindTo(Label* label, SysInt pos) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Make] - // ------------------------------------------------------------------------- - - virtual void* make(MemoryManager* memoryManager = NULL, UInt32 allocType = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Links] - // ------------------------------------------------------------------------- - - LinkData* _newLinkData() ASMJIT_NOTHROW; - void _freeLinkData(LinkData* link) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Members] - // ------------------------------------------------------------------------- - - //! @brief Binary code buffer. - Buffer _buffer; - - //! @brief Size of possible trampolines. - SysInt _trampolineSize; - - //! @brief Linked list of unused links (@c LinkData* structures) - LinkData* _unusedLinks; - - //! @brief Relocations data. - PodVector _relocData; - - //! @brief Buffer for inline comment (for next instruction). - char _inlineCommentBuffer[MAX_INLINE_COMMENT_SIZE]; -}; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_ASSEMBLERX86X64_H diff --git a/src/thirdparty/dyndetours/AsmJit/Build.h b/src/thirdparty/dyndetours/AsmJit/Build.h deleted file mode 100644 index 2d48b23bd..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Build.h +++ /dev/null @@ -1,228 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_BUILD_H -#define _ASMJIT_BUILD_H - -// [Include] -#include "Config.h" - -// Here should be optional include files that's needed fo successfuly -// use macros defined here. Remember, AsmJit uses only AsmJit namespace -// and all macros are used within it. So for example crash handler is -// not called as AsmJit::crash(0) in ASMJIT_CRASH() macro, but simply -// as crash(0). -#include -#include - -// [AsmJit - OS] -#if defined(WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64) -# define ASMJIT_WINDOWS -#elif defined(__linux__) || defined(__unix__) || \ - defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__DragonFly__) || defined(__BSD__) || defined(__FREEBSD__) || \ - defined(__APPLE__) -# define ASMJIT_POSIX -#else -# warning "AsmJit - Can't match operating system, using ASMJIT_POSIX" -# define ASMJIT_POSIX -#endif - -// [AsmJit - Architecture] -// define it only if it's not defined. In some systems we can -// use -D command in compiler to bypass this autodetection. -#if !defined(ASMJIT_X86) && !defined(ASMJIT_X64) -# if defined(__x86_64__) || defined(__LP64) || defined(__IA64__) || \ - defined(_M_X64) || defined(_WIN64) -# define ASMJIT_X64 // x86-64 -# else -// _M_IX86, __INTEL__, __i386__ -# define ASMJIT_X86 -# endif -#endif - -// [AsmJit - API] - -// Hide AsmJit symbols that we don't want to export (SerializerIntrinsics class for example). -#if !defined(ASMJIT_HIDDEN) -# if defined(__GNUC__) && __GNUC__ >= 4 -# define ASMJIT_HIDDEN __attribute__((visibility("hidden"))) -# endif // __GNUC__ -#endif // ASMJIT_HIDDEN - -// Make AsmJit as shared library by default. -#if !defined(ASMJIT_API) -# if defined(ASMJIT_WINDOWS) -# if defined(__GNUC__) -# if defined(AsmJit_EXPORTS) -# define ASMJIT_API __attribute__((dllexport)) -# else -# define ASMJIT_API __attribute__((dllimport)) -# endif -# else -# if defined(AsmJit_EXPORTS) -# define ASMJIT_API __declspec(dllexport) -# else -# define ASMJIT_API __declspec(dllimport) -# endif -# endif -# else -# if defined(__GNUC__) -# if __GNUC__ >= 4 -# define ASMJIT_API __attribute__((visibility("default"))) -# endif -# endif -# endif -#endif // ASMJIT_API - -// If not detected, fallback to nothing -#if !defined(ASMJIT_HIDDEN) -# define ASMJIT_HIDDEN -#endif // ASMJIT_HIDDEN - -#if !defined(ASMJIT_API) -# define ASMJIT_API -#endif // ASMJIT_API - -#if !defined(ASMJIT_NOTHROW) -#define ASMJIT_NOTHROW throw() -#endif // ASMJIT_NOTHROW - -// [AsmJit - Memory Management] -#if !defined(ASMJIT_MALLOC) -# define ASMJIT_MALLOC ::malloc -#endif // ASMJIT_MALLOC - -#if !defined(ASMJIT_REALLOC) -# define ASMJIT_REALLOC ::realloc -#endif // ASMJIT_REALLOC - -#if !defined(ASMJIT_FREE) -# define ASMJIT_FREE ::free -#endif // ASMJIT_FREE - -// [AsmJit - Crash handler] -namespace AsmJit -{ - static void crash(int* ptr = 0) { *ptr = 0; } -} - -// [AsmJit - Calling Conventions] -#if defined(ASMJIT_X86) -# if defined(__GNUC__) -# define ASMJIT_FASTCALL_2 __attribute__((regparm(2))) -# define ASMJIT_FASTCALL_3 __attribute__((regparm(3))) -# define ASMJIT_STDCALL __attribute__((stdcall)) -# define ASMJIT_CDECL __attribute__((cdecl)) -# else -# define ASMJIT_FASTCALL_2 __fastcall -# define ASMJIT_STDCALL __stdcall -# define ASMJIT_CDECL __cdecl -# endif -#else -# define ASMJIT_FASTCALL_2 -# define ASMJIT_STDCALL -# define ASMJIT_CDECL -#endif // ASMJIT_X86 - -#if !defined(ASMJIT_USE) -# define ASMJIT_USE(var) ((void)var) -#endif // ASMJIT_USE - -#if !defined(ASMJIT_NOP) -# define ASMJIT_NOP() ((void)0) -#endif // ASMJIT_NOP - -// [AsmJit - Types] -namespace AsmJit -{ - typedef char Int8; - typedef unsigned char UInt8; - typedef short Int16; - typedef unsigned short UInt16; - typedef int Int32; - typedef unsigned int UInt32; - -#if defined(_MSC_VER) - typedef __int64 Int64; - typedef unsigned __int64 UInt64; -#else // GCC, other compilers ? - typedef long long Int64; - typedef unsigned long long UInt64; -#endif - -#if defined(ASMJIT_X86) - typedef Int32 SysInt; - typedef UInt32 SysUInt; -#else - typedef Int64 SysInt; - typedef UInt64 SysUInt; -#endif -} - -#if defined(_MSC_VER) -# define ASMJIT_INT64_C(num) num##i64 -# define ASMJIT_UINT64_C(num) num##ui64 -#else -# define ASMJIT_INT64_C(num) num##LL -# define ASMJIT_UINT64_C(num) num##ULL -#endif - -// [AsmJit - C++ Macros] -#define ASMJIT_ARRAY_SIZE(A) (sizeof(A) / sizeof(*A)) - -#define ASMJIT_DISABLE_COPY(__type__) \ -private: \ - inline __type__(const __type__& other); \ - inline __type__& operator=(const __type__& other) - -// [AsmJit - Debug] -#if defined(DEBUG) || defined(_DEBUG) -# if !defined(ASMJIT_CRASH) -# define ASMJIT_CRASH() crash() -# endif -# if !defined(ASMJIT_ASSERT) -# define ASMJIT_ASSERT(exp) do { if (!(exp)) ASMJIT_CRASH(); } while(0) -# endif -#else -# if !defined(ASMJIT_CRASH) -# define ASMJIT_CRASH() ASMJIT_NOP() -# endif -# if !defined(ASMJIT_ASSERT) -# define ASMJIT_ASSERT(exp) ASMJIT_NOP() -# endif -#endif // DEBUG - -// GCC warnings fix: I can't understand why GCC hasn't interface to push/pop -// warning -// #if defined(__GNUC__) -// # if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 402001 -// # pragma GCC diagnostic ignored "-w" -// # endif -// #endif // __GNUC__ - -// [Guard] -#endif // _ASMJIT_BUILD_H diff --git a/src/thirdparty/dyndetours/AsmJit/Compiler.h b/src/thirdparty/dyndetours/AsmJit/Compiler.h deleted file mode 100644 index 7ba7a798e..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Compiler.h +++ /dev/null @@ -1,194 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_COMPILER_H -#define _ASMJIT_COMPILER_H - -// [Dependencies] -#include "Build.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_Compiler -//! @{ - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -struct Comment; -struct Compiler; -struct Emittable; -struct Epilog; -struct Function; -struct Instruction; -struct Prolog; -struct State; -struct Variable; - -// ============================================================================ -// [Constants] -// ============================================================================ - -//! @brief Emmitable type. -//! -//! For each emittable that is used by @c Compiler must be defined it's type. -//! Compiler can optimize instruction stream by analyzing emittables and each -//! type is hint for it. The most used emittables are instructions -//! (@c EMITTABLE_INSTRUCTION). -enum EMITTABLE_TYPE -{ - //! @brief Emittable is invalid (can't be used). - EMITTABLE_NONE = 0, - //! @brief Emittable is comment (no code). - EMITTABLE_COMMENT, - //! @brief Emittable is embedded data. - EMITTABLE_EMBEDDED_DATA, - //! @brief Emittable is .align directive. - EMITTABLE_ALIGN, - //! @brief Emittable is single instruction. - EMITTABLE_INSTRUCTION, - //! @brief Emittable is block of instructions. - EMITTABLE_BLOCK, - //! @brief Emittable is function declaration. - EMITTABLE_FUNCTION, - //! @brief Emittable is function prolog. - EMITTABLE_PROLOGUE, - //! @brief Emittable is function epilog. - EMITTABLE_EPILOGUE, - //! @brief Emittable is target (bound label). - EMITTABLE_TARGET, - //! @brief Emittable is jump table. - EMITTABLE_JUMP_TABLE -}; - -//! @brief State of variable. -//! -//! Variable state can be retrieved by @c AsmJit::VariableRef::state(). -enum VARIABLE_STATE -{ - //! @brief Variable is currently not used. - //! - //! Variables of this state are not used or they are currently not - //! initialized (short time after @c AsmJit::VariableRef::alloc() call). - VARIABLE_STATE_UNUSED = 0, - - //! @brief Variable is in register. - //! - //! Variable is currently allocated in register. - VARIABLE_STATE_REGISTER = 1, - - //! @brief Variable is in memory location or spilled. - //! - //! Variable was spilled from register to memory or variable is used for - //! memory only storage. - VARIABLE_STATE_MEMORY = 2 -}; - -//! @brief Variable alloc mode. -//! @internal -enum VARIABLE_ALLOC -{ - //! @brief Allocating variable to read only. - //! - //! Read only variables are used to optimize variable spilling. If variable - //! is some time ago deallocated and it's not marked as changed (so it was - //! all the life time read only) then spill is simply NOP (no mov instruction - //! is generated to move it to it's home memory location). - VARIABLE_ALLOC_READ = 0x1, - - //! @brief Allocating variable to write only (overwrite). - //! - //! Overwriting means that if variable is in memory, there is no generated - //! instruction to move variable from memory to register, because that - //! register will be overwritten by next instruction. This is used as a - //! simple optimization to improve generated code by @c Compiler. - VARIABLE_ALLOC_WRITE = 0x2, - - //! @brief Allocating variable to read / write. - //! - //! Variable allocated for read / write is marked as changed. This means that - //! if variable must be later spilled into memory, mov (or similar) - //! instruction will be generated. - VARIABLE_ALLOC_READWRITE = 0x3 -}; - -//! @brief Variable allocation method. -//! -//! Variable allocation method is used by compiler and it means if compiler -//! should first allocate preserved registers or not. Preserved registers are -//! registers that must be saved / restored by generated function. -//! -//! This option is for people who are calling C/C++ functions from JIT code so -//! Compiler can recude generating push/pop sequences before and after call, -//! respectively. -enum ALLOC_POLICY -{ - //! @brief Allocate preserved registers first. - ALLOC_POLICY_PRESERVED_FIRST, - //! @brief Allocate preserved registers last (default). - ALLOC_POLICY_PRESERVED_LAST -}; - -//! @brief Arguments direction used by @c Function. -enum ARGUMENT_DIR -{ - //! @brief Arguments are passed left to right. - //! - //! This arguments direction is unusual to C programming, it's used by pascal - //! compilers and in some calling conventions by Borland compiler). - ARGUMENT_DIR_LEFT_TO_RIGHT = 0, - //! @brief Arguments are passer right ro left - //! - //! This is default argument direction in C programming. - ARGUMENT_DIR_RIGHT_TO_LEFT = 1 -}; - -//! @brief Anonymous constants used by @c Compiler. -enum { - //! @brief Maximum length of variable name. - MAX_VARIABLE_LENGTH = 32 -}; - -//! @} - -} // AsmJit namespace. - -// ============================================================================ -// [Platform Specific] -// -// Following enums must be declared by platform specific header: -// - CALL_CONV - Calling convention. -// - VARIABLE_TYPE - Variable type. -// ============================================================================ - -// [X86 / X64] -#if defined(ASMJIT_X86) || defined(ASMJIT_X64) -#include "CompilerX86X64.h" -#endif // ASMJIT_X86 || ASMJIT_X64 - -// [Guard] -#endif // _ASMJIT_COMPILER_H diff --git a/src/thirdparty/dyndetours/AsmJit/CompilerX86X64.h b/src/thirdparty/dyndetours/AsmJit/CompilerX86X64.h deleted file mode 100644 index 5f565aab5..000000000 --- a/src/thirdparty/dyndetours/AsmJit/CompilerX86X64.h +++ /dev/null @@ -1,3174 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_COMPILERX86X64_H -#define _ASMJIT_COMPILERX86X64_H - -#if !defined(_ASMJIT_COMPILER_H) -#warning "AsmJit/CompilerX86X64 can be only included by AsmJit/Compiler.h" -#endif // _ASMJIT_COMPILER_H - -// [Dependencies] -#include "Build.h" -#include "Assembler.h" -#include "Serializer.h" -#include "Util.h" - -#include - -// A little bit C++. -#include - -// [Warnings-Push] -#include "WarningsPush.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_Compiler -//! @{ - -// ============================================================================ -// [Constants] -// ============================================================================ - -//! @brief Calling convention type. -//! -//! Calling convention is scheme how function arguments are passed into -//! function and how functions returns values. In assembler programming -//! it's needed to always comply with function calling conventions, because -//! even small inconsistency can cause undefined behavior or crash. -//! -//! List of calling conventions for 32 bit x86 mode: -//! - @c CALL_CONV_CDECL - Calling convention for C runtime. -//! - @c CALL_CONV_STDCALL - Calling convention for WinAPI functions. -//! - @c CALL_CONV_MSTHISCALL - Calling convention for C++ members under -//! Windows (produced by MSVC and all MSVC compatible compilers). -//! - @c CALL_CONV_MSFASTCALL - Fastest calling convention that can be used -//! by MSVC compiler. -//! - @c CALL_CONV_BORNANDFASTCALL - Borland fastcall convention. -//! - @c CALL_CONV_GCCFASTCALL_2 - GCC fastcall convention with 2 register -//! arguments. -//! - @c CALL_CONV_GCCFASTCALL_3 - GCC fastcall convention with 3 register -//! arguments. -//! -//! List of calling conventions for 64 bit x86 mode (x64): -//! - @c CALL_CONV_X64W - Windows 64 bit calling convention (WIN64 ABI). -//! - @c CALL_CONV_X64U - Unix 64 bit calling convention (AMD64 ABI). -//! -//! There is also @c CALL_CONV_DEFAULT that is defined to fit best to your -//! compiler. -//! -//! These types are used together with @c AsmJit::Compiler::newFunction() -//! method. -enum CALL_CONV -{ - //! @brief Calling convention is invalid (can't be used). - CALL_CONV_NONE = 0, - - // [X64 Calling Conventions] - - //! @brief X64 calling convention for Windows platform. - //! - //! For first four arguments are used these registers: - //! - 1. 32/64 bit integer or floating point argument - rcx/xmm0 - //! - 2. 32/64 bit integer or floating point argument - rdx/xmm1 - //! - 3. 32/64 bit integer or floating point argument - r8/xmm2 - //! - 4. 32/64 bit integer or floating point argument - r9/xmm3 - //! - //! Note first four arguments here means arguments at positions from 1 to 4 - //! (included). For example if second argument is not passed by register then - //! rdx/xmm1 register is unused. - //! - //! All other arguments are pushed on the stack in right-to-left direction. - //! Stack is aligned by 16 bytes. There is 32 bytes shadow space on the stack - //! that can be used to save up to four 64 bit registers (probably designed to - //! be used to save first four arguments passed in registers). - //! - //! Arguments direction: - //! - Right to Left (except for first 4 parameters that's in registers) - //! - //! Stack is cleaned by: - //! - Caller. - //! - //! Return value: - //! - Integer types - RAX register. - //! - Floating points - XMM0 register. - //! - //! Stack is always aligned by 16 bytes. - //! - //! More informations about this calling convention can be found on MSDN: - //! http://msdn.microsoft.com/en-us/library/9b372w95.aspx . - CALL_CONV_X64W = 1, - - //! @brief X64 calling convention for Unix platforms (AMD64 ABI). - //! - //! First six 32 or 64 bit integer arguments are passed in rdi, rsi, rdx, - //! rcx, r8, r9 registers. First eight floating point or XMM arguments - //! are passed in xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 registers. - //! This means that in registers can be transferred up to 14 arguments total. - //! - //! There is also RED ZONE below the stack pointer that can be used for - //! temporary storage. The red zone is the space from [rsp-128] to [rsp-8]. - //! - //! Arguments direction: - //! - Right to Left (Except for arguments passed in registers). - //! - //! Stack is cleaned by: - //! - Caller. - //! - //! Return value: - //! - Integer types - RAX register. - //! - Floating points - XMM0 register. - //! - //! Stack is always aligned by 16 bytes. - CALL_CONV_X64U = 2, - - // [X86 Calling Conventions] - - //! @brief Cdecl calling convention (used by C runtime). - //! - //! Compatible across MSVC and GCC. - //! - //! Arguments direction: - //! - Right to Left - //! - //! Stack is cleaned by: - //! - Caller. - CALL_CONV_CDECL = 3, - - //! @brief Stdcall calling convention (used by WinAPI). - //! - //! Compatible across MSVC and GCC. - //! - //! Arguments direction: - //! - Right to Left - //! - //! Stack is cleaned by: - //! - Callee. - //! - //! Return value: - //! - Integer types - EAX:EDX registers. - //! - Floating points - st(0) register. - CALL_CONV_STDCALL = 4, - - //! @brief MSVC specific calling convention used by MSVC/Intel compilers - //! for struct/class methods. - //! - //! This is MSVC (and Intel) only calling convention used in Windows - //! world for C++ class methods. Implicit 'this' pointer is stored in - //! ECX register instead of storing it on the stack. - //! - //! Arguments direction: - //! - Right to Left (except this pointer in ECX) - //! - //! Stack is cleaned by: - //! - Callee. - //! - //! Return value: - //! - Integer types - EAX:EDX registers. - //! - Floating points - st(0) register. - //! - //! C++ class methods that have variable count of arguments uses different - //! calling convention called cdecl. - //! - //! @note This calling convention is always used by MSVC for class methods, - //! it's implicit and there is no way how to override it. - CALL_CONV_MSTHISCALL = 5, - - //! @brief MSVC specific fastcall. - //! - //! Two first parameters (evaluated from left-to-right) are in ECX:EDX - //! registers, all others on the stack in right-to-left order. - //! - //! Arguments direction: - //! - Right to Left (except to first two integer arguments in ECX:EDX) - //! - //! Stack is cleaned by: - //! - Callee. - //! - //! Return value: - //! - Integer types - EAX:EDX registers. - //! - Floating points - st(0) register. - //! - //! @note This calling convention differs to GCC one in stack cleaning - //! mechanism. - CALL_CONV_MSFASTCALL = 6, - - //! @brief Borland specific fastcall with 2 parameters in registers. - //! - //! Two first parameters (evaluated from left-to-right) are in ECX:EDX - //! registers, all others on the stack in left-to-right order. - //! - //! Arguments direction: - //! - Left to Right (except to first two integer arguments in ECX:EDX) - //! - //! Stack is cleaned by: - //! - Callee. - //! - //! Return value: - //! - Integer types - EAX:EDX registers. - //! - Floating points - st(0) register. - //! - //! @note Arguments on the stack are in left-to-right order that differs - //! to other fastcall conventions used in different compilers. - CALL_CONV_BORLANDFASTCALL = 7, - - //! @brief GCC specific fastcall with 2 parameters in registers. - //! - //! Two first parameters (evaluated from left-to-right) are in ECX:EDX - //! registers, all others on the stack in right-to-left order. - //! - //! Arguments direction: - //! - Right to Left (except to first two integer arguments in ECX:EDX) - //! - //! Stack is cleaned by: - //! - Caller. - //! - //! Return value: - //! - Integer types - EAX:EDX registers. - //! - Floating points - st(0) register. - //! - //! @note This calling convention differs to MSVC one in stack cleaning - //! mechanism. - CALL_CONV_GCCFASTCALL_2 = 8, - - //! @brief GCC specific fastcall with 3 parameters in registers. - //! - //! Three first parameters (evaluated from left-to-right) are in - //! ECX:EDX:EAX registers, all others on the stack in right-to-left order. - //! - //! Arguments direction: - //! - Right to Left (except to first three integer arguments in ECX:EDX:EAX) - //! - //! Stack is cleaned by: - //! - Caller. - //! - //! Return value: - //! - Integer types - EAX:EDX registers. - //! - Floating points - st(0) register. - CALL_CONV_GCCFASTCALL_3 = 9, - - // [Preferred Calling Convention] - - //! @def CALL_CONV_DEFAULT - //! @brief Default calling convention for current platform / operating - //! system. - -#if defined(ASMJIT_X86) - CALL_CONV_DEFAULT = CALL_CONV_CDECL -#else -# if defined(WIN32) || defined(_WIN32) || defined(WINDOWS) - CALL_CONV_DEFAULT = CALL_CONV_X64W -# else - CALL_CONV_DEFAULT = CALL_CONV_X64U -# endif -#endif // ASMJIT_X86 -}; - -//! @brief Variable type. -//! -//! Variable type is used by @c AsmJit::Function::newVariable() method and can -//! be also retrieved by @c AsmJit::VariableRef::type(). -enum VARIABLE_TYPE -{ - //! @brief Invalid variable type (don't use). - VARIABLE_TYPE_NONE = 0, - - //! @brief Variable is 32 bit integer (@c Int32). - VARIABLE_TYPE_INT32 = 1, - //! @brief Variable is 32 bit unsigned integer (@c UInt32). - VARIABLE_TYPE_UINT32 = 1, - - //! @var VARIABLE_TYPE_INT64 - //! @brief Variable is 64 bit signed integer (@c Int64). - //! @note Can be used only in 64 bit mode. - - //! @var VARIABLE_TYPE_UINT64 - //! @brief Variable is 64 bit unsigned integer (@c UInt64). - //! @note Can be used only in 64 bit mode. - - //! @var VARIABLE_TYPE_SYSINT - //! @brief Variable is system wide integer (@c Int32 or @c Int64). - //! @var VARIABLE_TYPE_SYSUINT - //! @brief Variable is system wide unsigned integer (@c UInt32 or @c UInt64). -#if defined(ASMJIT_X86) - VARIABLE_TYPE_SYSINT = VARIABLE_TYPE_INT32, - VARIABLE_TYPE_SYSUINT = VARIABLE_TYPE_UINT32, -#else - VARIABLE_TYPE_INT64 = 2, - VARIABLE_TYPE_UINT64 = 2, - VARIABLE_TYPE_SYSINT = VARIABLE_TYPE_INT64, - VARIABLE_TYPE_SYSUINT = VARIABLE_TYPE_UINT64, -#endif - - //! @brief Variable is pointer or reference to memory (or any type). - VARIABLE_TYPE_PTR = VARIABLE_TYPE_SYSUINT, - - //! @brief Variable is X87 (FPU) SP-FP number (float). - //! - //! TODO: Float registers allocation is not supported. - VARIABLE_TYPE_X87_FLOAT = 3, - - //! @brief Variable is X87 (FPU) DP-FP number (double). - //! - //! TODO: Double registers allocation is not supported. - VARIABLE_TYPE_X87_DOUBLE = 4, - - //! @brief Variable is SSE scalar SP-FP number. - VARIABLE_TYPE_XMM_FLOAT = 5, - - //! @brief Variable is SSE2 scalar DP-FP number. - VARIABLE_TYPE_XMM_DOUBLE = 6, - - //! @brief Variable is SSE packed SP-FP number (4 floats). - VARIABLE_TYPE_XMM_FLOAT_4 = 7, - //! @brief Variable is SSE2 packed DP-FP number (2 doubles). - VARIABLE_TYPE_XMM_DOUBLE_2 = 8, - -#if defined(ASMJIT_X86) - VARIABLE_TYPE_FLOAT = VARIABLE_TYPE_X87_FLOAT, - VARIABLE_TYPE_DOUBLE = VARIABLE_TYPE_X87_DOUBLE, -#else - VARIABLE_TYPE_FLOAT = VARIABLE_TYPE_XMM_FLOAT, - VARIABLE_TYPE_DOUBLE = VARIABLE_TYPE_XMM_DOUBLE, -#endif - - //! @brief Variable is MM register / memory location. - VARIABLE_TYPE_MM = 9, - - //! @brief Variable is XMM register / memory location. - VARIABLE_TYPE_XMM = 10, - - //! @brief Count of variable types. - _VARIABLE_TYPE_COUNT -}; - -// ============================================================================ -// [AsmJit::Variable] -// ============================================================================ - -//! @brief Variable. -//! -//! Variables reresents registers or memory locations that can be allocated by -//! @c Function. Each function arguments are also allocated as variables, so -//! accessing function arguments is similar to accessing function variables. -//! -//! Variables can be declared by @c AsmJit::Function::newVariable() or by -//! declaring function arguments by AsmJit::Compiler::newFunction(). Compiler -//! always returns variables as pointers to @c Variable instance. -//! -//! Variable instances are never accessed directly, instead there are wrappers. -//! Wrappers are designed to simplify variables management and it's lifetime. -//! Because variables are based on reference counting, each variable that is -//! returned from @c Compiler needs to be wrapped in @c VariableRef or similar -//! (@c Int32Ref, @c Int64Ref, @c SysIntRef, @c PtrRef, @c MMRef, @c XMMRef) -//! classes. Each wrapper class is designed to wrap specific variable type. For -//! example integer should be always wrapped into @c Int32Ref or @c Int64Ref, -//! MMX register to @c MMRef, etc... -//! -//! Variable wrapping is also needed, because it's lifetime is based on -//! reference counting. Each variable returned from compiler has reference -//! count equal to zero! So wrapper class increases it to one (or more that -//! depends how much you wrapped it) and destroying wrapper means decreasing -//! reference count. If reference count is decreased to zero, variable life -//! ends, it's marked as unused and compiler can reuse it later. -//! -//! @sa @c VariableRef, @c Int32Ref, @c Int64Ref, @c SysIntRef, @c PtrRef, -//! @c MMRef, @c XMMRef. -struct ASMJIT_API Variable -{ - // [Typedefs] - - //! @brief Custom alloc function type. - typedef void (*AllocFn)(Variable* v); - //! @brief Custom spill function type. - typedef void (*SpillFn)(Variable* v); - - // [Construction / Destruction] - - //! @brief Create a new @a Variable instance. - //! - //! Always use @c AsmJit::Function::newVariable() method to create - //! @c Variable. - Variable(Compiler* c, Function* f, UInt8 type); - //! @brief Destroy variable instance. - //! - //! Never destroy @c Variable instance created by @c Compiler. - virtual ~Variable(); - - // [Methods] - - //! @brief Return compiler that owns this variable. - inline Compiler* compiler() const ASMJIT_NOTHROW - { return _compiler; } - - //! @brief Return function that owns this variable. - inline Function* function() const ASMJIT_NOTHROW - { return _function; } - - //! @brief Return reference count. - inline SysUInt refCount() const ASMJIT_NOTHROW - { return _refCount; } - - //! @brief Return spill count. - inline SysUInt spillCount() const ASMJIT_NOTHROW - { return _spillCount; } - - //! @brief Return life id. - inline SysUInt lifeId() const ASMJIT_NOTHROW - { return _lifeId; } - - //! @brief Return register access statistics. - inline SysUInt registerAccessCount() const ASMJIT_NOTHROW - { return _registerAccessCount; } - - //! @brief Return memory access statistics. - inline SysUInt memoryAccessCount() const ASMJIT_NOTHROW - { return _memoryAccessCount; } - - //! @brief Return variable type, see @c VARIABLE_TYPE. - inline UInt8 type() const ASMJIT_NOTHROW - { return _type; } - - //! @brief Return variable size (in bytes). - inline UInt8 size() const ASMJIT_NOTHROW - { return _size; } - - //! @brief Return variable state, see @c VARIABLE_STATE. - inline UInt8 state() const ASMJIT_NOTHROW - { return _state; } - - //! @brief Return variable priority. - //! - //! Variable priority is used for spilling. Lower number means less chance - //! to spill. Zero means that variable can't be never spilled. - inline UInt8 priority() const ASMJIT_NOTHROW - { return _priority; } - - //! @brief Return variable register code (where it now lives), or NO_REG if - //! it's only in memory (spilled). - inline UInt8 registerCode() const ASMJIT_NOTHROW - { return _registerCode; } - - //! @brief Return variable preferred register. - inline UInt8 preferredRegisterCode() const ASMJIT_NOTHROW - { return _preferredRegisterCode; } - - //! @brief Return variable home register code (this is usually last - //! allocated register code). - inline UInt8 homeRegisterCode() const ASMJIT_NOTHROW - { return _homeRegisterCode; } - - //! @brief Return variable changed state. - inline UInt8 changed() const ASMJIT_NOTHROW - { return _changed; } - - //! @brief Return whether variable is reusable. - inline UInt8 reusable() const ASMJIT_NOTHROW - { return _reusable; } - - //! @brief Return whether variable contains custom memory home address. - inline UInt8 customMemoryHome() const ASMJIT_NOTHROW - { return _customMemoryHome; } - - //! @brief Return whether variable contains custom memory home address. - inline UInt8 stackArgument() const ASMJIT_NOTHROW - { return _stackArgument; } - - //! @brief Return variable stack offset. - //! - //! @note Stack offsets can be changed by Compiler, don't use this - //! to generate memory operands. - inline SysInt stackOffset() const ASMJIT_NOTHROW - { return _stackOffset; } - - //! @brief Set variable priority. - void setPriority(UInt8 priority); - - //! @brief Set varialbe preferred register. - inline void setPreferredRegisterCode(UInt8 code) ASMJIT_NOTHROW - { _preferredRegisterCode = code; } - - //! @brief Set variable changed state. - inline void setChanged(UInt8 changed) ASMJIT_NOTHROW - { _changed = changed; } - - //! @brief Memory operand that will be always pointed to variable memory address. */ - inline const Mem& memoryOperand() const ASMJIT_NOTHROW - { return *_memoryOperand; } - - void setMemoryHome(const Mem& memoryHome) ASMJIT_NOTHROW; - - // [Reference counting] - - //! @brief Increase reference count and return itself. - Variable* ref(); - - //! @brief Decrease reference count. If reference is decreased to zero, - //! variable is marked as unused and deallocated. - void deref(); - - // [Code Generation] - - //! @brief Allocate variable to register. - //! @param mode Allocation mode (see @c VARIABLE_ALLOC enum) - //! @param preferredRegister Preferred register to use (see @c AsmJit::REG enum). - inline bool alloc( - UInt8 mode = VARIABLE_ALLOC_READWRITE, - UInt8 preferredRegister = NO_REG); - - //! @brief Allocate variable to register and return it in @a dest. - //! - //! This function is similar to @c alloc(), but setups @a dest register. It's - //! convenience method for @c AsmJit::VariableRef register accesses. - void getReg( - UInt8 mode, UInt8 preferredRegister, - BaseReg* dest, UInt8 regType); - - const Mem& m(); - - //! @brief Spill variable (move to memory). - inline bool spill(); - - //! @brief Unuse variable - //! - //! This will completely destroy variable. After @c unuse() you can use - //! @c alloc() to allocate it again. - inline void unuse(); - - // [Custom Spill / Restore] - - //! @brief Return @c true if this variable uses custom alloc or spill - //! functions (this means bypassing built-in functions). - //! - //! @note If alloc or spill function is set, variable is marked as custom - //! and there is no chance to move it to / from stack. For example mmx zero - //! register can be implemented in allocFn() that will emit pxor(mm, mm). - //! Variable will never spill into stack in this case. - inline bool isCustom() const ASMJIT_NOTHROW - { return _allocFn != NULL || _spillFn != NULL; } - - //! @brief Get custom alloc function. - inline AllocFn allocFn() const ASMJIT_NOTHROW - { return _allocFn; } - - //! @brief Get custom spill function. - inline SpillFn spillFn() const ASMJIT_NOTHROW - { return _spillFn; } - - //! @brief Get custom data pointer. - inline void* dataPtr() const ASMJIT_NOTHROW - { return _dataPtr; } - - //! @brief Get custom data pointer. - inline SysInt dataInt() const ASMJIT_NOTHROW - { return _dataInt; } - - //! @brief Set custom alloc function. - inline void setAllocFn(AllocFn fn) ASMJIT_NOTHROW - { _allocFn = fn; } - - //! @brief Set custom spill function. - inline void setSpillFn(SpillFn fn) ASMJIT_NOTHROW - { _spillFn = fn; } - - //! @brief Set custom data pointer. - inline void setDataPtr(void* data) ASMJIT_NOTHROW - { _dataPtr = data; } - - //! @brief Set custom data integer. - inline void setDataInt(SysInt data) ASMJIT_NOTHROW - { _dataInt = data; } - - //! @brief Get variable name. - inline const char* name() const ASMJIT_NOTHROW - { return _name; } - - //! @brief Set variable name. - void setName(const char* name) ASMJIT_NOTHROW; - -private: - //! @brief Set variable stack offset. - //! @internal - inline void setStackOffset(SysInt stackOffset) ASMJIT_NOTHROW - { _stackOffset = stackOffset; } - - //! @brief Set most members by one shot. - inline void setAll( - UInt8 type, UInt8 size, UInt8 state, UInt8 priority, - UInt8 registerCode, UInt8 preferredRegisterCode, - SysInt stackOffset) ASMJIT_NOTHROW - { - _type = type; - _size = size; - _state = state; - _priority = priority; - _registerCode = registerCode; - _preferredRegisterCode = preferredRegisterCode; - _stackOffset = stackOffset; - } - - //! @brief Compiler that owns this variable. - Compiler* _compiler; - //! @brief Function that owns this variable. - Function* _function; - - //! @brief Reference count. - SysUInt _refCount; - - //! @brief How many times was variable spilled (in current context). - SysUInt _spillCount; - //! @brief Register access count (in current context). - SysUInt _registerAccessCount; - //! @brief Memory access count (in current context). - SysUInt _memoryAccessCount; - - //! @brief Current variable life ID (also means how many times was variable reused). - SysUInt _lifeId; - - //! @brief How many times was variable spilled (in current context). - SysUInt _globalSpillCount; - //! @brief Register access count (in current context). - SysUInt _globalRegisterAccessCount; - //! @brief Memory access count (in current context). - SysUInt _globalMemoryAccessCount; - - //! @brief Variable type, see @c VARIABLE_TYPE. - UInt8 _type; - - //! @brief Variable size (in bytes). - UInt8 _size; - - //! @brief Variable state, see @c VARIABLE_STATE. - UInt8 _state; - - //! @brief Variable priority. - UInt8 _priority; - - //! @brief Register code if variable state is @c VARIABLE_STATE_REGISTER. - UInt8 _registerCode; - - //! @brief Default register where to alloc variable. - UInt8 _preferredRegisterCode; - - //! @brief Last allocated register code. - UInt8 _homeRegisterCode; - - //! @brief true if variable in register was changed and when spilling it - //! needs to be copied into memory location. - UInt8 _changed; - - //! @brief Whether variable can be reused. - UInt8 _reusable; - - //! @brief Whether variable contains custom home address. - UInt8 _customMemoryHome; - - //! @brief Whether variable is function argument passed onto the stack. - UInt8 _stackArgument; - - //! @brief Stack location. - SysInt _stackOffset; - - //! @brief Variable memory operand. - Mem* _memoryOperand; - - //! @brief Custom alloc function (or NULL). - AllocFn _allocFn; - - //! @brief Custom spill function (or NULL). - SpillFn _spillFn; - - //! @brief Custom void* data that can be used by custom spill and restore functions. - void* _dataPtr; - - //! @brief Custom integer that can be used by custom spill and restore functions. - SysInt _dataInt; - - //! @brief Variable name. - char _name[MAX_VARIABLE_LENGTH]; - - friend struct CompilerCore; - friend struct Function; - friend struct VariableRef; - - // Disable copy. - ASMJIT_DISABLE_COPY(Variable); -}; - -// ============================================================================ -// [AsmJit::XXXRef] -// ============================================================================ - -//! @brief Base class for variable wrappers. -//! -//! @c VariableRef class is designed to manage @c Variable instances. It's -//! based on reference counting and if reference gets to zero (in destructor), -//! variable is freed by compiler. This helps with scoping variables and -//! minimizes mistakes that can be done with manual allocation / freeing. -//! -//! @note Compiler can reuse existing variables if reference gets zero. -//! -//! @sa @c Variable, -//! @c Int32Ref, @c Int64Ref, @c SysIntRef, @c PtrRef, @c MMRef, @c XMMRef. -struct ASMJIT_HIDDEN VariableRef -{ - // [Typedefs] - - typedef Variable::AllocFn AllocFn; - typedef Variable::SpillFn SpillFn; - - // [Construction / Destruction] - - //! @brief Create new uninitialized variable reference. - //! - //! Using uninitialized variable reference is forbidden. - inline VariableRef() : _v(NULL) {} - - //! @brief Reference variable @a v (@a v can't be @c NULL). - inline VariableRef(Variable* v) : _v(v->ref()) {} - - //! @brief Dereference variable if it's wrapped. - inline ~VariableRef() { if (_v) _v->deref(); } - - inline VariableRef& operator=(Variable* v) - { - use(v); return *this; - } - - //! @brief Return @c Variable instance. - inline Variable* v() const { return _v; } - - // [Methods] - - //! @brief Return variable type, see @c VARIABLE_TYPE. - inline UInt8 type() const { ASMJIT_ASSERT(_v); return _v->type(); } - //! @brief Return variable size (in bytes). - inline UInt8 size() const { ASMJIT_ASSERT(_v); return _v->size(); } - //! @brief Return variable state, see @c VARIABLE_STATE. - inline UInt8 state() const { ASMJIT_ASSERT(_v); return _v->state(); } - - void use(Variable* v) - { - Variable* tmp = v->ref(); - if (_v) _v->deref(); - _v = tmp; - } - - //! @brief Allocate variable to register. - //! @param mode Allocation mode (see @c VARIABLE_ALLOC enum) - //! @param preferredRegister Preferred register to use (see @c REG enum). - inline bool alloc( - UInt8 mode = VARIABLE_ALLOC_READWRITE, - UInt8 preferredRegister = NO_REG) - { - ASMJIT_ASSERT(_v); - return _v->alloc(mode, preferredRegister); - } - - //! @brief Spill variable (move to memory). - inline bool spill() - { - ASMJIT_ASSERT(_v); - return _v->spill(); - } - - //! @brief Unuse variable - //! - //! This will completely destroy variable. After @c unuse() you can use - //! @c alloc() to allocate it again. - inline void unuse() - { - if (_v) _v->unuse(); - } - - //! @brief Destroy variable (@c VariableRef can't be used anymore after destroy). - inline void destroy() - { - if (_v) - { - _v->deref(); - _v = NULL; - } - } - - //! @brief Get variable preferred register code. - inline UInt8 preferredRegisterCode() const - { ASMJIT_ASSERT(_v); return _v->preferredRegisterCode(); } - - //! @brief Set variable preferred register code to @a code. - //! @param code Preferred register code (see @c AsmJit::REG enum). - inline void setPreferredRegisterCode(UInt8 code) - { ASMJIT_ASSERT(_v); _v->setPreferredRegisterCode(code); } - - //! @brief Get variable home register code. - inline UInt8 homeRegisterCode() const - { ASMJIT_ASSERT(_v); return _v->homeRegisterCode(); } - - //! @brief Get variable priority. - inline UInt8 priority() const - { ASMJIT_ASSERT(_v); return _v->priority(); } - - //! @brief Set variable priority. - inline void setPriority(UInt8 priority) - { ASMJIT_ASSERT(_v); _v->setPriority(priority); } - - //! @brief Return if variable changed state. - inline UInt8 changed() const - { ASMJIT_ASSERT(_v); return _v->changed(); } - - //! @brief Set variable changed state. - inline void setChanged(UInt8 changed) - { ASMJIT_ASSERT(_v); _v->setChanged(changed); } - - //! @brief Return whether variable is reusable. - inline UInt8 reusable() const ASMJIT_NOTHROW - { ASMJIT_ASSERT(_v); return _v->reusable(); } - - //! @brief Return whether variable contains custom memory home address. - inline UInt8 customMemoryHome() const ASMJIT_NOTHROW - { ASMJIT_ASSERT(_v); return _v->customMemoryHome(); } - - inline void setMemoryHome(const Mem& memoryHome) ASMJIT_NOTHROW - { ASMJIT_ASSERT(_v); _v->setMemoryHome(memoryHome); } - - //! @brief Return memory address operand. - //! - //! @note Getting memory address operand will always call @c spill(). - inline const Mem& m() const - { ASMJIT_ASSERT(_v); return _v->m(); } - - // [Reference counting] - - //! @brief Increase reference count and return @c Variable instance. - inline Variable* ref() - { ASMJIT_ASSERT(_v); return _v->ref(); } - - // [Custom Spill / Restore] - - //! @brief Return @c true if variable uses custom alloc / spill functions. - //! - //! @sa @c AsmJit::Variable::isCustom() method. - inline bool isCustom() const { ASMJIT_ASSERT(_v); return _v->isCustom(); } - - //! @brief Get custom restore function. - inline AllocFn allocFn() const { ASMJIT_ASSERT(_v); return _v->allocFn(); } - //! @brief Get custom spill function. - inline SpillFn spillFn() const { ASMJIT_ASSERT(_v); return _v->spillFn(); } - //! @brief Get custom data pointer. - inline void* dataPtr() const { ASMJIT_ASSERT(_v); return _v->dataPtr(); } - //! @brief Get custom data pointer. - inline SysInt dataInt() const { ASMJIT_ASSERT(_v); return _v->dataInt(); } - - //! @brief Set custom restore function. - inline void setAllocFn(AllocFn fn) { ASMJIT_ASSERT(_v); _v->setAllocFn(fn); } - //! @brief Set custom spill function. - inline void setSpillFn(SpillFn fn) { ASMJIT_ASSERT(_v); _v->setSpillFn(fn); } - //! @brief Set custom data. - inline void setDataPtr(void* data) { ASMJIT_ASSERT(_v); _v->setDataPtr(data); } - //! @brief Set custom data. - inline void setDataInt(SysInt data) { ASMJIT_ASSERT(_v); _v->setDataInt(data); } - - inline const char* name() const { ASMJIT_ASSERT(_v); return _v->name(); } - inline void setName(const char* name) const { ASMJIT_ASSERT(_v); _v->setName(name); } - - inline bool operator==(const VariableRef& other) const { return _v == other._v; } - inline bool operator!=(const VariableRef& other) const { return _v != other._v; } - -protected: - void _assign(const VariableRef& other) - { - Variable* tmp = other._v ? other._v->ref() : NULL; - if (_v) _v->deref(); - _v = tmp; - } - - //! @brief @c Variable instance. - Variable* _v; - -private: - // Disable copy. - ASMJIT_DISABLE_COPY(VariableRef); -}; - -// Helper macro for VariableRef::... register access methods. -#define __REG_ACCESS(__regClass__, __allocType__, __preferredRegCode__, __regType__) \ - ASMJIT_ASSERT(_v); \ - __regClass__ result; \ - _v->getReg(__allocType__, __preferredRegCode__, (BaseReg*)&result, __regType__); \ - return result - -//! @brief 32 bit integer variable wrapper. -struct ASMJIT_HIDDEN Int32Ref : public VariableRef -{ - // [Construction / Destruction] - - inline Int32Ref() : VariableRef() {} - inline Int32Ref(const Int32Ref& other) : VariableRef(other._v) {} - inline Int32Ref(Variable* v) : VariableRef(v) {} - - inline Int32Ref& operator=(const Int32Ref& other) { _assign(other); return *this; } - - // [Registers] - - inline Register r (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPD); } - inline Register r8 (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPB); } - inline Register r16(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPW); } - inline Register r32(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPD); } -#if defined(ASMJIT_X64) - inline Register r64(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPQ); } -#endif // ASMJIT_X64 - - inline Register c (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPD); } - inline Register c8 (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPB); } - inline Register c16(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPW); } - inline Register c32(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPD); } -#if defined(ASMJIT_X64) - inline Register c64(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPQ); } -#endif // ASMJIT_X64 - - inline Register x (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPD); } - inline Register x8 (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPB); } - inline Register x16(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPW); } - inline Register x32(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPD); } -#if defined(ASMJIT_X64) - inline Register x64(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPQ); } -#endif // ASMJIT_X64 -}; - -#if defined(ASMJIT_X64) -//! @brief 64 bit integer variable wrapper. -struct ASMJIT_HIDDEN Int64Ref : public VariableRef -{ - // [Construction / Destruction] - - inline Int64Ref() : VariableRef() {} - inline Int64Ref(const Int64Ref& other) : VariableRef(other._v) {} - inline Int64Ref(Variable* v) : VariableRef(v) {} - - inline Int64Ref& operator=(const Int64Ref& other) { _assign(other); return *this; } - - // [Registers] - - inline Register r (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPQ); } - inline Register r8 (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPB); } - inline Register r16(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPW); } - inline Register r32(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPD); } - inline Register r64(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READWRITE, pref, REG_GPQ); } - - inline Register c (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPQ); } - inline Register c8 (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPB); } - inline Register c16(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPW); } - inline Register c32(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPD); } - inline Register c64(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_READ , pref, REG_GPQ); } - - inline Register x (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPQ); } - inline Register x8 (UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPB); } - inline Register x16(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPW); } - inline Register x32(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPD); } - inline Register x64(UInt8 pref = NO_REG) const { __REG_ACCESS(Register, VARIABLE_ALLOC_WRITE , pref, REG_GPQ); } -}; -#endif // ASMJIT_X64 - -//! @brief MMX variable wrapper. -struct ASMJIT_HIDDEN MMRef : public VariableRef -{ - // [Construction / Destruction] - - inline MMRef() : VariableRef() {} - inline MMRef(const MMRef& other) : VariableRef(other._v) {} - inline MMRef(Variable* v) : VariableRef(v) {} - - inline MMRef& operator=(const MMRef& other) { _assign(other); return *this; } - - // [Registers] - - inline MMRegister r(UInt8 pref = NO_REG) const { __REG_ACCESS(MMRegister, VARIABLE_ALLOC_READWRITE, pref, REG_MM); } - inline MMRegister c(UInt8 pref = NO_REG) const { __REG_ACCESS(MMRegister, VARIABLE_ALLOC_READ , pref, REG_MM); } - inline MMRegister x(UInt8 pref = NO_REG) const { __REG_ACCESS(MMRegister, VARIABLE_ALLOC_WRITE , pref, REG_MM); } -}; - -//! @brief SSE variable wrapper. -struct ASMJIT_HIDDEN XMMRef : public VariableRef -{ - // [Construction / Destruction] - - inline XMMRef() : VariableRef() {} - inline XMMRef(const XMMRef& other) : VariableRef(other._v) {} - inline XMMRef(Variable* v) : VariableRef(v) {} - - inline XMMRef& operator=(const XMMRef& other) { _assign(other); return *this; } - - // [Registers] - - inline XMMRegister r(UInt8 pref = NO_REG) const { __REG_ACCESS(XMMRegister, VARIABLE_ALLOC_READWRITE, pref, REG_XMM); } - inline XMMRegister c(UInt8 pref = NO_REG) const { __REG_ACCESS(XMMRegister, VARIABLE_ALLOC_READ , pref, REG_XMM); } - inline XMMRegister x(UInt8 pref = NO_REG) const { __REG_ACCESS(XMMRegister, VARIABLE_ALLOC_WRITE , pref, REG_XMM); } -}; - -#if defined(ASMJIT_X86) -typedef Int32Ref SysIntRef; -#else -typedef Int64Ref SysIntRef; -#endif - -//! @brief Pointer variable wrapper (same as system integer). -typedef SysIntRef PtrRef; - -// Cleanup -#undef __REG_ACCESS - -// ============================================================================ -// [AsmJit::State] -// ============================================================================ - -//! @brief Contains informations about current register state. -//! -//! @note Always use StateRef to manage register states and don't create State -//! directly. Instead use @c AsmJit::Function::saveState() and -//! @c AsmJit::Function::restoreState() methods. -//! -//! @sa StateRef -struct ASMJIT_API State -{ - // [Construction / Destruction] - - State(Compiler* c, Function* f); - virtual ~State(); - - //! @brief State entry (variable and some details about variable life cycle). - struct Entry - { - Variable* v; - UInt32 lifeId; - UInt8 state; - UInt8 changed; - }; - - //! @brief State data (allocated registers <-> variables). - struct Data - { - union - { - //! @brief All variables in one array. - Entry regs[16+8+16]; - - struct { - //! @brief Regeral purpose registers. - Entry gp[16]; - //! @brief MMX registers. - Entry mm[8]; - //! @brief XMM registers. - Entry xmm[16]; - }; - }; - - //! @brief used GP registers bitmask. - UInt32 usedGpRegisters; - //! @brief used MMX registers bitmask. - UInt32 usedMmRegisters; - //! @brief used XMM registers bitmask. - UInt32 usedXmmRegisters; - }; - - static void saveFunctionState(Data* dst, Function* f); - -private: - //! @brief Clear state. - void _clear(); - - //! @brief Save function state (there is no code generated when saving state). - void _save(); - //! @brief Restore function state, can spill and alloc registers. - void _restore(); - - //! @brief Set function state to current state. - //! - //! @note This method is similar to @c _restore(), but it will not alloc or - //! spill registers. - void _set(); - - //! @brief Compiler this state is related to. - Compiler* _compiler; - - //! @brief Function this state is related to. - Function* _function; - - //! @brief State data. - Data _data; - - friend struct CompilerCore; - friend struct Function; - friend struct StateRef; - - // Disable copy. - ASMJIT_DISABLE_COPY(State); -}; - -// ============================================================================ -// [AsmJit::StateRef] -// ============================================================================ - -//! @brief State wrapper used to manage @c State's. -struct ASMJIT_HIDDEN StateRef -{ - //! @brief Create StateRef instance from @a state (usually returned by - //! @c Compiler / @c Function). - inline StateRef(State* state) : - _state(state) - {} - - //! @brief Destroy StateRef instance. - inline ~StateRef(); - - //! @brief Return managed @c State instance. - inline State* state() const { return _state; } - - //! @brief Implicit cast to @c State. - inline operator State*() const { return _state; } - -private: - State* _state; - - // Disable copy. - ASMJIT_DISABLE_COPY(StateRef); -}; - -// ============================================================================ -// [AsmJit::Emittable] -// ============================================================================ - -//! @brief Emmitable. -//! -//! Emittable is object that can emit single or more instructions. To -//! create your custom emittable it's needed to override abstract virtual -//! method @c emit(). -//! -//! When you are finished serializing instructions to the @c Compiler and you -//! call @c Compiler::make(), it will first call @c prepare() method for each -//! emittable in list, then @c emit() and then @c postEmit(). Prepare can be -//! used to calculate something that can be only calculated when everything -//! is finished (for example @c Function uses @c prepare() to relocate memory -//! home for all memory/spilled variables). @c emit() should be used to emit -//! instruction or multiple instructions into @a Assembler stream, and -//! @c postEmit() is here to allow emitting embedded data (after function -//! declaration), etc. -struct ASMJIT_API Emittable -{ - // [Construction / Destruction] - - //! @brief Create new emittable. - //! - //! Never create @c Emittable by @c new operator or on the stack, use - //! @c Compiler::newObject template to do that. - Emittable(Compiler* c, UInt32 type) ASMJIT_NOTHROW; - - //! @brief Destroy emittable. - //! - //! @note Never destroy emittable using @c delete keyword, @c Compiler - //! manages all emittables in internal memory pool and it will destroy - //! all emittables after you destroy it. - virtual ~Emittable() ASMJIT_NOTHROW; - - // [Emit] - - //! @brief Prepare for emitting (optional). - virtual void prepare(); - //! @brief Emit instruction stream. - virtual void emit(Assembler& a) = 0; - //! @brief Post emit (optional). - virtual void postEmit(Assembler& a); - - // [Methods] - - //! @brief Return compiler instance where this emittable is connected to. - inline Compiler* compiler() const ASMJIT_NOTHROW { return _compiler; } - //! @brief Return previsou emittable in list. - inline Emittable* prev() const ASMJIT_NOTHROW { return _prev; } - //! @brief Return next emittable in list. - inline Emittable* next() const ASMJIT_NOTHROW { return _next; } - //! @brief Return emittable type, see @c EMITTABLE_TYPE. - inline UInt32 type() const ASMJIT_NOTHROW { return _type; } - - // [Members] - -protected: - //! @brief Compiler where this emittable is connected to. - Compiler* _compiler; - //! @brief Previous emittable. - Emittable* _prev; - //! @brief Next emittable. - Emittable* _next; - //! @brief Type of emittable, see @c EMITTABLE_TYPE. - UInt32 _type; - -private: - friend struct CompilerCore; - - // Disable copy. - ASMJIT_DISABLE_COPY(Emittable); -}; - -// ============================================================================ -// [AsmJit::Comment] -// ============================================================================ - -//! @brief Emittable used to emit comment into @c Assembler logger. -//! -//! Comments allows to comment your assembler stream for better debugging -//! and visualization whats happening. Comments are ignored if logger is not -//! set. -//! -//! Comment data can't be modified after comment was created. -struct ASMJIT_API Comment : public Emittable -{ - // [Construction / Destruction] - - Comment(Compiler* c, const char* str) ASMJIT_NOTHROW; - virtual ~Comment() ASMJIT_NOTHROW; - - // [Emit] - - virtual void emit(Assembler& a); - - // [Methods] - - //! @brief Get comment data. - inline const char* str() const ASMJIT_NOTHROW { return _str; } - - // [Members] - -private: - const char* _str; -}; - -// ============================================================================ -// [AsmJit::EmbeddedData] -// ============================================================================ - -//! @brief Emittable used to emit comment into @c Assembler logger. -//! -//! @note This class is always allocated by @c AsmJit::Compiler. -struct ASMJIT_API EmbeddedData : public Emittable -{ - // [Construction / Destruction] - - EmbeddedData(Compiler* c, SysUInt capacity, const void* data, SysUInt size) ASMJIT_NOTHROW; - virtual ~EmbeddedData() ASMJIT_NOTHROW; - - // [Emit] - - virtual void emit(Assembler& a); - - // [Methods] - - //! @brief Get size of embedded data. - SysUInt size() const ASMJIT_NOTHROW { return _size; } - //! @brief Get capacity of embedded data. - //! @internal - SysUInt capacity() const ASMJIT_NOTHROW { return _size; } - //! @brief Get pointer to embedded data. - UInt8* data() const ASMJIT_NOTHROW { return (UInt8*)_data; } - - // [Members] - -private: - SysUInt _size; - SysUInt _capacity; - UInt8 _data[sizeof(void*)]; - - friend struct CompilerCore; -}; - -// ============================================================================ -// [AsmJit::Align] -// ============================================================================ - -//! @brief Emittable used to align assembler code. -struct ASMJIT_API Align : public Emittable -{ - // [Construction / Destruction] - - Align(Compiler* c, SysInt size = 0) ASMJIT_NOTHROW; - virtual ~Align() ASMJIT_NOTHROW; - - // [Methods] - - virtual void emit(Assembler& a); - - //! @brief Get align size in bytes. - inline SysInt size() const ASMJIT_NOTHROW { return _size; } - //! @brief Set align size in bytes to @a size. - inline void setSize(SysInt size) ASMJIT_NOTHROW { _size = size; } - -private: - SysInt _size; -}; - -// ============================================================================ -// [AsmJit::Instruction] -// ============================================================================ - -//! @brief Emittable that represents single instruction and its operands. -struct ASMJIT_API Instruction : public Emittable -{ - // [Construction / Destruction] - - Instruction(Compiler* c) ASMJIT_NOTHROW; - Instruction(Compiler* c, - UInt32 code, - const Operand* o1, const Operand* o2, const Operand* o3, - const char* inlineComment = NULL) ASMJIT_NOTHROW; - virtual ~Instruction() ASMJIT_NOTHROW; - - // [Emit] - - virtual void emit(Assembler& a); - - // [Methods] - - //! @brief Return instruction code, see @c INST_CODE. - inline UInt32 code() const ASMJIT_NOTHROW { return _code; } - - //! @brief Return array of operands (3 operands total). - inline Operand* const* ops() ASMJIT_NOTHROW { return _o; } - - //! @brief Return first instruction operand. - inline Operand* o1() const ASMJIT_NOTHROW { return _o[0]; } - - //! @brief Return second instruction operand. - inline Operand* o2() const ASMJIT_NOTHROW { return _o[1]; } - - //! @brief Return third instruction operand. - inline Operand* o3() const ASMJIT_NOTHROW { return _o[2]; } - - //! @brief Set instruction code. - //! - //! Please do not modify instruction code if you are not know what you are - //! doing. Incorrect instruction code or operands can assert() in runtime. - inline void setCode(UInt32 code) ASMJIT_NOTHROW { _code = code; } - - // [Members] - -private: - //! @brief Instruction code, see @c INST_CODE. - UInt32 _code; - //! @brief Instruction operands. - Operand *_o[3]; - //! @brief Static array for instruction operands (cache) - Operand _ocache[3]; - - const char* _inlineComment; - - friend struct Function; -}; - -// ============================================================================ -// [AsmJit::TypeAsId] -// ============================================================================ - -//! @brief Template based type to variable ID converter. -template -struct TypeAsId -{ -#if defined(ASMJIT_NODOC) - enum { - //! @brief Variable id, see @c VARIABLE_TYPE enum - Id = X - }; -#endif -}; - -// Skip documenting this. -#if !defined(ASMJIT_NODOC) - -template -struct TypeAsId { enum { Id = VARIABLE_TYPE_PTR }; }; - -#define ASMJIT_DECLARE_TYPE_AS_ID(__T__, __Id__) \ - template<> \ - struct TypeAsId<__T__> { enum { Id = __Id__ }; } - -ASMJIT_DECLARE_TYPE_AS_ID(Int32, VARIABLE_TYPE_INT32); -ASMJIT_DECLARE_TYPE_AS_ID(UInt32, VARIABLE_TYPE_UINT32); - -#if defined(ASMJIT_X64) -ASMJIT_DECLARE_TYPE_AS_ID(Int64, VARIABLE_TYPE_INT64); -ASMJIT_DECLARE_TYPE_AS_ID(UInt64, VARIABLE_TYPE_UINT64); -#endif // ASMJIT_X64 - -ASMJIT_DECLARE_TYPE_AS_ID(float, VARIABLE_TYPE_FLOAT); -ASMJIT_DECLARE_TYPE_AS_ID(double, VARIABLE_TYPE_DOUBLE); - -#endif // !ASMJIT_NODOC - -// ============================================================================ -// [AsmJit::Function Builder] -// ============================================================================ - -//! @brief Class used to build function without arguments. -struct BuildFunction0 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { return NULL; } - inline SysUInt count() const ASMJIT_NOTHROW { return 0; } -}; - -//! @brief Class used to build function with 1 argument. -template -struct BuildFunction1 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 1; } -}; - -//! @brief Class used to build function with 2 arguments. -template -struct BuildFunction2 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 2; } -}; - -//! @brief Class used to build function with 3 arguments. -template -struct BuildFunction3 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 3; } -}; - -//! @brief Class used to build function with 4 arguments. -template -struct BuildFunction4 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 4; } -}; - -//! @brief Class used to build function with 5 arguments. -template -struct BuildFunction5 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 5; } -}; - -//! @brief Class used to build function with 6 arguments. -template -struct BuildFunction6 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 6; } -}; - -//! @brief Class used to build function with 7 arguments. -template -struct BuildFunction7 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 7; } -}; - -//! @brief Class used to build function with 8 arguments. -template -struct BuildFunction8 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 8; } -}; - -//! @brief Class used to build function with 9 arguments. -template -struct BuildFunction9 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 9; } -}; - -//! @brief Class used to build function with 9 arguments. -template -struct BuildFunction10 -{ - inline const UInt32* args() const ASMJIT_NOTHROW { static const UInt32 data[] = { TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id, TypeAsId::Id }; return data; } - inline SysUInt count() const ASMJIT_NOTHROW { return 10; } -}; - -// ============================================================================ -// [AsmJit::Function] -// ============================================================================ - -//! @brief Function emittable used to generate C/C++ functions. -//! -//! Functions are base blocks for generating assembler output. Each generated -//! assembler stream needs standard entry and leave sequences thats compatible -//! to operating system conventions (ABI). -//! -//! Function class can be used to generate entry (prolog) and leave (epilog) -//! sequences that is compatible to a given calling convention and to allocate -//! and manage variables that can be allocated to registers or spilled. -//! -//! @note To create function use @c AsmJit::Compiler::newFunction() method, do -//! not create @c Function instances by different ways. -//! -//! @sa @c State, @c StateRef, @c Variable, @c VariableRef. -struct ASMJIT_API Function : public Emittable -{ - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! @brief Create new @c Function instance. - //! - //! @note Always use @c AsmJit::Compiler::newFunction() to create @c Function - //! instance. - Function(Compiler* c) ASMJIT_NOTHROW; - //! @brief Destroy @c Function instance. - virtual ~Function() ASMJIT_NOTHROW; - - // -------------------------------------------------------------------------- - // [Emit] - // -------------------------------------------------------------------------- - - virtual void prepare(); - virtual void emit(Assembler& a); - - // -------------------------------------------------------------------------- - // [Calling Convention / Function Arguments] - // -------------------------------------------------------------------------- - - //! @brief Set function prototype. - //! - //! This will set function calling convention and setup arguments variables. - void setPrototype(UInt32 cconv, const UInt32* args, SysUInt count); - - //! @brief Set naked function to true or false (naked means no prolog / epilog code). - void setNaked(UInt8 naked) ASMJIT_NOTHROW; - - //! @brief Enable or disable allocation of EBP/RBP register. - inline void setAllocableEbp(UInt8 val) ASMJIT_NOTHROW { _allocableEbp = val; } - - //! @brief Enable or disable allocation of EBP/RBP register. - inline void setPrologEpilogPushPop(UInt8 val) ASMJIT_NOTHROW { _prologEpilogPushPop = val; } - - //! @brief Enable or disable emms instruction in epilog. - inline void setEmms(UInt8 val) ASMJIT_NOTHROW { _emms = val; } - - //! @brief Enable or disable sfence instruction in epilog. - inline void setSfence(UInt8 val) ASMJIT_NOTHROW { _sfence = val; } - - //! @brief Enable or disable lfence instruction in epilog. - inline void setLfence(UInt8 val) ASMJIT_NOTHROW { _lfence = val; } - - //! @brief Return whether optimizing prolog / epilog is enabled or disabled. - inline void setOptimizedPrologEpilog(UInt8 val) ASMJIT_NOTHROW { _optimizedPrologEpilog = val; } - - //! @brief Return function calling convention, see @c CALL_CONV. - inline UInt32 cconv() const ASMJIT_NOTHROW { return _cconv; } - - //! @brief Return @c true if callee pops the stack by ret() instruction. - //! - //! Stdcall calling convention is designed to pop the stack by callee, - //! but all calling conventions used in MSVC extept cdecl does that. - //! - //! @note This is related to used calling convention, it's not affected by - //! number of function arguments or their types. - inline UInt8 calleePopsStack() const ASMJIT_NOTHROW { return _calleePopsStack; } - - //! @brief Return @c true if function is naked (no prolog / epilog code). - inline UInt8 naked() const ASMJIT_NOTHROW { return _naked; } - - //! @brief Return @c true if EBP/RBP register can be allocated by register allocator. - inline UInt8 allocableEbp() const ASMJIT_NOTHROW { return _allocableEbp; } - - //! @brief Return @c true if EBP/RBP register can be allocated by register allocator. - inline UInt8 prologEpilogPushPop() const ASMJIT_NOTHROW { return _prologEpilogPushPop; } - - //! @brief Return whether emms instruction is enabled or disabled in epilog. - inline UInt8 emms() const ASMJIT_NOTHROW { return _emms; } - - //! @brief Return whether sfence instruction is enabled or disabled in epilog. - inline UInt8 sfence() const ASMJIT_NOTHROW { return _sfence; } - - //! @brief Return whether lfence instruction is enabled or disabled in epilog. - inline UInt8 lfence() const ASMJIT_NOTHROW { return _lfence; } - - //! @brief Return whether optimizing prolog / epilog is enabled or disabled. - inline UInt8 optimizedPrologEpilog() const ASMJIT_NOTHROW { return _optimizedPrologEpilog; } - - //! @brief Return direction of arguments passed on the stack. - //! - //! Direction should be always @c ARGUMENT_DIR_RIGHT_TO_LEFT. - //! - //! @note This is related to used calling convention, it's not affected by - //! number of function arguments or their types. - inline UInt32 cconvArgumentsDirection() const ASMJIT_NOTHROW { return _cconvArgumentsDirection; } - - //! @brief Return registers used to pass first integer parameters by current - //! calling convention. - //! - //! @note This is related to used calling convention, it's not affected by - //! number of function arguments or their types. - inline const UInt32* cconvArgumentsGp() const ASMJIT_NOTHROW { return _cconvArgumentsGp; } - - //! @brief Return registers used to pass first SP-FP or DP-FPparameters by - //! current calling convention. - //! - //! @note This is related to used calling convention, it's not affected by - //! number of function arguments or their types. - inline const UInt32* cconvArgumentsXmm() const ASMJIT_NOTHROW { return _cconvArgumentsXmm; } - - //! @brief Return bitmask of general purpose registers that's preserved - //! (non-volatile). - //! - //! @note This is related to used calling convention, it's not affected by - //! number of function arguments or their types. - inline UInt32 cconvPreservedGp() const ASMJIT_NOTHROW { return _cconvPreservedGp; } - //! @brief Return bitmask of sse registers that's preserved (non-volatile). - //! - //! @note This is related to used calling convention, it's not affected by - //! number of function arguments or their types. - inline UInt32 cconvPreservedXmm() const ASMJIT_NOTHROW { return _cconvPreservedXmm; } - - // -------------------------------------------------------------------------- - // [Registers allocator / Variables] - // -------------------------------------------------------------------------- - - //! @brief Return argument at @a i. - inline Variable* argument(SysInt i) ASMJIT_NOTHROW - { - ASMJIT_ASSERT((SysUInt)i < _argumentsCount); - return _variables[i]; - } - - //! @brief Create new variable - Variable* newVariable(UInt8 type, UInt8 priority = 10, UInt8 preferredRegister = NO_REG); - - bool alloc(Variable* v, - UInt8 mode = VARIABLE_ALLOC_READWRITE, - UInt8 preferredRegister = NO_REG); - bool spill(Variable* v); - void unuse(Variable* v); - - void spillAll(); - void spillAllGp(); - void spillAllMm(); - void spillAllXmm(); - void _spillAll(SysUInt start, SysUInt end); - void spillRegister(const BaseReg& reg); - - //! @brief Get count of free GP registers (in current state). - SysInt numFreeGp() const; - //! @brief Get count of free MMX registers (in current state). - SysInt numFreeMm() const; - //! @brief Get count of free XMM registers (in current state). - SysInt numFreeXmm() const; - - //! @brief Get if variable @a v is prevented. - //! @return true if variable @a v is prevented (in _prevented list). - //! @sa _prevented. - bool isPrevented(Variable* v); - - //! @brief Add variable @a v to list of prevented variables. - //! @sa _prevented. - void addPrevented(Variable* v); - - //! @brief Remove variable @a v from list of prevented variables. - //! @sa _prevented. - void removePrevented(Variable* v); - - //! @brief Remove all variables from list of prevented ones. - //! @sa _prevented. - void clearPrevented(); - - //! @brief Return spill candidate for variable type @a type. - Variable* _getSpillCandidate(UInt8 type); - - void _allocAs(Variable* v, UInt8 mode, UInt32 code); - void _allocReg(UInt8 code, Variable* v); - void _freeReg(UInt8 code); - - void _moveGp(Variable* v, UInt8 code); - void _exchangeGp(Variable* v, UInt8 mode, Variable* other); - void _postAlloc(Variable* v, UInt8 mode); - - //! @brief Return size of alignment on the stack. - //! - //! Stack is aligned to 16 bytes by default. For X64 platforms there is - //! no extra code needed to align stack to 16 bytes, because it's default - //! stack alignment. - inline SysInt stackAlignmentSize() const ASMJIT_NOTHROW { return _stackAlignmentSize; } - - //! @brief Size needed to save registers in prolog / epilog. - inline SysInt prologEpilogStackSize() const ASMJIT_NOTHROW { return _prologEpilogStackSize; } - - //! @brief Return size of variables on the stack. - //! - //! This variable is always aligned to 16 bytes for each platform. - inline SysInt variablesStackSize() const ASMJIT_NOTHROW { return _variablesStackSize; } - - //! @brief Return count of arguments. - inline UInt32 argumentsCount() const ASMJIT_NOTHROW { return _argumentsCount; } - - //! @brief Return stack size of all function arguments (passed on the - //! stack). - inline UInt32 argumentsStackSize() const ASMJIT_NOTHROW { return _argumentsStackSize; } - - //! @brief Return bitmask of all used (for actual context) general purpose registers. - inline UInt32 usedGpRegisters() const ASMJIT_NOTHROW { return _usedGpRegisters; } - //! @brief Return bitmask of all used (for actual context) mmx registers. - inline UInt32 usedMmRegisters() const ASMJIT_NOTHROW { return _usedMmRegisters; } - //! @brief Return bitmask of all used (for actual context) sse registers. - inline UInt32 usedXmmRegisters() const ASMJIT_NOTHROW { return _usedXmmRegisters; } - - //! @brief Mark general purpose registers in the given @a mask as used. - inline void useGpRegisters(UInt32 mask) ASMJIT_NOTHROW { _usedGpRegisters |= mask; } - //! @brief Mark mmx registers in the given @a mask as used. - inline void useMmRegisters(UInt32 mask) ASMJIT_NOTHROW { _usedMmRegisters |= mask; } - //! @brief Mark sse registers in the given @a mask as used. - inline void useXmmRegisters(UInt32 mask) ASMJIT_NOTHROW { _usedXmmRegisters |= mask; } - - //! @brief Mark general purpose registers in the given @a mask as unused. - inline void unuseGpRegisters(UInt32 mask) ASMJIT_NOTHROW { _usedGpRegisters &= ~mask; } - //! @brief Mark mmx registers in the given @a mask as unused. - inline void unuseMmRegisters(UInt32 mask) ASMJIT_NOTHROW { _usedMmRegisters &= ~mask; } - //! @brief Mark sse registers in the given @a mask as unused. - inline void unuseXmmRegisters(UInt32 mask) ASMJIT_NOTHROW { _usedXmmRegisters &= ~mask; } - - //! @brief Return bitmask of all changed general purpose registers during - //! function execution (for generating optimized prolog / epilog). - inline UInt32 modifiedGpRegisters() const ASMJIT_NOTHROW { return _modifiedGpRegisters; } - //! @brief Return bitmask of all changed mmx registers during - //! function execution (for generating optimized prolog / epilog). - inline UInt32 modifiedMmRegisters() const ASMJIT_NOTHROW { return _modifiedMmRegisters; } - //! @brief Return bitmask of all changed sse registers during - //! function execution (for generating optimized prolog / epilog). - inline UInt32 modifiedXmmRegisters() const ASMJIT_NOTHROW { return _modifiedXmmRegisters; } - - //! @brief Mark general purpose registers in the given @a mask as modified. - inline void modifyGpRegisters(UInt32 mask) ASMJIT_NOTHROW { _modifiedGpRegisters |= mask; } - //! @brief Mark mmx registers in the given @a mask as modified. - inline void modifyMmRegisters(UInt32 mask) ASMJIT_NOTHROW { _modifiedMmRegisters |= mask; } - //! @brief Mark sse registers in the given @a mask as modified. - inline void modifyXmmRegisters(UInt32 mask) ASMJIT_NOTHROW { _modifiedXmmRegisters |= mask; } - - //! @brief Get count of GP registers that must be saved by prolog and restored - //! by epilog. - SysInt countOfGpRegistersToBeSaved() const ASMJIT_NOTHROW; - //! @brief Get count of XMM registers that must be saved by prolog and restored - //! by epilog. - SysInt countOfXmmRegistersToBeSaved() const ASMJIT_NOTHROW; - - // -------------------------------------------------------------------------- - // [State] - // -------------------------------------------------------------------------- - - //! @brief Save function current register state. - //! - //! To save function state always wrap returned value into @c StateRef: - //! - //! @code - //! // Your function - //! Function &f = ...; - //! - //! // Block - //! { - //! // Save state - //! StateRef state(f.saveState()); - //! - //! // Your code ... - //! - //! // Restore state (automatic by @c StateRef destructor). - //! } - //! - //! @endcode - State* saveState(); - - //! @brief Restore function register state to @a state. - //! @sa saveState(). - void restoreState(State* state); - - //! @brief Set function register state to @a state. - void setState(State* state); - - // -------------------------------------------------------------------------- - // [Labels] - // -------------------------------------------------------------------------- - - //! @brief Return function entry label. - //! - //! Entry label can be used to call this function from another code that's - //! being generated. - inline Label* entryLabel() const ASMJIT_NOTHROW { return _entryLabel; } - - //! @brief Return prolog label (label after function prolog) - inline Label* prologLabel() const ASMJIT_NOTHROW { return _prologLabel; } - - //! @brief Return exit label. - //! - //! Use exit label to jump to function epilog. - inline Label* exitLabel() const ASMJIT_NOTHROW { return _exitLabel; } - -private: - // -------------------------------------------------------------------------- - // [Calling Convention / Function Arguments] - // -------------------------------------------------------------------------- - - //! @brief Sets function calling convention. - void _setCallingConvention(UInt32 cconv) ASMJIT_NOTHROW; - - //! @brief Sets function arguments (must be done after correct calling - //! convention is set). - void _setArguments(const UInt32* args, SysUInt len); - - //! @brief Internal, used from other _jmpAndRestore method. This method does - //! the main job. - static void _jmpAndRestore(Compiler* c, Label* label); - - //! @brief Calling convention, see @c CALL_CONV. - UInt32 _cconv; - - //! @brief Callee pops stack; - UInt8 _calleePopsStack; - - //! @brief Generate naked function? - UInt8 _naked; - - //! @brief Whether EBP/RBP register can be used by register allocator. - UInt8 _allocableEbp; - - //! @brief Whether Prolog and epilog should be generated by push/pop - //! instructions instead of mov instructions. - UInt8 _prologEpilogPushPop; - - //! @brief Whether to generate emms instruction in epilog. - UInt8 _emms; - - //! @brief Whether to generate sfence instruction in epilog. - UInt8 _sfence; - - //! @brief Whether to generate lfence instruction in epilog. - UInt8 _lfence; - - //! @brief Whether to optimize prolog / epilog sequences. - UInt8 _optimizedPrologEpilog; - - //! @brief Direction for arguments passed on stack, see @c ARGUMENT_DIR. - UInt32 _cconvArgumentsDirection; - - //! @brief List of registers that's used for first INT arguments instead of stack. - UInt32 _cconvArgumentsGp[16]; - //! @brief List of registers that's used for first FP arguments instead of stack. - UInt32 _cconvArgumentsXmm[16]; - - //! @brief Bitmask for preserved general purpose registers. - UInt32 _cconvPreservedGp; - //! @brief Bitmask for preserved sse registers. - UInt32 _cconvPreservedXmm; - - //! @brief Count of arguments (in @c _argumentsList). - UInt32 _argumentsCount; - - //! @brief Count of bytes consumed by arguments on the stack. - UInt32 _argumentsStackSize; - - // -------------------------------------------------------------------------- - // [Registers allocator / Variables] - // -------------------------------------------------------------------------- - - //! @brief Size of maximum alignment size on the stack. - SysInt _stackAlignmentSize; - //! @brief Size of prolog/epilog on the stack. - SysInt _prologEpilogStackSize; - //! @brief Size of all variables on the stack. - SysInt _variablesStackSize; - - //! @brief Bitmask where are stored are used GP registers. - UInt32 _usedGpRegisters; - //! @brief Bitmask where are stored are used MMX registers. - UInt32 _usedMmRegisters; - //! @brief Bitmask where are stored are used XMM registers. - UInt32 _usedXmmRegisters; - - //! @brief Bitmask where are stored are modified GP registers. - UInt32 _modifiedGpRegisters; - //! @brief Bitmask where are stored are modified MMX registers. - UInt32 _modifiedMmRegisters; - //! @brief Bitmask where are stored are modified XMM registers. - UInt32 _modifiedXmmRegisters; - - //! @brief List of variables managed by Function/Compiler. - PodVector _variables; - - //! @brief List of prevented variables that can't be spilled. - //! - //! Prevented variables are variables used when generating code chain. First - //! the variables are allocated/spilled and then the assembler instruction - //! is emitted. - //! - //! For example look at this simple code: - //! - //! @code - //! Compiler::mov(dst_variable.x(), src_variable.c()); - //! @endcode - //! - //! Before mov instruction is emitted, variables dst_variable and src_variable - //! are stored in @c Compiler::_prevented list. Prevention prevents variables - //! to be spilled (if some variable needs to be allocated and compiler must - //! decide which variable to spill). - PodVector _prevented; - - //! @brief Whether to use registers prevention. This is internally turned - //! on / off while switching between states. - //! - //! Never modify this varialbe unless you know what you are doing. Prevention - //! is Compiler/Function implementation detail. - bool _usePrevention; - - // -------------------------------------------------------------------------- - // [State] - // -------------------------------------------------------------------------- - - //! @brief This is similar to State::Data, but we need to save only allocated - //! variables (this is enough). First idea was to use State here, but source - //! code was bloated by it (setting and restoring values that weren't needed) - union StateData - { - //! @brief All variables in one array. - Variable* regs[16+8+16]; - - struct { - //! @brief Regeral purpose registers. - Variable* gp[16]; - //! @brief MMX registers. - Variable* mm[8]; - //! @brief XMM registers. - Variable* xmm[16]; - }; - }; - - //! @brief Current state data. - StateData _state; - - // -------------------------------------------------------------------------- - // [Labels] - // -------------------------------------------------------------------------- - - //! @brief Function entry point label. - Label* _entryLabel; - //! @brief Label that points to start of function prolog generated by @c Prolog. - Label* _prologLabel; - //! @brief Label that points before function epilog generated by @c Epilog. - Label* _exitLabel; - - friend struct CompilerCore; - friend struct State; -}; - -// Inlines that uses AsmJit::Function -inline bool Variable::alloc(UInt8 mode, UInt8 preferredRegister) -{ return function()->alloc(this, mode, preferredRegister); } - -inline bool Variable::spill() -{ return function()->spill(this); } - -inline void Variable::unuse() -{ function()->unuse(this); } - -inline StateRef::~StateRef() -{ if (_state) _state->_function->restoreState(_state); } - -// ============================================================================ -// [AsmJit::Prolog] -// ============================================================================ - -//! @brief Prolog emittable. -struct ASMJIT_API Prolog : public Emittable -{ - // [Construction / Destruction] - - Prolog(Compiler* c, Function* f) ASMJIT_NOTHROW; - virtual ~Prolog() ASMJIT_NOTHROW; - - // [Emit] - - virtual void emit(Assembler& a); - - // [Methods] - - //! @brief Get function associated with this prolog. - inline Function* function() const ASMJIT_NOTHROW { return _function; } - - // [Members] - -private: - Function* _function; - Label* _label; - - friend struct CompilerCore; - friend struct Function; -}; - -// ============================================================================ -// [AsmJit::Epilog] -// ============================================================================ - -//! @brief Epilog emittable. -struct ASMJIT_API Epilog : public Emittable -{ - // [Construction / Destruction] - - Epilog(Compiler* c, Function* f) ASMJIT_NOTHROW; - virtual ~Epilog() ASMJIT_NOTHROW; - - // [Emit] - - virtual void emit(Assembler& a); - - // [Methods] - - //! @brief Get function associated with this epilog. - inline Function* function() const ASMJIT_NOTHROW { return _function; } - - // [Members] - -private: - Function* _function; - Label* _label; - - friend struct CompilerCore; - friend struct Function; -}; - -// ============================================================================ -// [AsmJit::Target] -// ============================================================================ - -//! @brief Target. -//! -//! Target is bound label location. -struct ASMJIT_API Target : public Emittable -{ - // [Construction / Destruction] - - Target(Compiler* c, Label* target) ASMJIT_NOTHROW; - virtual ~Target() ASMJIT_NOTHROW; - - // [Emit] - - virtual void emit(Assembler& a); - - // [Methods] - - //! @brief Return label bound to this target. - inline Label* target() const ASMJIT_NOTHROW { return _target; } - - // [Members] - -private: - Label* _target; -}; - -// ============================================================================ -// [AsmJit::JumpTable] -// ============================================================================ - -//! @brief Jump table. -struct ASMJIT_API JumpTable : public Emittable -{ - // [Construction / Destruction] - - JumpTable(Compiler* c) ASMJIT_NOTHROW; - virtual ~JumpTable() ASMJIT_NOTHROW; - - // [Emit] - - virtual void emit(Assembler& a); - virtual void postEmit(Assembler& a); - - // [Methods] - - //! @brief Return target label where are informations about jump adresses. - inline Label* target() const ASMJIT_NOTHROW { return _target; } - - //! @brief Return labels list. - PodVector& labels() ASMJIT_NOTHROW { return _labels; } - - //! @brief Return labels list. - const PodVector& labels() const ASMJIT_NOTHROW { return _labels; } - - //! @brief Add new label @a target to jump table. - //! @param target @c Label to add (or NULL to create one). - //! @param pos Position in jump table where to add it - Label* addLabel(Label* target = NULL, SysInt pos = -1); - - // [Members] - -private: - Label* _target; - PodVector _labels; -}; - -// ============================================================================ -// [AsmJit::CompilerCore] -// ============================================================================ - -//! @brief Compiler core. -//! -//! @sa @c AsmJit::Compiler. -struct ASMJIT_API CompilerCore : public Serializer -{ - // ------------------------------------------------------------------------- - // [Typedefs] - // ------------------------------------------------------------------------- - - //! @brief List of variables used and managed by @c Compiler. - typedef PodVector VariableList; - //! @brief List of operands used and managed by @c Compiler. - typedef PodVector OperandList; - - // ------------------------------------------------------------------------- - // [Construction / Destruction] - // ------------------------------------------------------------------------- - - //! @brief Create new (empty) instance of @c Compiler. - CompilerCore() ASMJIT_NOTHROW; - //! @brief Destroy @c Compiler instance. - virtual ~CompilerCore() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Compiler] - // ------------------------------------------------------------------------- - - //! @brief Clear everything, but not deallocate buffers. - //! - //! @note This method will destroy your code. - void clear() ASMJIT_NOTHROW; - - //! @brief Free internal buffer, all emitters and NULL all pointers. - //! - //! @note This method will destroy your code. - void free() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Emittables] - // ------------------------------------------------------------------------- - - //! @brief Return first emittables in double linked list. - inline Emittable* firstEmittable() const ASMJIT_NOTHROW { return _first; } - - //! @brief Return last emittable in double linked list. - inline Emittable* lastEmittable() const ASMJIT_NOTHROW { return _last; } - - //! @brief Return current emittable after all emittables are emitter. - //! - //! @note If this method return @c NULL it means first position. - inline Emittable* currentEmittable() const ASMJIT_NOTHROW { return _current; } - - //! @brief Add emittable after current and set current to @a emittable. - void addEmittable(Emittable* emittable) ASMJIT_NOTHROW; - - //! @brief Remove emittable (and if needed set current to previous). - void removeEmittable(Emittable* emittable) ASMJIT_NOTHROW; - - //! @brief Set new current emittable and return previous one. - Emittable* setCurrentEmittable(Emittable* current) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Logging] - // ------------------------------------------------------------------------- - - //! @brief Emit a single comment line into @c Assembler logger. - //! - //! Emitting comments are useful to log something. Because assembler can be - //! generated from AST or other data structures, you may sometimes need to - //! log data characteristics or statistics. - //! - //! @note Emitting comment is not directly sent to logger, but instead it's - //! stored in @c AsmJit::Compiler and emitted when @c serialize() method is - //! called with all instructions together in correct order. - void comment(const char* fmt, ...) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Function Builder] - // ------------------------------------------------------------------------- - - //! @brief Create a new function. - //! - //! @param cconv Calling convention to use (see @c CALL_CONV enum) - //! @param params Function arguments prototype. - //! - //! This method is usually used as a first step when generating functions - //! by @c Compiler. First parameter @a cconv specifies function calling - //! convention to use. Second parameter @a params specifies function - //! arguments. To create function arguments are used templates - //! @c BuildFunction0<>, @c BuildFunction1<...>, @c BuildFunction2<...>, - //! etc... - //! - //! Templates with BuildFunction prefix are used to generate argument IDs - //! based on real C++ types. See next example how to generate function with - //! two 32 bit integer arguments. - //! - //! @code - //! // Building function using AsmJit::Compiler example. - //! - //! // Compiler instance - //! Compiler c; - //! - //! // Begin of function (also emits function @c Prolog) - //! Function& f = *c.newFunction( - //! // Default calling convention (32 bit cdecl or 64 bit for host OS) - //! CALL_CONV_DEFAULT, - //! // Using function builder to generate arguments list - //! BuildFunction2()); - //! - //! // End of function (also emits function @c Epilog) - //! c.endFunction(); - //! @endcode - //! - //! You can see that building functions is really easy. Previous code snipped - //! will generate code for function with two 32 bit integer arguments. You - //! can access arguments by @c AsmJit::Function::argument() method. Arguments - //! are indexed from 0 (like everything in C). - //! - //! @code - //! // Accessing function arguments through AsmJit::Function example. - //! - //! // Compiler instance - //! Compiler c; - //! - //! // Begin of function (also emits function @c Prolog) - //! Function& f = *c.newFunction( - //! // Default calling convention (32 bit cdecl or 64 bit for host OS) - //! CALL_CONV_DEFAULT, - //! // Using function builder to generate arguments list - //! BuildFunction2()); - //! - //! // Arguments are like other variables, you need to reference them by - //! // VariableRef types: - //! Int32Ref a0 = f.argument(0); - //! Int32Ref a1 = f.argument(1); - //! - //! // To allocate them to registers just use .alloc(), .r(), .x() or .c() - //! // variable methods: - //! c.add(a0.r(), a1.r()); - //! - //! // End of function (also emits function @c Epilog) - //! c.endFunction(); - //! @endcode - //! - //! Arguments are like variables. How to manipulate with variables is - //! documented in @c AsmJit::Compiler detail and @c AsmJit::VariableRef - //! class. - //! - //! @note To get current function use @c currentFunction() method or save - //! pointer to @c AsmJit::Function returned by @c AsmJit::Compiler::newFunction<> - //! method. Recommended is to save the pointer. - //! - //! @sa @c BuildFunction0, @c BuildFunction1, @c BuildFunction2, ... - template - Function* newFunction(UInt32 cconv, const T& params) ASMJIT_NOTHROW - { return newFunction_(cconv, params.args(), params.count()); } - - //! @brief Create a new function (low level version). - //! - //! @param cconv Function calling convention (see @c AsmJit::CALL_CONV). - //! @param args Function arguments (see @c AsmJit::VARIABLE_TYPE). - //! @param count Arguments count. - //! - //! This method is internally called from @c newFunction() method and - //! contains arguments thats used internally by @c AsmJit::Compiler. - //! - //! @note To get current function use @c currentFunction() method. - Function* newFunction_(UInt32 cconv, const UInt32* args, SysUInt count) ASMJIT_NOTHROW; - - //! @brief Ends current function. - Function* endFunction() ASMJIT_NOTHROW; - - //! @brief Return current function. - //! - //! This method can be called within @c newFunction() and @c endFunction() - //! block to get current function you are working with. It's recommended - //! to store @c AsmJit::Function pointer returned by @c newFunction<> method, - //! because this allows you in future implement function sections outside of - //! function itself (yeah, this is possible!). - inline Function* currentFunction() const ASMJIT_NOTHROW { return _currentFunction; } - - //! @brief Create function prolog (function begin section). - //! - //! Function prologs and epilogs are standardized sequences of instructions - //! thats used to build functions. If you are using @c Function and - //! @c AsmJit::Compiler::newFunction() to make a function, keep in mind that - //! it creates prolog (by @c newFunction()) and epilog (by @c endFunction()) - //! for you. - //! - //! @note Never use prolog after @c newFunction() method. It will create - //! prolog for you! - //! - //! @note Compiler can optimize prologs and epilogs. - //! - //! @sa @c Prolog, @c Function. - Prolog* newProlog(Function* f) ASMJIT_NOTHROW; - - //! @brief Create function epilog (function leave section). - //! - //! Function prologs and epilogs are standardized sequences of instructions - //! thats used to build functions. If you are using @c Function and - //! @c AsmJit::Compiler::newFunction() to make a function, keep in mind that - //! it creates prolog (by @c newFunction()) and epilog (by @c endFunction()) - //! for you. - //! - //! @note Never use epilog before @c endFunction() method. It will create - //! epilog for you! - //! - //! @note Compiler can optimize prologs and epilogs. - //! - //! @sa @c Epilog, @c Function. - Epilog* newEpilog(Function* f) ASMJIT_NOTHROW; - - // -------------------------------------------------------------------------- - // [Registers allocator / Variables] - // -------------------------------------------------------------------------- - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->argument() - //! @sa @c Function::argument() - Variable* argument(SysInt i) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->newVariable() - //! @sa @c Function::newVariable() - Variable* newVariable(UInt8 type, UInt8 priority = 10, UInt8 preferredRegister = NO_REG) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->alloc() - //! @sa @c Function::alloc() - bool alloc(Variable* v, - UInt8 mode = VARIABLE_ALLOC_READWRITE, - UInt8 preferredRegister = NO_REG) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->spill() - //! @sa @c Function::spill() - bool spill(Variable* v) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->unuse() - //! @sa @c Function::unuse() - void unuse(Variable* v) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->spillAll() - //! @sa @c Function::spillAll() - void spillAll() ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->spillAllGp() - //! @sa @c Function::spillAllGp() - void spillAllGp() ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->spillAllMm() - //! @sa @c Function::spillAllMm() - void spillAllMm() ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->spillAllXmm() - //! @sa @c Function::spillAllXmm() - void spillAllXmm() ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->spillRegister() - //! @sa @c Function::spillRegister() - void spillRegister(const BaseReg& reg) ASMJIT_NOTHROW; - - SysInt numFreeGp() const ASMJIT_NOTHROW; - SysInt numFreeMm() const ASMJIT_NOTHROW; - SysInt numFreeXmm() const ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->isPrevented() - //! @sa @c Function::isPrevented() - bool isPrevented(Variable* v) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->addPrevented() - //! @sa @c Function::addPrevented() - void addPrevented(Variable* v) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->removePrevented() - //! @sa @c Function::removePrevented() - void removePrevented(Variable* v) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->clearPrevented() - //! @sa @c Function::clearPrevented() - void clearPrevented() ASMJIT_NOTHROW; - - // -------------------------------------------------------------------------- - // [State] - // -------------------------------------------------------------------------- - - //! @brief Convenience method that calls: - //! Compiler::currentFunction()->saveState() - //! @sa @c Function::saveState(). - State* saveState() ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFuncion()->restoreState() - //! @sa @c Function::restoreState(). - void restoreState(State* state) ASMJIT_NOTHROW; - - //! @brief Convenience method that calls: - //! Compiler::currentFuncion()->setState() - //! @sa @c Function::setState() - void setState(State* state) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Labels] - // ------------------------------------------------------------------------- - - //! @brief Create and return new @a Label managed by compiler. - //! - //! Labels created by compiler are same objects as labels created for - //! @c Assembler. There is only one limitation that if you are using - //! @c Compiler each label must be created by @c AsmJit::Compiler::newLabel() - //! method. - Label* newLabel() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Jump Table] - // ------------------------------------------------------------------------- - - JumpTable* newJumpTable() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Memory Management] - // ------------------------------------------------------------------------- - - //! @brief Create object managed by compiler internal memory manager. - template - inline T* newObject() ASMJIT_NOTHROW - { - void* addr = _zoneAlloc(sizeof(T)); - return new(addr) T(reinterpret_cast(this)); - } - - //! @brief Create object managed by compiler internal memory manager. - template - inline T* newObject(P1 p1) ASMJIT_NOTHROW - { - void* addr = _zoneAlloc(sizeof(T)); - return new(addr) T(reinterpret_cast(this), p1); - } - - //! @brief Create object managed by compiler internal memory manager. - template - inline T* newObject(P1 p1, P2 p2) ASMJIT_NOTHROW - { - void* addr = _zoneAlloc(sizeof(T)); - return new(addr) T(reinterpret_cast(this), p1, p2); - } - - //! @brief Create object managed by compiler internal memory manager. - template - inline T* newObject(P1 p1, P2 p2, P3 p3) ASMJIT_NOTHROW - { - void* addr = _zoneAlloc(sizeof(T)); - return new(addr) T(reinterpret_cast(this), p1, p2, p3); - } - - //! @brief Create object managed by compiler internal memory manager. - template - inline T* newObject(P1 p1, P2 p2, P3 p3, P4 p4) ASMJIT_NOTHROW - { - void* addr = _zoneAlloc(sizeof(T)); - return new(addr) T(reinterpret_cast(this), p1, p2, p3, p4); - } - - //! @brief Create object managed by compiler internal memory manager. - template - inline T* newObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) ASMJIT_NOTHROW - { - void* addr = _zoneAlloc(sizeof(T)); - return new(addr) T(reinterpret_cast(this), p1, p2, p3, p4, p5); - } - - //! @brief Internal function that registers operand @a op in compiler. - //! - //! Operand registration means adding @a op to internal operands list and - //! setting operand id. - //! - //! @note Operand @a op should by allocated by @c Compiler or you must - //! guarantee that it will be not destroyed before @c Compiler is destroyed. - void _registerOperand(Operand* op) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Jumps / Calls] - // ------------------------------------------------------------------------- - - using Serializer::jmp; - using Serializer::call; - - void jumpToTable(JumpTable* jt, const Register& index) ASMJIT_NOTHROW; - - SysInt _addTarget(void* target) ASMJIT_NOTHROW; - - void _jmpAndRestore(UInt32 code, Label* label, State* state) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Intrinsics] - // ------------------------------------------------------------------------- - - //! @brief Intrinsics helper method. - //! @internal - void op_var32(UInt32 code, const Int32Ref& a) ASMJIT_NOTHROW; - - //! @brief Intrinsics helper method. - //! @internal - void op_reg32_var32(UInt32 code, const Register& a, const Int32Ref& b) ASMJIT_NOTHROW; - - //! @brief Intrinsics helper method. - //! @internal - void op_var32_reg32(UInt32 code, const Int32Ref& a, const Register& b) ASMJIT_NOTHROW; - - //! @brief Intrinsics helper method. - //! @internal - void op_var32_imm(UInt32 code, const Int32Ref& a, const Immediate& b) ASMJIT_NOTHROW; - -#if defined(ASMJIT_X64) - //! @brief Intrinsics helper method. - //! @internal - void op_var64(UInt32 code, const Int64Ref& a) ASMJIT_NOTHROW; - - //! @brief Intrinsics helper method. - //! @internal - void op_reg64_var64(UInt32 code, const Register& a, const Int64Ref& b) ASMJIT_NOTHROW; - - //! @brief Intrinsics helper method. - //! @internal - void op_var64_reg64(UInt32 code, const Int64Ref& a, const Register& b) ASMJIT_NOTHROW; - - //! @brief Intrinsics helper method. - //! @internal - void op_var64_imm(UInt32 code, const Int64Ref& a, const Immediate& b) ASMJIT_NOTHROW; -#endif // ASMJIT_X64 - - // ------------------------------------------------------------------------- - // [EmitX86] - // ------------------------------------------------------------------------- - - virtual void _inlineComment(const char* text, SysInt len = -1) ASMJIT_NOTHROW; - virtual void _emitX86(UInt32 code, const Operand* o1, const Operand* o2, const Operand* o3) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Embed] - // ------------------------------------------------------------------------- - - virtual void _embed(const void* dataPtr, SysUInt dataSize) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Align] - // ------------------------------------------------------------------------- - - virtual void align(SysInt m) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Bind] - // ------------------------------------------------------------------------- - - virtual void bind(Label* label) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Make] - // ------------------------------------------------------------------------- - - virtual void* make(MemoryManager* memoryManager = NULL, UInt32 allocType = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW; - - //! @brief Method that will emit everything to @c Assembler instance @a a. - void serialize(Assembler& a) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Variables] - // ------------------------------------------------------------------------- -private: - //! @brief First emittable. - Emittable* _first; - //! @brief Last emittable. - Emittable* _last; - //! @brief Current emittable. - Emittable* _current; - - //! @brief Operands list (operand id is index in this list, id 0 is not valid). - OperandList _operands; - - //! @brief Current function. - Function* _currentFunction; - - //! @brief Label id counter (starts from 1). - UInt32 _labelIdCounter; - - //! @brief Jump table label. - Label* _jumpTableLabel; - - //! @brief Jump table entities. - PodVector _jumpTableData; - - //! @brief Buffer for inline comment (for next instruction). - const char* _inlineCommentBuffer; - - friend struct Instruction; - friend struct Variable; -}; - -// ============================================================================ -// [AsmJit::CompilerIntrinsics] -// ============================================================================ - -//! @brief Implementation of @c Compiler intrinsics. -//! -//! Methods in this class are implemented here, because we wan't to hide them -//! in shared libraries. These methods should be never exported by C++ compiler. -//! -//! @sa @c AsmJit::Compiler. -struct ASMJIT_HIDDEN CompilerIntrinsics : public CompilerCore -{ - //! @brief Create @c CompilerIntrinsics instance. Always use @c AsmJit::Compiler. - inline CompilerIntrinsics() ASMJIT_NOTHROW {} - - // -------------------------------------------------------------------------- - // [jmpAndRestore] - // -------------------------------------------------------------------------- - - inline void jAndRestore(CONDITION cc, Label* label, State* state) - { - ASMJIT_ASSERT(static_cast(cc) <= 0xF); - _jmpAndRestore(_jcctable[cc], label, state); - } - - inline void jaAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JA , label, state); } - inline void jaeAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JAE , label, state); } - inline void jbAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JB , label, state); } - inline void jbeAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JBE , label, state); } - inline void jcAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JC , label, state); } - inline void jeAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JE , label, state); } - inline void jgAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JG , label, state); } - inline void jgeAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JGE , label, state); } - inline void jlAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JL , label, state); } - inline void jleAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JLE , label, state); } - inline void jnaAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNA , label, state); } - inline void jnaeAndRestore(Label* label, State* state) { _jmpAndRestore(INST_JNAE, label, state); } - inline void jnbAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNB , label, state); } - inline void jnbeAndRestore(Label* label, State* state) { _jmpAndRestore(INST_JNBE, label, state); } - inline void jncAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNC , label, state); } - inline void jneAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNE , label, state); } - inline void jngAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNG , label, state); } - inline void jngeAndRestore(Label* label, State* state) { _jmpAndRestore(INST_JNGE, label, state); } - inline void jnlAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNL , label, state); } - inline void jnleAndRestore(Label* label, State* state) { _jmpAndRestore(INST_JNLE, label, state); } - inline void jnoAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNO , label, state); } - inline void jnpAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNP , label, state); } - inline void jnsAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNS , label, state); } - inline void jnzAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JNZ , label, state); } - inline void joAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JO , label, state); } - inline void jpAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JP , label, state); } - inline void jpeAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JPE , label, state); } - inline void jpoAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JPO , label, state); } - inline void jsAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JS , label, state); } - inline void jzAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JZ , label, state); } - inline void jmpAndRestore (Label* label, State* state) { _jmpAndRestore(INST_JMP , label, state); } - - // -------------------------------------------------------------------------- - // [Intrinsics] - // -------------------------------------------------------------------------- - - using SerializerIntrinsics::adc; - using SerializerIntrinsics::add; - using SerializerIntrinsics::and_; - using SerializerIntrinsics::cmp; - using SerializerIntrinsics::dec; - using SerializerIntrinsics::inc; - using SerializerIntrinsics::mov; - using SerializerIntrinsics::neg; - using SerializerIntrinsics::not_; - using SerializerIntrinsics::or_; - using SerializerIntrinsics::sbb; - using SerializerIntrinsics::sub; - using SerializerIntrinsics::xor_; - - inline void adc(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_ADC, dst, src); } - inline void adc(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_ADC, dst, src); } - inline void adc(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_ADC, dst, src); } - - inline void add(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_ADD, dst, src); } - inline void add(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_ADD, dst, src); } - inline void add(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_ADD, dst, src); } - - inline void and_(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_AND, dst, src); } - inline void and_(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_AND, dst, src); } - inline void and_(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_AND, dst, src); } - - inline void cmp(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_CMP, dst, src); } - inline void cmp(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_CMP, dst, src); } - inline void cmp(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_CMP, dst, src); } - - inline void dec(const Int32Ref& dst) { op_var32(INST_DEC, dst); } - inline void inc(const Int32Ref& dst) { op_var32(INST_INC, dst); } - inline void neg(const Int32Ref& dst) { op_var32(INST_NEG, dst); } - inline void not_(const Int32Ref& dst) { op_var32(INST_NOT, dst); } - - inline void mov(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_MOV, dst, src); } - inline void mov(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_MOV, dst, src); } - inline void mov(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_MOV, dst, src); } - - inline void or_(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_OR, dst, src); } - inline void or_(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_OR, dst, src); } - inline void or_(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_OR, dst, src); } - - inline void sbb(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_SBB, dst, src); } - inline void sbb(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_SBB, dst, src); } - inline void sbb(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_SBB, dst, src); } - - inline void sub(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_SUB, dst, src); } - inline void sub(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_SUB, dst, src); } - inline void sub(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_SUB, dst, src); } - - inline void xor_(const Register& dst, const Int32Ref& src) { op_reg32_var32(INST_XOR, dst, src); } - inline void xor_(const Int32Ref& dst, const Register& src) { op_var32_reg32(INST_XOR, dst, src); } - inline void xor_(const Int32Ref& dst, const Immediate& src) { op_var32_imm(INST_XOR, dst, src); } - -#if defined(ASMJIT_X64) - inline void adc(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_ADC, dst, src); } - inline void adc(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_ADC, dst, src); } - inline void adc(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_ADC, dst, src); } - - inline void add(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_ADD, dst, src); } - inline void add(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_ADD, dst, src); } - inline void add(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_ADD, dst, src); } - - inline void and_(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_AND, dst, src); } - inline void and_(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_AND, dst, src); } - inline void and_(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_AND, dst, src); } - - inline void cmp(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_CMP, dst, src); } - inline void cmp(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_CMP, dst, src); } - inline void cmp(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_CMP, dst, src); } - - inline void dec(const Int64Ref& dst) { op_var64(INST_DEC, dst); } - inline void inc(const Int64Ref& dst) { op_var64(INST_INC, dst); } - inline void neg(const Int64Ref& dst) { op_var64(INST_NEG, dst); } - inline void not_(const Int64Ref& dst) { op_var64(INST_NOT, dst); } - - inline void mov(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_MOV, dst, src); } - inline void mov(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_MOV, dst, src); } - inline void mov(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_MOV, dst, src); } - - inline void or_(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_OR, dst, src); } - inline void or_(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_OR, dst, src); } - inline void or_(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_OR, dst, src); } - - inline void sbb(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_SBB, dst, src); } - inline void sbb(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_SBB, dst, src); } - inline void sbb(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_SBB, dst, src); } - - inline void sub(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_SUB, dst, src); } - inline void sub(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_SUB, dst, src); } - inline void sub(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_SUB, dst, src); } - - inline void xor_(const Register& dst, const Int64Ref& src) { op_reg64_var64(INST_XOR, dst, src); } - inline void xor_(const Int64Ref& dst, const Register& src) { op_var64_reg64(INST_XOR, dst, src); } - inline void xor_(const Int64Ref& dst, const Immediate& src) { op_var64_imm(INST_XOR, dst, src); } -#endif // ASMJIT_X64 -}; - -// ============================================================================ -// [AsmJit::Compiler] -// ============================================================================ - -//! @brief Compiler - high level code generation. -//! -//! This class is used to store instruction stream and allows to modify -//! it on the fly. It uses different concept than @c AsmJit::Assembler class -//! and in fact @c AsmJit::Assembler is only used as a backend. Compiler never -//! emits machine code and each instruction you use is stored to instruction -//! array instead. This allows to modify instruction stream later and for -//! example to reorder instructions to make better performance. -//! -//! Using @c AsmJit::Compiler moves code generation to higher level. Higher -//! level constructs allows to write more abstract and extensible code that -//! is not possible with pure @c AsmJit::Assembler class. Because -//! @c AsmJit::Compiler needs to create many objects and lifetime of these -//! objects is small (same as @c AsmJit::Compiler lifetime itself) it uses -//! very fast memory management model. This model allows to create object -//! instances in nearly zero time (compared to @c malloc() or @c new() -//! operators) so overhead by creating machine code by @c AsmJit::Compiler -//! is minimized. -//! -//! Code Generation -//! -//! First that is needed to know about compiler is that compiler never emits -//! machine code. It's used as a middleware between @c AsmJit::Assembler and -//! your code. There is also convenience method @c make() that allows to -//! generate machine code directly without creating @c AsmJit::Assembler -//! instance. -//! -//! Example how to generate machine code using @c Assembler and @c Compiler: -//! -//! @code -//! // Assembler instance is low level code generation class that emits -//! // machine code. -//! Assembler a; -//! -//! // Compiler instance is high level code generation class that stores all -//! // instructions in internal representation. -//! Compiler c; -//! -//! // ... put your code using Compiler instance ... -//! -//! // Final step - generate code. AsmJit::Compiler::serialize() will serialize -//! // all instructions into Assembler and this ensures generating real machine -//! // code. -//! c.serialize(a); -//! -//! // Your function -//! void* fn = a.make(); -//! @endcode -//! -//! Example how to generate machine code using only @c Compiler (preferred): -//! -//! @code -//! // Compiler instance is enough. -//! Compiler c; -//! -//! // ... put your code using Compiler instance ... -//! -//! // Your function -//! void* fn = c.make(); -//! @endcode -//! -//! You can see that there is @c AsmJit::Compiler::serialize() function that -//! emits instructions into @c AsmJit::Assembler(). This layered architecture -//! means that each class is used for something different and there is no code -//! duplication. For convenience there is also @c AsmJit::Compiler::make() -//! method that can create your function using @c AsmJit::Assembler, but -//! internally (this is preffered bahavior when using @c AsmJit::Compiler). -//! -//! @c make() allocates memory using global memory manager instance, if your -//! function lifetime is over, you should free that memory by -//! @c AsmJit::MemoryManager::free() method. -//! -//! @code -//! // Compiler instance is enough. -//! Compiler c; -//! -//! // ... put your code using Compiler instance ... -//! -//! // Your function -//! void* fn = c.make(); -//! -//! // Free it if you don't want it anymore -//! // (using global memory manager instance) -//! MemoryManager::global()->free(fn); -//! @endcode -//! -//! Functions -//! -//! To build functions with @c Compiler, see @c AsmJit::Compiler::newFunction() -//! method. -//! -//! Variables -//! -//! Compiler also manages your variables and function arguments. Using manual -//! register allocation is not recommended way and it must be done carefully. -//! See @c AsmJit::VariableRef and related classes how to work with variables -//! and next example how to use AsmJit API to create function and manage them: -//! -//! @code -//! // Compiler and function declaration - void f(int*); -//! Compiler c; -//! Function& f = *c.newFunction(CALL_CONV_DEFAULT, BuildFunction1()); -//! -//! // Get argument variable (it's pointer) -//! PtrRef a1(f.argument(0)); -//! -//! // Create your variables -//! Int32Ref x1(f.newVariable(VARIABLE_TYPE_INT32)); -//! Int32Ref x2(f.newVariable(VARIABLE_TYPE_INT32)); -//! -//! // Init your variables -//! c.mov(x1.r(), 1); -//! c.mov(x2.r(), 2); -//! -//! // ... your code ... -//! c.add(x1.r(), x2.r()); -//! // ... your code ... -//! -//! // Store result to a given pointer in first argument -//! c.mov(dword_ptr(a1.c()), x1.c()); -//! -//! // Make function -//! typedef void (*MyFn)(int*); -//! MyFn fn = function_cast(c.make()); -//! @endcode -//! -//! There was presented small code snippet with variables, but it's needed to -//! explain it more. You can see that there are more variable types that can -//! be used. Most useful variables that can be allocated to general purpose -//! registers are variables wrapped to @c Int32Ref, @c Int64Ref, @c SysIntRef -//! and @c PtrRef. Only @c Int64Ref is limited to 64 bit architecture. -//! @c SysIntRef and @c PtrRef variables are equal and it's size depends to -//! architecture (32 or 64 bits). -//! -//! Compiler is not using variables directly, instead you need to create the -//! function and create variables through @c AsmJit::Function. In code you will -//! always work with @c AsmJit::Compiler and @c AsmJit::Function together. -//! -//! Each variable contains state that describes where it is currently allocated -//! and if it's used. Life of variables is based on reference counting and if -//! variable is dereferenced to zero its life ends. -//! -//! Variable states: -//! -//! - Unused (@c AsmJit::VARIABLE_STATE_UNUSED) - State that is assigned to -//! newly created variables or to not used variables (dereferenced to zero). -//! - In register (@c AsmJit::VARIABLE_STATE_REGISTER) - State that means that -//! variable is currently allocated in register. -//! - In memory (@c AsmJit::VARIABLE_STATE_MEMORY) - State that means that -//! variable is currently only in memory location. -//! -//! When you create new variable, its state is always @c VARIABLE_STATE_UNUSED, -//! allocating it to register or spilling to memory changes this state to -//! @c VARIABLE_STATE_REGISTER or @c VARIABLE_STATE_MEMORY, respectively. -//! During variable lifetime it's usual that its state is changed multiple -//! times. To generate better code, you can control allocating and spilling -//! by using up to four types of methods that allows it (see next list). -//! -//! Explicit variable allocating / spilling methods: -//! -//! - @c VariableRef::alloc() - Explicit method to alloc variable into -//! register. You can use this before loops or code blocks. -//! -//! - @c VariableRef::spill() - Explicit method to spill variable. If variable -//! is in register and you call this method, it's moved to its home memory -//! location. If variable is not in register no operation is performed. -//! -//! Implicit variable allocating / spilling methods: -//! -//! - @c VariableRef::r() - Method used to allocate (if it's not previously -//! allocated) variable to register for read / write. In most cases -//! this is the right method to use in your code. If variable is in -//! memory and you use this method it's allocated and moved to register. -//! If variable is already in register or it's marked as unused this -//! method does nothing. -//! -//! - @c VariableRef::x() - Method used to allocate variable for write only. -//! In AsmJit this means completely overwrite it without using it's value. -//! This method is helpful when you want to prevent from copying variable -//! from memory to register to save one mov() instruction. If you want -//! to clear or set your variable to something it's recommended to use -//! @c VariableRef::x(). -//! -//! - @c VariableRef::c() - Method used to use variable as a constant. -//! Constants means that you will not change that variable or you don't -//! want to mark variable as changed. If variable is not marked as changed -//! and spill happens you will save one mov() instruction that is needed -//! to copy variable from register to its home address. -//! -//! - @c VariableRef::m() - Method used to access variable memory address. If -//! variable is allocated in register and you call this method, it's -//! spilled, in all other cases it does nothing. -//! -//! Next example shows how allocating and spilling works: -//! -//! @code -//! // Small example to show how variable allocating and spilling works -//! -//! // Your compiler -//! Compiler c; -//! -//! // Your variable -//! Int32Ref var = ...; -//! -//! // Make sure variable is spilled -//! var.spill(); -//! -//! // 1. Example: using var.r() -//! c.mov(var.r(), imm(0)); -//! var.spill(); -//! // Generated code: -//! // mov var.reg, [var.home] -//! // mov var.reg, 0 -//! // mov [var.home], var.reg -//! -//! // 2. Example: using var.x() -//! c.mov(var.x(), imm(0)); -//! var.spill(); -//! // Generated code: -//! // --- no alloc, .x() inhibits it. -//! // mov var.reg, 0 -//! // mov [var.home], var.reg -//! -//! // 3. Example: using var.c() -//! c.mov(var.c(), imm(0)); -//! var.spill(); -//! // Generated code: -//! // mov var.reg, [var.home] -//! // mov var.reg, 0 -//! // --- no spill, .c() means that you are not changing it, it's 'c'onstant -//! -//! // 4. Example: using var.m() -//! c.mov(var.m(), imm(0)); -//! var.spill(); -//! // Generated code: -//! // --- no alloc, because we are not allocating it -//! // mov [var.home], 0 -//! // --- no spill, because variable is not allocated -//! -//! // 5. Example: using var.x(), setChanged() -//! c.mov(var.x(),imm(0)); -//! var.setChanged(false); -//! var.spill(); -//! // Generated code: -//! // --- no alloc, .x() inhibits it. -//! // mov var.reg, 0 -//! // --- no spill, setChanged(false) marked variable as unmodified -//! @endcode -//! -//! Please see AsmJit tutorials (testcompiler.cpp and testvariables.cpp) for -//! more complete examples. -//! -//! Intrinsics Extensions -//! -//! Compiler supports extensions to intrinsics implemented in -//! @c AsmJit::Serializer that enables to use variables in instructions without -//! specifying to use it as register or as memory operand. Sometimes is better -//! not to alloc variable for each read or write. There is limitation that you -//! can use variable without specifying if it's in register or in memory -//! location only for one operand. This is because x86/x64 architecture not -//! allows to use two memory operands in one instruction and this could -//! happen without this restriction (two variables in memory). -//! -//! @code -//! // Small example to show how intrinsics extensions works -//! -//! // Your compiler -//! Compiler c; -//! -//! // Your variable -//! Int32Ref var = ...; -//! -//! // Make sure variable is spilled -//! var.spill(); -//! -//! // 1. Example: Allocated variable -//! var.alloc() -//! c.mov(var, imm(0)); -//! var.spill(); -//! // Generated code: -//! // mov var.reg, [var.home] -//! // mov var.reg, 0 -//! // mov [var.home], var.reg -//! -//! // 2. Example: Memory variable -//! c.mov(var, imm(0)); -//! var.spill(); -//! // Generated code: -//! // --- no alloc, we want variable in memory -//! // mov [var.home], 0 -//! // --- no spill, becuase variable in not allocated -//! @endcode -//! -//! Memory Management -//! -//! @c Compiler Memory management follows these rules: -//! - Everything created by @c Compiler is always freed by @c Compiler. -//! - To get decent performance, compiler always uses larger buffer for -//! objects to allocate and when compiler instance is destroyed, this -//! buffer is freed. Destructors of active objects are called when -//! destroying compiler instance. Destructors of abadonded compiler -//! objects are called immediately after abadonding it. -//! -//! This means that you can't use any @c Compiler object after destructing it, -//! it also means that each object like @c Label, @c Variable nad others are -//! created and managed by @c Compiler itself. -//! -//! Compiling process details -//! -//! This section is here for people interested in the compiling process. There -//! are few steps that must be done for each compiled function (or your code). -//! -//! When your Compiler instance is ready, you can create function and add -//! emittables using intrinsics or higher level methods implemented in the -//! @c AsmJit::Compiler. When you are done serializing instructions you will -//! usually call @c AsmJit::Compiler::make() method to serialize all emittables -//! to @c AsmJit::Assembler. Next steps shows what's done internally before code -//! is serialized into @c AsmJit::Assembler -//! (implemented in @c AsmJit::Compiler::serialize() method). -//! -//! 1. All emittables are traversed (from first to last) and method -//! @c AsmJit::Emittable::prepare() is called. This signalizes to all -//! emittables that instruction generation step is over and now they -//! should prepare to code generation. In this step can be processed -//! variables, states, etc... -//! 2. All emittables are traversed (from first to last) and method -//! @c AsmJit::Emittable::emit() is called. In this step each emittable -//! can serialize real assembler instructions into @c AsmJit::Assembler -//! instance. This step also generates function prolog and epilog. -//! 3. All emittables are traversed (from first to last) and method -//! @c AsmJit::Emittable::postEmit() is called. Post emitting is used -//! to embed data after function body (not only user data, but also some -//! helper data that can help generating jumps, variables restore / save -//! sequences, condition blocks). -//! 4. Jump tables data are emitted. -//! -//! When everything here ends, @c AsmJit::Assembler contains binary stream -//! that needs only relocation to be callable. -//! -//! Differences summary to @c AsmJit::Assembler -//! -//! - Instructions are not translated to machine code immediately, they are -//! stored as @c Emmitable's (see @c AsmJit::Instruction). -//! - Each @c Label must be allocated by @c AsmJit::Compiler::newLabel(). -//! - Contains function builder. -//! - Contains register allocator / variables management. -//! - Contains a lot of helper methods to simplify code generation. -struct ASMJIT_API Compiler : public CompilerIntrinsics -{ - //! @brief Create a new @c Compiler instance. - Compiler() ASMJIT_NOTHROW; - //! @brief Destroy @c Compiler instance. - virtual ~Compiler() ASMJIT_NOTHROW; -}; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_COMPILERX86X64_H diff --git a/src/thirdparty/dyndetours/AsmJit/Config.h b/src/thirdparty/dyndetours/AsmJit/Config.h deleted file mode 100644 index 42fb13dfc..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Config.h +++ /dev/null @@ -1,77 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// This file is designed to be changeable. Platform specific changes -// should be applied to this file and this guarantes and never versions -// of AsmJit library will never overwrite generated config files. -// -// So modify this will by your build system or hand. - -// [Guard] -#ifndef _ASMJIT_CONFIG_H -#define _ASMJIT_CONFIG_H - -// [AsmJit - OS] -// -// Provides definitions about your operating system. It's detected by default, -// so override it if you have problems with automatic detection. -// -// #define ASMJIT_WINDOWS 1 -// #define ASMJIT_POSIX 2 - -// [AsmJit - Architecture] -// -// Provides definitions about your cpu architecture. It's detected by default, -// so override it if you have problems with automatic detection. - -// #define ASMJIT_X86 -// #define ASMJIT_X64 - -// [AsmJit - API] -// -// If you are embedding AsmJit library into your project (statically), undef -// ASMJIT_API macro. ASMJIT_HIDDEN macro can contain visibility (used by GCC) -// to hide some AsmJit symbols that shouldn't be never exported. -// -// If you have problems with throw() in compilation time, undef ASMJIT_NOTHROW -// to disable this feature. ASMJIT_NOTHROW marks functions that never throws -// an exception. - -// #define ASMJIT_HIDDEN -#define ASMJIT_API -// #define ASMJIT_NOTHROW - - -// [AsmJit - Memory Management] -// #define ASMJIT_MALLOC ::malloc -// #define ASMJIT_REALLOC ::realloc -// #define ASMJIT_FREE ::free - -// [AsmJit - Debug] -// #define ASMJIT_CRASH() crash() -// #define ASMJIT_ASSERT(exp) do { if (!(exp)) ASMJIT_CRASH(); } while(0) - -// [Guard] -#endif // _ASMJIT_CONFIG_H diff --git a/src/thirdparty/dyndetours/AsmJit/CpuInfo.h b/src/thirdparty/dyndetours/AsmJit/CpuInfo.h deleted file mode 100644 index 565cebe63..000000000 --- a/src/thirdparty/dyndetours/AsmJit/CpuInfo.h +++ /dev/null @@ -1,216 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_CPUINFO_H -#define _ASMJIT_CPUINFO_H - -// [Dependencies] -#include "Build.h" - -// [Warnings-Push] -#include "WarningsPush.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_CpuInfo -//! @{ - -// ============================================================================ -// [AsmJit::CpuId] -// ============================================================================ - -#if defined(ASMJIT_X86) || defined(ASMJIT_X64) -//! @brief Structure (union) used by cpuid() function. -union CpuId -{ - //! @brief cpuid results array(eax, ebx, ecx and edx registers). - UInt32 i[4]; - - struct - { - //! @brief cpuid result in eax register. - UInt32 eax; - //! @brief cpuid result in ebx register. - UInt32 ebx; - //! @brief cpuid result in ecx register. - UInt32 ecx; - //! @brief cpuid result in edx register. - UInt32 edx; - }; -}; - -//! @brief Calls CPUID instruction with eax == @a in and returns result to @a out. -//! -//! @c cpuid() function has one input parameter that is passed to cpuid through -//! eax register and results in four output values representing result of cpuid -//! instruction (eax, ebx, ecx and edx registers). -ASMJIT_API void cpuid(UInt32 in, CpuId* out) ASMJIT_NOTHROW; -#endif // ASMJIT_X86 || ASMJIT_X64 - -// ============================================================================ -// [AsmJit::CpuInfo] -// ============================================================================ - -//! @brief Informations about host cpu. -struct ASMJIT_HIDDEN CpuInfo -{ - //! @brief Cpu short vendor string. - char vendor[16]; - //! @brief Cpu vendor id (see @c AsmJit::CpuInfo::VendorId enum). - UInt32 vendorId; - //! @brief Cpu family ID. - UInt32 family; - //! @brief Cpu model ID. - UInt32 model; - //! @brief Cpu stepping. - UInt32 stepping; - //! @brief Number of processors or cores. - UInt32 numberOfProcessors; - //! @brief Cpu features bitfield, see @c AsmJit::CpuInfo::Feature enum). - UInt32 features; - //! @brief Cpu bugs bitfield, see @c AsmJit::CpuInfo::Bug enum). - UInt32 bugs; - - //! @brief Cpu vendor IDs. - //! - //! Cpu vendor IDs are specific for AsmJit library. Vendor ID is not directly - //! read from cpuid result, instead it's based on CPU vendor string. - enum VendorId - { - //! @brief Unknown vendor. - Vendor_Unknown = 0, - //! @brief Intel vendor (GenuineIntel vendor string). - Vendor_INTEL = 1, - //! @brief AMD vendor (AuthenticAMD or alternatively AMDisbetter! vendor strings). - Vendor_AMD = 2, - //! @brief VIA vendor (VIA VIA VIA vendor string). - Vendor_VIA = 3 - }; - -#if defined(ASMJIT_X86) || defined(ASMJIT_X64) - //! @brief Extended informations for x86/x64 compatible processors. - struct X86ExtendedInfo - { - UInt32 processorType; - UInt32 brandIndex; - UInt32 clFlushCacheLineSize; - UInt32 logicalProcessors; - UInt32 apicPhysicalId; - }; - X86ExtendedInfo x86ExtendedInfo; - - //! @brief X86/X64 CPU features. - enum Feature - { - //! @brief Cpu has RDTSC instruction. - Feature_RDTSC = 1U << 0, - //! @brief Cpu has RDTSCP instruction. - Feature_RDTSCP = 1U << 1, - //! @brief Cpu has CMOV instruction (conditional move) - Feature_CMOV = 1U << 2, - //! @brief Cpu has CMPXCHG8B instruction - Feature_CMPXCHG8B = 1U << 3, - //! @brief Cpu has CMPXCHG16B instruction (64 bit processors) - Feature_CMPXCHG16B = 1U << 4, - //! @brief Cpu has CLFUSH instruction - Feature_CLFLUSH = 1U << 5, - //! @brief Cpu has PREFETCH instruction - Feature_PREFETCH = 1U << 6, - //! @brief Cpu supports LAHF and SAHF instrictions. - Feature_LAHF_SAHF = 1U << 7, - //! @brief Cpu supports FXSAVE and FXRSTOR instructions. - Feature_FXSR = 1U << 8, - //! @brief Cpu supports FXSAVE and FXRSTOR instruction optimizations (FFXSR). - Feature_FFXSR = 1U << 9, - - //! @brief Cpu has MMX. - Feature_MMX = 1U << 10, - //! @brief Cpu has extended MMX. - Feature_MMXExt = 1U << 11, - //! @brief Cpu has 3dNow! - Feature_3dNow = 1U << 12, - //! @brief Cpu has enchanced 3dNow! - Feature_3dNowExt = 1U << 13, - //! @brief Cpu has SSE. - Feature_SSE = 1U << 14, - //! @brief Cpu has Misaligned SSE (MSSE). - Feature_MSSE = 1U << 15, - //! @brief Cpu has SSE2. - Feature_SSE2 = 1U << 16, - //! @brief Cpu has SSE3. - Feature_SSE3 = 1U << 17, - //! @brief Cpu has Supplemental SSE3 (SSSE3). - Feature_SSSE3 = 1U << 18, - //! @brief Cpu has SSE4.A. - Feature_SSE4_A = 1U << 19, - //! @brief Cpu has SSE4.1. - Feature_SSE4_1 = 1U << 20, - //! @brief Cpu has SSE4.2. - Feature_SSE4_2 = 1U << 21, - //! @brief Cpu has SSE5. - Feature_SSE5 = 1U << 22, - //! @brief Cpu supports MONITOR and MWAIT instructions. - Feature_MonitorMWait = 1U << 23, - //! @brief Cpu supports POPCNT instruction. - Feature_POPCNT = 1U << 24, - //! @brief Cpu supports LZCNT instruction. - Feature_LZCNT = 1U << 25, - //! @brief Cpu supports multithreading. - Feature_MultiThreading = 1U << 29, - //! @brief Cpu supports execute disable bit (execute protection). - Feature_ExecuteDisableBit = 1U << 30, - //! @brief Cpu supports 64 bits. - Feature_64Bit = 1U << 31 - }; - - //! @brief X86/X64 CPU bugs. - enum Bug - { - Bug_AmdLockMB = 1U << 0 - }; - -#endif // ASMJIT_X86 || ASMJIT_X64 -}; - -//! @brief Detect CPU features to CpuInfo structure @a i. -//! -//! @sa @c CpuInfo. -ASMJIT_API void detectCpuInfo(CpuInfo* i) ASMJIT_NOTHROW; - -//! @brief Return CpuInfo (detection is done only once). -//! -//! @sa @c CpuInfo. -ASMJIT_API CpuInfo* cpuInfo() ASMJIT_NOTHROW; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_CPUINFO_H diff --git a/src/thirdparty/dyndetours/AsmJit/Defs.h b/src/thirdparty/dyndetours/AsmJit/Defs.h deleted file mode 100644 index f92f8c9d7..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Defs.h +++ /dev/null @@ -1,198 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_DEFS_H -#define _ASMJIT_DEFS_H - -// [Dependencies] -#include "Build.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_Defs -//! @{ - -// ============================================================================ -// [AsmJit::ERROR_CODE] -// ============================================================================ - -//! @brief AsmJit error codes. -enum ERROR_CODE -{ - //! @brief No error (success). - //! - //! This is default state and state you want. - ERROR_NONE = 0, - - //! @brief Memory allocation error (@c ASMJIT_MALLOC returned @c NULL). - ERROR_NO_HEAP_MEMORY = 1, - - //! @brief Virtual memory allocation error (@c VirtualMemory returned @c NULL). - ERROR_NO_VIRTUAL_MEMORY = 2, - - //! @brief Unknown instruction. This happens only if instruction code is - //! out of bounds. Shouldn't happen. - ERROR_UNKNOWN_INSTRUCTION = 3, - - //! @brief Illegal instruction, usually generated by AsmJit::AssemblerCore - //! class when emitting instruction opcode. If this error is generated the - //! target buffer is not affected by this invalid instruction. - //! - //! In debug mode you get assertion failure instead. - ERROR_ILLEGAL_INSTRUCTION = 4, - - //! @brief Illegal addressing used (unencodable). - ERROR_ILLEGAL_ADDRESING = 5, - - //! @brief Short jump instruction used, but displacement is out of bounds. - ERROR_ILLEGAL_SHORT_JUMP = 6, - - //! @brief Count of error codes by AsmJit. Can grow in future. - _ERROR_COUNT -}; - -// ============================================================================ -// [AsmJit::OP] -// ============================================================================ - -//! @brief Operand types that can be encoded in @c Op operand. -enum OP -{ - //! @brief Operand is none, used only internally (not initialized Operand). - //! - //! This operand is not valid. - OP_NONE = 0, - - //! @brief Operand is register. - OP_REG = 1, - //! @brief Operand is memory. - OP_MEM = 2, - //! @brief Operand is immediate. - OP_IMM = 3, - //! @brief Operand is label. - OP_LABEL = 4, - //! @brief Operand is variable. - OP_VAR = 5 -}; - -// ============================================================================ -// [AsmJit::SIZE] -// ============================================================================ - -//! @brief Size of registers and pointers. -enum SIZE -{ - //! @brief 1 byte size. - SIZE_BYTE = 1, - //! @brief 2 bytes size. - SIZE_WORD = 2, - //! @brief 4 bytes size. - SIZE_DWORD = 4, - //! @brief 8 bytes size. - SIZE_QWORD = 8, - //! @brief 10 bytes size. - SIZE_TWORD = 10, - //! @brief 16 bytes size. - SIZE_DQWORD = 16 -}; - -// ============================================================================ -// [AsmJit::RELOC_MODE] -// ============================================================================ - -//! @brief Relocation info. -enum RELOC_MODE -{ - //! @brief No relocation. - RELOC_NONE = 0, - - //! @brief Overwrite relocation (immediates as constants). - RELOC_OVERWRITE = 1 -}; - -// ============================================================================ -// [AsmJit::LABEL_STATE] -// ============================================================================ - -//! @brief Label state. -enum LABEL_STATE -{ - //! @brief Label is unused. - LABEL_STATE_UNUSED = 0, - //! @brief Label is linked (waiting to be bound) - LABEL_STATE_LINKED = 1, - //! @brief Label is bound - LABEL_STATE_BOUND = 2 -}; - -// ============================================================================ -// [AsmJit::PROPERTY] -// ============================================================================ - -//! @brief @c Assembler/Compiler properties. -enum PROPERTY -{ - //! @brief Optimize align for current processor. - //! - //! Default: @c true. - PROPERTY_OPTIMIZE_ALIGN = 0, - - //! @brief Force rex prefix emitting. - //! - //! Default: @c false. - //! - //! @note This is X86/X86 property only. - PROPERTY_X86_FORCE_REX = 1, - - //! @brief Emit hints added to jcc() instructions. - //! - //! Default: @c true. - //! - //! @note This is X86/X86 property only. - PROPERTY_X86_JCC_HINTS = 2 -}; - -// ============================================================================ -// [AsmJit::API] -// ============================================================================ - -//! @brief Translates error code (see @c ERROR_CODE) into text representation. -ASMJIT_API const char* errorCodeToString(UInt32 error) ASMJIT_NOTHROW; - -//! @} - -} // AsmJit namespace - -// ============================================================================ -// [AsmJit::Definitions - X86 / X64] -// ============================================================================ - -#if defined(ASMJIT_X86) || defined(ASMJIT_X64) -#include "DefsX86X64.h" -#endif // ASMJIT_X86 || ASMJIT_X64 - -// [Guard] -#endif // _ASMJIT_DEFS_H diff --git a/src/thirdparty/dyndetours/AsmJit/DefsX86X64.h b/src/thirdparty/dyndetours/AsmJit/DefsX86X64.h deleted file mode 100644 index 9a17acfd7..000000000 --- a/src/thirdparty/dyndetours/AsmJit/DefsX86X64.h +++ /dev/null @@ -1,1067 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_DEFSX86X64_H -#define _ASMJIT_DEFSX86X64_H - -// [Dependencies] -#include "Build.h" -#include "Util.h" - -#include -#include - -// [Warnings-Push] -#include "WarningsPush.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_Defs -//! @{ - -// ============================================================================ -// [AsmJit::RID] -// ============================================================================ - -//! @brief Valid X86 register IDs. -//! -//! These codes are real, don't miss with @c REG enum! and don't use these -//! values if you are not writing @c AsmJit::Serializer backend. -enum RID -{ - //! @brief ID for AX/EAX/RAX registers. - RID_EAX = 0, - //! @brief ID for CX/ECX/RCX registers. - RID_ECX = 1, - //! @brief ID for DX/EDX/RDX registers. - RID_EDX = 2, - //! @brief ID for BX/EBX/RBX registers. - RID_EBX = 3, - //! @brief ID for SP/ESP/RSP registers. - RID_ESP = 4, - //! @brief ID for BP/EBP/RBP registers. - RID_EBP = 5, - //! @brief ID for SI/ESI/RSI registers. - RID_ESI = 6, - //! @brief ID for DI/EDI/RDI registers. - RID_EDI = 7 -}; - -// ============================================================================ -// [AsmJit::REG] -// ============================================================================ - -//! @brief Pseudo (not real X86) register codes used for generating opcodes. -//! -//! From this register code can be generated real x86 register ID, type of -//! register and size of register. -enum REG -{ - //! @brief Mask for register type. - REGTYPE_MASK = 0xF0, - //! @brief Mask for register code (index). - REGCODE_MASK = 0x0F, - - // First nibble contains register type (mask 0xF0), Second nibble contains - // register index code. - - // [8 bit, 16 bit and 32 bit general purpose registers] - - //! @brief 8 bit general purpose register type. - REG_GPB = 0x00, - //! @brief 16 bit general purpose register type. - REG_GPW = 0x10, - //! @brief 32 bit general purpose register type. - REG_GPD = 0x20, - - // [64 bit registers (RAX, RBX, ...), not available in 32 bit mode] - - //! @brief 64 bit general purpose register type. - REG_GPQ = 0x30, - - //! @var REG_GPN - //! @brief 32 bit or 64 bit general purpose register type. - - // native 32 bit or 64 bit registers -#if defined(ASMJIT_X86) - REG_GPN = REG_GPD, -#else - REG_GPN = REG_GPQ, -#endif - - //! @brief X87 (FPU) register type. - REG_X87 = 0x50, - - //! @brief 64 bit mmx register type. - REG_MM = 0x60, - - //! @brief 128 bit sse register type. - REG_XMM = 0x70, - - // 8/16 bit registers - REG_AL = REG_GPB , REG_CL , REG_DL , REG_BL , REG_AH , REG_CH , REG_DH , REG_BH , -#if defined(ASMJIT_X64) - REG_R8B , REG_R9B , REG_R10B , REG_R11B , REG_R12B , REG_R13B , REG_R14B , REG_R15B , -#endif // ASMJIT_X64 - REG_AX = REG_GPW , REG_CX , REG_DX , REG_BX , REG_SP , REG_BP , REG_SI , REG_DI , -#if defined(ASMJIT_X64) - REG_R8W , REG_R9W , REG_R10W , REG_R11W , REG_R12W , REG_R13W , REG_R14W , REG_R15W , -#endif // ASMJIT_X64 - - // 32 bit registers - REG_EAX = REG_GPD , REG_ECX , REG_EDX , REG_EBX , REG_ESP , REG_EBP , REG_ESI , REG_EDI , -#if defined(ASMJIT_X64) - REG_R8D , REG_R9D , REG_R10D , REG_R11D , REG_R12D , REG_R13D , REG_R14D , REG_R15D , -#endif // ASMJIT_X64 - - // 64 bit registers -#if defined(ASMJIT_X64) - REG_RAX = REG_GPQ , REG_RCX , REG_RDX , REG_RBX , REG_RSP , REG_RBP , REG_RSI , REG_RDI , - REG_R8 , REG_R9 , REG_R10 , REG_R11 , REG_R12 , REG_R13 , REG_R14 , REG_R15 , -#endif // ASMJIT_X64 - - // MMX registers - REG_MM0 = REG_MM , REG_MM1 , REG_MM2 , REG_MM3 , REG_MM4 , REG_MM5 , REG_MM6 , REG_MM7 , - - // SSE registers - REG_XMM0 = REG_XMM , REG_XMM1 , REG_XMM2 , REG_XMM3 , REG_XMM4 , REG_XMM5 , REG_XMM6 , REG_XMM7 , -#if defined(ASMJIT_X64) - REG_XMM8 , REG_XMM9 , REG_XMM10, REG_XMM11, REG_XMM12, REG_XMM13, REG_XMM14, REG_XMM15, -#endif // ASMJIT_X64 - - // native registers (depends if processor runs in 32 bit or 64 bit mode) -#if defined(ASMJIT_X86) - REG_NAX = REG_GPD , REG_NCX , REG_NDX , REG_NBX , REG_NSP , REG_NBP , REG_NSI , REG_NDI , -#else - REG_NAX = REG_GPQ , REG_NCX , REG_NDX , REG_NBX , REG_NSP , REG_NBP , REG_NSI , REG_NDI , -#endif - - //! @brief Invalid register code. - NO_REG = 0xFF -}; - -//! @var NUM_REGS -//! @brief Count of General purpose registers and SSE registers. - -#if defined(ASMJIT_X86) -enum { NUM_REGS = 8 }; -#else -enum { NUM_REGS = 16 }; -#endif // ASMJIT - -// ============================================================================ -// [AsmJit::SEGMENT] -// ============================================================================ - -//! @brief Segment override prefixes. -enum SEGMENT -{ - // DO NOT MODIFY INDEX CODES - They are used by logger in this order. - - //! @brief No segment override prefix. - SEGMENT_NONE = 0, - //! @brief Use 'cs' segment override prefix. - SEGMENT_CS = 1, - //! @brief Use 'ss' segment override prefix. - SEGMENT_SS = 2, - //! @brief Use 'ds' segment override prefix. - SEGMENT_DS = 3, - //! @brief Use 'es' segment override prefix. - SEGMENT_ES = 4, - //! @brief Use 'fs' segment override prefix. - SEGMENT_FS = 5, - //! @brief Use 'gs' segment override prefix. - SEGMENT_GS = 6, - //! @brief End of prefix codes - _SEGMENT_END -}; - -// ============================================================================ -// [AsmJit::PREFETCH_HINT] -// ============================================================================ - -//! @brief Prefetch hints. -enum PREFETCH_HINT -{ - //! @brief Prefetch to L0 cache. - PREFETCH_T0 = 1, - //! @brief Prefetch to L1 cache. - PREFETCH_T1 = 2, - //! @brief Prefetch to L2 cache. - PREFETCH_T2 = 3, - //! @brief Prefetch using NT hint. - PREFETCH_NTA = 0 -}; - -// ============================================================================ -// [AsmJit::CONDITION] -// ============================================================================ - -//! @brief Condition codes. -enum CONDITION -{ - //! @brief No condition code. - C_NO_CONDITION = -1, - - // Condition codes from processor manuals. - C_A = 0x7, - C_AE = 0x3, - C_B = 0x2, - C_BE = 0x6, - C_C = 0x2, - C_E = 0x4, - C_G = 0xF, - C_GE = 0xD, - C_L = 0xC, - C_LE = 0xE, - C_NA = 0x6, - C_NAE = 0x2, - C_NB = 0x3, - C_NBE = 0x7, - C_NC = 0x3, - C_NE = 0x5, - C_NG = 0xE, - C_NGE = 0xC, - C_NL = 0xD, - C_NLE = 0xF, - C_NO = 0x1, - C_NP = 0xB, - C_NS = 0x9, - C_NZ = 0x5, - C_O = 0x0, - C_P = 0xA, - C_PE = 0xA, - C_PO = 0xB, - C_S = 0x8, - C_Z = 0x4, - - // Simplified condition codes - C_OVERFLOW = 0x0, - C_NO_OVERFLOW = 0x1, - C_BELOW = 0x2, - C_ABOVE_EQUAL = 0x3, - C_EQUAL = 0x4, - C_NOT_EQUAL = 0x5, - C_BELOW_EQUAL = 0x6, - C_ABOVE = 0x7, - C_SIGN = 0x8, - C_NOT_SIGN = 0x9, - C_PARITY_EVEN = 0xA, - C_PARITY_ODD = 0xB, - C_LESS = 0xC, - C_GREATER_EQUAL = 0xD, - C_LESS_EQUAL = 0xE, - C_GREATER = 0xF, - - // aliases - C_ZERO = 0x4, - C_NOT_ZERO = 0x5, - C_NEGATIVE = 0x8, - C_POSITIVE = 0x9, - - // x87 floating point only - C_FP_UNORDERED = 16, - C_FP_NOT_UNORDERED = 17 -}; - -//! @brief Returns the equivalent of !cc. -//! -//! Negation of the default no_condition (-1) results in a non-default -//! no_condition value (-2). As long as tests for no_condition check -//! for condition < 0, this will work as expected. -static inline CONDITION negateCondition(CONDITION cc) -{ - return static_cast(cc ^ 1); -} - -//! @brief Corresponds to transposing the operands of a comparison. -static inline CONDITION reverseCondition(CONDITION cc) -{ - switch (cc) { - case C_BELOW: - return C_ABOVE; - case C_ABOVE: - return C_BELOW; - case C_ABOVE_EQUAL: - return C_BELOW_EQUAL; - case C_BELOW_EQUAL: - return C_ABOVE_EQUAL; - case C_LESS: - return C_GREATER; - case C_GREATER: - return C_LESS; - case C_GREATER_EQUAL: - return C_LESS_EQUAL; - case C_LESS_EQUAL: - return C_GREATER_EQUAL; - default: - return cc; - }; -} - -// ============================================================================ -// [AsmJit::SCALE] -// ============================================================================ - -//! @brief Scale, can be used for addressing. -//! -//! See @c Op and addressing methods like @c byte_ptr(), @c word_ptr(), -//! @c dword_ptr(), etc... -enum SCALE -{ - //! @brief Scale 1 times (no scale). - TIMES_1 = 0, - //! @brief Scale 2 times (same as shifting to left by 1). - TIMES_2 = 1, - //! @brief Scale 4 times (same as shifting to left by 2). - TIMES_4 = 2, - //! @brief Scale 8 times (same as shifting to left by 3). - TIMES_8 = 3 -}; - -// ============================================================================ -// [AsmJit::HINT] -// ============================================================================ - -//! @brief Condition hint, see @c AsmJit::Serializer::jz() and friends. -enum HINT -{ - //! @brief No hint. - HINT_NONE = 0x00, - //! @brief Condition will be taken (likely). - HINT_TAKEN = 0x01, - //! @brief Condition will be not taken (unlikely). - HINT_NOT_TAKEN = 0x02 -}; - -//! @brief Hint byte value is the byte that will be emitted if hint flag -//! is specified by @c HINT. -enum HINT_BYTE_VALUE -{ - //! @brief Condition will be taken (likely). - HINT_BYTE_VALUE_TAKEN = 0x3E, - //! @brief Condition will be not taken (unlikely). - HINT_BYTE_VALUE_NOT_TAKEN = 0x2E -}; - -// ============================================================================ -// [AsmJit::FP_STATUS] -// ============================================================================ - -//! @brief Floating point status. -enum FP_STATUS -{ - FP_C0 = 0x100, - FP_C1 = 0x200, - FP_C2 = 0x400, - FP_C3 = 0x4000, - FP_CC_MASK = 0x4500 -}; - -// ============================================================================ -// [AsmJit::FP_CW] -// ============================================================================ - -//! @brief Floating point control word. -enum FP_CW -{ - FP_CW_INVOPEX_MASK = 0x001, - FP_CW_DENOPEX_MASK = 0x002, - FP_CW_ZERODIV_MASK = 0x004, - FP_CW_OVFEX_MASK = 0x008, - FP_CW_UNDFEX_MASK = 0x010, - FP_CW_PRECEX_MASK = 0x020, - FP_CW_PRECC_MASK = 0x300, - FP_CW_ROUNDC_MASK = 0xC00, - - // Values for precision control. - FP_CW_PREC_SINGLE = 0x000, - FP_CW_PREC_DOUBLE = 0x200, - FP_CW_PREC_EXTENDED = 0x300, - - // Values for rounding control. - FP_CW_ROUND_NEAREST = 0x000, - FP_CW_ROUND_DOWN = 0x400, - FP_CW_ROUND_UP = 0x800, - FP_CW_ROUND_TOZERO = 0xC00 -}; - -// ============================================================================ -// [AsmJit::INST_CODE] -// ============================================================================ - -//! @brief Instruction codes. -//! -//! Note that these instruction codes are AsmJit specific. Each instruction is -//! unique ID into AsmJit instruction table. Instruction codes are used together -//! with AsmJit::Assembler and you can also use instruction codes to serialize -//! instructions by AsmJit::SerializerCore::_emitX86(). -enum INST_CODE -{ - INST_ADC, // X86/X64 - INST_ADD, // X86/X64 - INST_ADDPD, - INST_ADDPS, - INST_ADDSD, - INST_ADDSS, - INST_ADDSUBPD, - INST_ADDSUBPS, - INST_AMD_PREFETCH, - INST_AMD_PREFETCHW, - INST_AND, // X86/X64 - INST_ANDNPD, - INST_ANDNPS, - INST_ANDPD, - INST_ANDPS, - INST_BLENDPD, - INST_BLENDPS, - INST_BLENDVPD, - INST_BLENDVPS, - INST_BSF, // X86/X64 - INST_BSR, // X86/X64 - INST_BSWAP, // X86/X64 (i486) - INST_BT, // X86/X64 - INST_BTC, // X86/X64 - INST_BTR, // X86/X64 - INST_BTS, // X86/X64 - INST_CALL, // X86/X64 - INST_CBW, // X86/X64 - INST_CDQE, // X64 only - INST_CLC, // X86/X64 - INST_CLD, // X86/X64 - INST_CLFLUSH, - INST_CMC, // X86/X64 - - INST_CMOV, // Begin (cmovcc) (i586) - INST_CMOVA = INST_CMOV, //X86/X64 (cmovcc) (i586) - INST_CMOVAE, // X86/X64 (cmovcc) (i586) - INST_CMOVB, // X86/X64 (cmovcc) (i586) - INST_CMOVBE, // X86/X64 (cmovcc) (i586) - INST_CMOVC, // X86/X64 (cmovcc) (i586) - INST_CMOVE, // X86/X64 (cmovcc) (i586) - INST_CMOVG, // X86/X64 (cmovcc) (i586) - INST_CMOVGE, // X86/X64 (cmovcc) (i586) - INST_CMOVL, // X86/X64 (cmovcc) (i586) - INST_CMOVLE, // X86/X64 (cmovcc) (i586) - INST_CMOVNA, // X86/X64 (cmovcc) (i586) - INST_CMOVNAE, // X86/X64 (cmovcc) (i586) - INST_CMOVNB, // X86/X64 (cmovcc) (i586) - INST_CMOVNBE, // X86/X64 (cmovcc) (i586) - INST_CMOVNC, // X86/X64 (cmovcc) (i586) - INST_CMOVNE, // X86/X64 (cmovcc) (i586) - INST_CMOVNG, // X86/X64 (cmovcc) (i586) - INST_CMOVNGE, // X86/X64 (cmovcc) (i586) - INST_CMOVNL, // X86/X64 (cmovcc) (i586) - INST_CMOVNLE, // X86/X64 (cmovcc) (i586) - INST_CMOVNO, // X86/X64 (cmovcc) (i586) - INST_CMOVNP, // X86/X64 (cmovcc) (i586) - INST_CMOVNS, // X86/X64 (cmovcc) (i586) - INST_CMOVNZ, // X86/X64 (cmovcc) (i586) - INST_CMOVO, // X86/X64 (cmovcc) (i586) - INST_CMOVP, // X86/X64 (cmovcc) (i586) - INST_CMOVPE, // X86/X64 (cmovcc) (i586) - INST_CMOVPO, // X86/X64 (cmovcc) (i586) - INST_CMOVS, // X86/X64 (cmovcc) (i586) - INST_CMOVZ, // X86/X64 (cmovcc) (i586) - - INST_CMP, // X86/X64 - INST_CMPPD, - INST_CMPPS, - INST_CMPSD, - INST_CMPSS, - INST_CMPXCHG, // X86/X64 (i486) - INST_CMPXCHG16B, // X64 only - INST_CMPXCHG8B, // X86/X64 (i586) - INST_COMISD, - INST_COMISS, - INST_CPUID, // X86/X64 (i486) - INST_CRC32, - INST_CVTDQ2PD, - INST_CVTDQ2PS, - INST_CVTPD2DQ, - INST_CVTPD2PI, - INST_CVTPD2PS, - INST_CVTPI2PD, - INST_CVTPI2PS, - INST_CVTPS2DQ, - INST_CVTPS2PD, - INST_CVTPS2PI, - INST_CVTSD2SI, - INST_CVTSD2SS, - INST_CVTSI2SD, - INST_CVTSI2SS, - INST_CVTSS2SD, - INST_CVTSS2SI, - INST_CVTTPD2DQ, - INST_CVTTPD2PI, - INST_CVTTPS2DQ, - INST_CVTTPS2PI, - INST_CVTTSD2SI, - INST_CVTTSS2SI, - INST_CWDE, // X86/X64 - INST_DAA, // X86 only - INST_DAS, // X86 only - INST_DEC, // X86/X64 - INST_DIV, // X86/X64 - INST_DIVPD, - INST_DIVPS, - INST_DIVSD, - INST_DIVSS, - INST_DPPD, - INST_DPPS, - INST_EMMS, // MMX - INST_ENTER, // X86/X64 - INST_EXTRACTPS, - INST_F2XM1, // X87 - INST_FABS, // X87 - INST_FADD, // X87 - INST_FADDP, // X87 - INST_FBLD, // X87 - INST_FBSTP, // X87 - INST_FCHS, // X87 - INST_FCLEX, // X87 - INST_FCMOVB, // X87 - INST_FCMOVBE, // X87 - INST_FCMOVE, // X87 - INST_FCMOVNB, // X87 - INST_FCMOVNBE, // X87 - INST_FCMOVNE, // X87 - INST_FCMOVNU, // X87 - INST_FCMOVU, // X87 - INST_FCOM, // X87 - INST_FCOMI, // X87 - INST_FCOMIP, // X87 - INST_FCOMP, // X87 - INST_FCOMPP, // X87 - INST_FCOS, // X87 - INST_FDECSTP, // X87 - INST_FDIV, // X87 - INST_FDIVP, // X87 - INST_FDIVR, // X87 - INST_FDIVRP, // X87 - INST_FEMMS, // 3dNow! - INST_FFREE, // X87 - INST_FIADD, // X87 - INST_FICOM, // X87 - INST_FICOMP, // X87 - INST_FIDIV, // X87 - INST_FIDIVR, // X87 - INST_FILD, // X87 - INST_FIMUL, // X87 - INST_FINCSTP, // X87 - INST_FINIT, // X87 - INST_FIST, // X87 - INST_FISTP, // X87 - INST_FISTTP, - INST_FISUB, // X87 - INST_FISUBR, // X87 - INST_FLD, // X87 - INST_FLD1, // X87 - INST_FLDCW, // X87 - INST_FLDENV, // X87 - INST_FLDL2E, // X87 - INST_FLDL2T, // X87 - INST_FLDLG2, // X87 - INST_FLDLN2, // X87 - INST_FLDPI, // X87 - INST_FLDZ, // X87 - INST_FMUL, // X87 - INST_FMULP, // X87 - INST_FNCLEX, // X87 - INST_FNINIT, // X87 - INST_FNOP, // X87 - INST_FNSAVE, // X87 - INST_FNSTCW, // X87 - INST_FNSTENV, // X87 - INST_FNSTSW, // X87 - INST_FPATAN, // X87 - INST_FPREM, // X87 - INST_FPREM1, // X87 - INST_FPTAN, // X87 - INST_FRNDINT, // X87 - INST_FRSTOR, // X87 - INST_FSAVE, // X87 - INST_FSCALE, // X87 - INST_FSIN, // X87 - INST_FSINCOS, // X87 - INST_FSQRT, // X87 - INST_FST, // X87 - INST_FSTCW, // X87 - INST_FSTENV, // X87 - INST_FSTP, // X87 - INST_FSTSW, // X87 - INST_FSUB, // X87 - INST_FSUBP, // X87 - INST_FSUBR, // X87 - INST_FSUBRP, // X87 - INST_FTST, // X87 - INST_FUCOM, // X87 - INST_FUCOMI, // X87 - INST_FUCOMIP, // X87 - INST_FUCOMP, // X87 - INST_FUCOMPP, // X87 - INST_FWAIT, // X87 - INST_FXAM, // X87 - INST_FXCH, // X87 - INST_FXRSTOR, // X87 - INST_FXSAVE, // X87 - INST_FXTRACT, // X87 - INST_FYL2X, // X87 - INST_FYL2XP1, // X87 - INST_HADDPD, - INST_HADDPS, - INST_HSUBPD, - INST_HSUBPS, - INST_IDIV, // X86/X64 - INST_IMUL, // X86/X64 - INST_INC, // X86/X64 - INST_INT3, // X86/X64 - - INST_J, // Begin (jcc) - INST_JA = INST_J, // X86/X64 (jcc) - INST_JAE, // X86/X64 (jcc) - INST_JB, // X86/X64 (jcc) - INST_JBE, // X86/X64 (jcc) - INST_JC, // X86/X64 (jcc) - INST_JE, // X86/X64 (jcc) - INST_JG, // X86/X64 (jcc) - INST_JGE, // X86/X64 (jcc) - INST_JL, // X86/X64 (jcc) - INST_JLE, // X86/X64 (jcc) - INST_JNA, // X86/X64 (jcc) - INST_JNAE, // X86/X64 (jcc) - INST_JNB, // X86/X64 (jcc) - INST_JNBE, // X86/X64 (jcc) - INST_JNC, // X86/X64 (jcc) - INST_JNE, // X86/X64 (jcc) - INST_JNG, // X86/X64 (jcc) - INST_JNGE, // X86/X64 (jcc) - INST_JNL, // X86/X64 (jcc) - INST_JNLE, // X86/X64 (jcc) - INST_JNO, // X86/X64 (jcc) - INST_JNP, // X86/X64 (jcc) - INST_JNS, // X86/X64 (jcc) - INST_JNZ, // X86/X64 (jcc) - INST_JO, // X86/X64 (jcc) - INST_JP, // X86/X64 (jcc) - INST_JPE, // X86/X64 (jcc) - INST_JPO, // X86/X64 (jcc) - INST_JS, // X86/X64 (jcc) - INST_JZ, // X86/X64 (jcc) - INST_JMP, // X86/X64 (jmp) - - INST_J_SHORT, // Begin (jcc short) - INST_JA_SHORT = INST_J_SHORT, // X86/X64 (jcc short) - INST_JAE_SHORT, // X86/X64 (jcc short) - INST_JB_SHORT, // X86/X64 (jcc short) - INST_JBE_SHORT, // X86/X64 (jcc short) - INST_JC_SHORT, // X86/X64 (jcc short) - INST_JE_SHORT, // X86/X64 (jcc short) - INST_JG_SHORT, // X86/X64 (jcc short) - INST_JGE_SHORT, // X86/X64 (jcc short) - INST_JL_SHORT, // X86/X64 (jcc short) - INST_JLE_SHORT, // X86/X64 (jcc short) - INST_JNA_SHORT, // X86/X64 (jcc short) - INST_JNAE_SHORT, // X86/X64 (jcc short) - INST_JNB_SHORT, // X86/X64 (jcc short) - INST_JNBE_SHORT, // X86/X64 (jcc short) - INST_JNC_SHORT, // X86/X64 (jcc short) - INST_JNE_SHORT, // X86/X64 (jcc short) - INST_JNG_SHORT, // X86/X64 (jcc short) - INST_JNGE_SHORT, // X86/X64 (jcc short) - INST_JNL_SHORT, // X86/X64 (jcc short) - INST_JNLE_SHORT, // X86/X64 (jcc short) - INST_JNO_SHORT, // X86/X64 (jcc short) - INST_JNP_SHORT, // X86/X64 (jcc short) - INST_JNS_SHORT, // X86/X64 (jcc short) - INST_JNZ_SHORT, // X86/X64 (jcc short) - INST_JO_SHORT, // X86/X64 (jcc short) - INST_JP_SHORT, // X86/X64 (jcc short) - INST_JPE_SHORT, // X86/X64 (jcc short) - INST_JPO_SHORT, // X86/X64 (jcc short) - INST_JS_SHORT, // X86/X64 (jcc short) - INST_JZ_SHORT, // X86/X64 (jcc short) - INST_JMP_SHORT, // X86/Z64 (jmp short) - - INST_LDDQU, - INST_LDMXCSR, - INST_LEA, // X86/X64 - INST_LEAVE, // X86/X64 - INST_LFENCE, - INST_LOCK, // X86/X64 - INST_MASKMOVDQU, - INST_MASKMOVQ, // MMX Extensions - INST_MAXPD, - INST_MAXPS, - INST_MAXSD, - INST_MAXSS, - INST_MFENCE, - INST_MINPD, - INST_MINPS, - INST_MINSD, - INST_MINSS, - INST_MONITOR, - INST_MOV, // X86/X64 - INST_MOVAPD, - INST_MOVAPS, - INST_MOVBE, - INST_MOVD, - INST_MOVDDUP, - INST_MOVDQ2Q, - INST_MOVDQA, - INST_MOVDQU, - INST_MOVHLPS, - INST_MOVHPD, - INST_MOVHPS, - INST_MOVLHPS, - INST_MOVLPD, - INST_MOVLPS, - INST_MOVMSKPD, - INST_MOVMSKPS, - INST_MOVNTDQ, - INST_MOVNTDQA, - INST_MOVNTI, - INST_MOVNTPD, - INST_MOVNTPS, - INST_MOVNTQ, // MMX Extensions - INST_MOVQ, - INST_MOVQ2DQ, - INST_MOVSD, - INST_MOVSHDUP, - INST_MOVSLDUP, - INST_MOVSS, - INST_MOVSX, // X86/X64 - INST_MOVSXD, // X86/X64 - INST_MOVUPD, - INST_MOVUPS, - INST_MOVZX, // X86/X64 - INST_MOV_PTR, // X86/X64 - INST_MPSADBW, - INST_MUL, // X86/X64 - INST_MULPD, - INST_MULPS, - INST_MULSD, - INST_MULSS, - INST_MWAIT, - INST_NEG, // X86/X64 - INST_NOP, // X86/X64 - INST_NOT, // X86/X64 - INST_OR, // X86/X64 - INST_ORPD, - INST_ORPS, - INST_PABSB, - INST_PABSD, - INST_PABSW, - INST_PACKSSDW, - INST_PACKSSWB, - INST_PACKUSDW, - INST_PACKUSWB, - INST_PADDB, - INST_PADDD, - INST_PADDQ, - INST_PADDSB, - INST_PADDSW, - INST_PADDUSB, - INST_PADDUSW, - INST_PADDW, - INST_PALIGNR, - INST_PAND, - INST_PANDN, - INST_PAUSE, - INST_PAVGB, // MMX Extensions - INST_PAVGW, // MMX Extensions - INST_PBLENDVB, - INST_PBLENDW, - INST_PCMPEQB, - INST_PCMPEQD, - INST_PCMPEQQ, - INST_PCMPEQW, - INST_PCMPESTRI, - INST_PCMPESTRM, - INST_PCMPGTB, - INST_PCMPGTD, - INST_PCMPGTQ, - INST_PCMPGTW, - INST_PCMPISTRI, - INST_PCMPISTRM, - INST_PEXTRB, - INST_PEXTRD, - INST_PEXTRQ, - INST_PEXTRW, // MMX Extensions - INST_PF2ID, // 3dNow! - INST_PF2IW, // 3dNow! Extensions - INST_PFACC, // 3dNow! - INST_PFADD, // 3dNow! - INST_PFCMPEQ, // 3dNow! - INST_PFCMPGE, // 3dNow! - INST_PFCMPGT, // 3dNow! - INST_PFMAX, // 3dNow! - INST_PFMIN, // 3dNow! - INST_PFMUL, // 3dNow! - INST_PFNACC, // 3dNow! Extensions - INST_PFPNACC, // 3dNow! Extensions - INST_PFRCP, // 3dNow! - INST_PFRCPIT1, // 3dNow! - INST_PFRCPIT2, // 3dNow! - INST_PFRSQIT1, // 3dNow! - INST_PFRSQRT, // 3dNow! - INST_PFSUB, // 3dNow! - INST_PFSUBR, // 3dNow! - INST_PHADDD, - INST_PHADDSW, - INST_PHADDW, - INST_PHMINPOSUW, - INST_PHSUBD, - INST_PHSUBSW, - INST_PHSUBW, - INST_PI2FD, // 3dNow! - INST_PI2FW, // 3dNow! Extensions - INST_PINSRB, - INST_PINSRD, - INST_PINSRQ, - INST_PINSRW, // MMX Extensions - INST_PMADDUBSW, - INST_PMADDWD, - INST_PMAXSB, - INST_PMAXSD, - INST_PMAXSW, // MMX Extensions - INST_PMAXUB, // MMX Extensions - INST_PMAXUD, - INST_PMAXUW, - INST_PMINSB, - INST_PMINSD, - INST_PMINSW, // MMX Extensions - INST_PMINUB, // MMX Extensions - INST_PMINUD, - INST_PMINUW, - INST_PMOVMSKB, // MMX Extensions - INST_PMOVSXBD, - INST_PMOVSXBQ, - INST_PMOVSXBW, - INST_PMOVSXDQ, - INST_PMOVSXWD, - INST_PMOVSXWQ, - INST_PMOVZXBD, - INST_PMOVZXBQ, - INST_PMOVZXBW, - INST_PMOVZXDQ, - INST_PMOVZXWD, - INST_PMOVZXWQ, - INST_PMULDQ, - INST_PMULHRSW, - INST_PMULHUW, // MMX Extensions - INST_PMULHW, - INST_PMULLD, - INST_PMULLW, - INST_PMULUDQ, - INST_POP, // X86/X64 - INST_POPAD, // X86 only - INST_POPCNT, - INST_POPFD, // X86 only - INST_POPFQ, // X64 only - INST_POR, - INST_PREFETCH, // MMX Extensions - INST_PSADBW, // MMX Extensions - INST_PSHUFB, - INST_PSHUFD, - INST_PSHUFW, // MMX Extensions - INST_PSHUFHW, - INST_PSHUFLW, - INST_PSIGNB, - INST_PSIGND, - INST_PSIGNW, - INST_PSLLD, - INST_PSLLDQ, - INST_PSLLQ, - INST_PSLLW, - INST_PSRAD, - INST_PSRAW, - INST_PSRLD, - INST_PSRLDQ, - INST_PSRLQ, - INST_PSRLW, - INST_PSUBB, - INST_PSUBD, - INST_PSUBQ, - INST_PSUBSB, - INST_PSUBSW, - INST_PSUBUSB, - INST_PSUBUSW, - INST_PSUBW, - INST_PSWAPD, // 3dNow! Extensions - INST_PTEST, - INST_PUNPCKHBW, - INST_PUNPCKHDQ, - INST_PUNPCKHQDQ, - INST_PUNPCKHWD, - INST_PUNPCKLBW, - INST_PUNPCKLDQ, - INST_PUNPCKLQDQ, - INST_PUNPCKLWD, - INST_PUSH, // X86/X64 - INST_PUSHAD, // X86 only - INST_PUSHFD, // X86 only - INST_PUSHFQ, // X64 only - INST_PXOR, - INST_RCL, // X86/X64 - INST_RCPPS, - INST_RCPSS, - INST_RCR, // X86/X64 - INST_RDTSC, // X86/X64 - INST_RDTSCP, // X86/X64 - INST_RET, // X86/X64 - INST_ROL, // X86/X64 - INST_ROR, // X86/X64 - INST_ROUNDPD, - INST_ROUNDPS, - INST_ROUNDSD, - INST_ROUNDSS, - INST_RSQRTPS, - INST_RSQRTSS, - INST_SAHF, // X86 only - INST_SAL, // X86/X64 - INST_SAR, // X86/X64 - INST_SBB, // X86/X64 - INST_SET, // Begin (setcc) - INST_SETA=INST_SET, // X86/X64 (setcc) - INST_SETAE, // X86/X64 (setcc) - INST_SETB, // X86/X64 (setcc) - INST_SETBE, // X86/X64 (setcc) - INST_SETC, // X86/X64 (setcc) - INST_SETE, // X86/X64 (setcc) - INST_SETG, // X86/X64 (setcc) - INST_SETGE, // X86/X64 (setcc) - INST_SETL, // X86/X64 (setcc) - INST_SETLE, // X86/X64 (setcc) - INST_SETNA, // X86/X64 (setcc) - INST_SETNAE, // X86/X64 (setcc) - INST_SETNB, // X86/X64 (setcc) - INST_SETNBE, // X86/X64 (setcc) - INST_SETNC, // X86/X64 (setcc) - INST_SETNE, // X86/X64 (setcc) - INST_SETNG, // X86/X64 (setcc) - INST_SETNGE, // X86/X64 (setcc) - INST_SETNL, // X86/X64 (setcc) - INST_SETNLE, // X86/X64 (setcc) - INST_SETNO, // X86/X64 (setcc) - INST_SETNP, // X86/X64 (setcc) - INST_SETNS, // X86/X64 (setcc) - INST_SETNZ, // X86/X64 (setcc) - INST_SETO, // X86/X64 (setcc) - INST_SETP, // X86/X64 (setcc) - INST_SETPE, // X86/X64 (setcc) - INST_SETPO, // X86/X64 (setcc) - INST_SETS, // X86/X64 (setcc) - INST_SETZ, // X86/X64 (setcc) - INST_SFENCE, // MMX Extensions - INST_SHL, // X86/X64 - INST_SHLD, // X86/X64 - INST_SHR, // X86/X64 - INST_SHRD, // X86/X64 - INST_SHUFPD, - INST_SHUFPS, - INST_SQRTPD, - INST_SQRTPS, - INST_SQRTSD, - INST_SQRTSS, - INST_STC, // X86/X64 - INST_STD, // X86/X64 - INST_STMXCSR, - INST_SUB, // X86/X64 - INST_SUBPD, - INST_SUBPS, - INST_SUBSD, - INST_SUBSS, - INST_TEST, // X86/X64 - INST_UCOMISD, - INST_UCOMISS, - INST_UD2, // X86/X64 - INST_UNPCKHPD, - INST_UNPCKHPS, - INST_UNPCKLPD, - INST_UNPCKLPS, - INST_XADD, // X86/X64 (i486) - INST_XCHG, // X86/X64 (i386) - INST_XOR, // X86/X64 - INST_XORPD, - INST_XORPS, - - // [Additions, AsmJit-0.8.6] - - // LODS[BDQW]. - INST_REP_LODSB, - INST_REP_LODSD, - INST_REP_LODSQ, - INST_REP_LODSW, - - // MOV[BDQW]. - INST_REP_MOVSB, - INST_REP_MOVSD, - INST_REP_MOVSQ, - INST_REP_MOVSW, - - // STOS[BDQW]. - INST_REP_STOSB, - INST_REP_STOSD, - INST_REP_STOSQ, - INST_REP_STOSW, - - // CMPS[BDQW]. - INST_REPE_CMPSB, - INST_REPE_CMPSD, - INST_REPE_CMPSQ, - INST_REPE_CMPSW, - - // SCAS[BDQW]. - INST_REPE_SCASB, - INST_REPE_SCASD, - INST_REPE_SCASQ, - INST_REPE_SCASW, - - // CMPS[BDQW]. - INST_REPNE_CMPSB, - INST_REPNE_CMPSD, - INST_REPNE_CMPSQ, - INST_REPNE_CMPSW, - - // SCAS[BDQW]. - INST_REPNE_SCASB, - INST_REPNE_SCASD, - INST_REPNE_SCASQ, - INST_REPNE_SCASW, - - _INST_COUNT -}; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_DEFSX86X64_H diff --git a/src/thirdparty/dyndetours/AsmJit/Lock.h b/src/thirdparty/dyndetours/AsmJit/Lock.h deleted file mode 100644 index ff5129bcb..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Lock.h +++ /dev/null @@ -1,147 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_LOCK_H -#define _ASMJIT_LOCK_H - -// [Dependencies] -#include "Build.h" - -#if defined(ASMJIT_WINDOWS) -#include -#endif // ASMJIT_WINDOWS - -#if defined(ASMJIT_POSIX) -#include -#endif // ASMJIT_POSIX - -// [Warnings-Push] -#include "WarningsPush.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_Platform -//! @{ - -//! @brief Lock. -struct ASMJIT_HIDDEN Lock -{ -#if defined(ASMJIT_WINDOWS) - typedef CRITICAL_SECTION Handle; -#endif // ASMJIT_WINDOWS -#if defined(ASMJIT_POSIX) - typedef pthread_mutex_t Handle; -#endif // ASMJIT_POSIX - - inline Lock() ASMJIT_NOTHROW - { -#if defined(ASMJIT_WINDOWS) - InitializeCriticalSection(&_handle); - // InitializeLockAndSpinCount(&_handle, 2000); -#endif // ASMJIT_WINDOWS -#if defined(ASMJIT_POSIX) - pthread_mutex_init(&_handle, NULL); -#endif // ASMJIT_POSIX - } - - inline ~Lock() ASMJIT_NOTHROW - { -#if defined(ASMJIT_WINDOWS) - DeleteCriticalSection(&_handle); -#endif // ASMJIT_WINDOWS -#if defined(ASMJIT_POSIX) - pthread_mutex_destroy(&_handle); -#endif // ASMJIT_POSIX - } - - inline Handle& handle() ASMJIT_NOTHROW - { - return _handle; - } - - inline const Handle& handle() const ASMJIT_NOTHROW - { - return _handle; - } - - inline void lock() ASMJIT_NOTHROW - { -#if defined(ASMJIT_WINDOWS) - EnterCriticalSection(&_handle); -#endif // ASMJIT_WINDOWS -#if defined(ASMJIT_POSIX) - pthread_mutex_lock(&_handle); -#endif // ASMJIT_POSIX - } - - inline void unlock() ASMJIT_NOTHROW - { -#if defined(ASMJIT_WINDOWS) - LeaveCriticalSection(&_handle); -#endif // ASMJIT_WINDOWS -#if defined(ASMJIT_POSIX) - pthread_mutex_unlock(&_handle); -#endif // ASMJIT_POSIX - } - -private: - Handle _handle; - - // Disable copy. - ASMJIT_DISABLE_COPY(Lock); -}; - -struct ASMJIT_HIDDEN AutoLock -{ - //! @brief Locks @a target. - inline AutoLock(Lock& target) ASMJIT_NOTHROW : _target(target) - { - _target.lock(); - } - - //! @brief Unlocks target. - inline ~AutoLock() ASMJIT_NOTHROW - { - _target.unlock(); - } - -private: - //! @brief Pointer to target (lock). - Lock& _target; - - // Disable copy. - ASMJIT_DISABLE_COPY(AutoLock); -}; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_LOCK_H diff --git a/src/thirdparty/dyndetours/AsmJit/Logger.h b/src/thirdparty/dyndetours/AsmJit/Logger.h deleted file mode 100644 index 5709b32cd..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Logger.h +++ /dev/null @@ -1,39 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_LOGGER_H -#define _ASMJIT_LOGGER_H - -// [Dependencies] -#include "Build.h" - -// [X86 / X64] -#if defined(ASMJIT_X86) || defined(ASMJIT_X64) -#include "LoggerX86X64.h" -#endif // ASMJIT_X86 || ASMJIT_X64 - -// [Guard] -#endif // _ASMJIT_LOGGER_H diff --git a/src/thirdparty/dyndetours/AsmJit/LoggerX86X64.h b/src/thirdparty/dyndetours/AsmJit/LoggerX86X64.h deleted file mode 100644 index 7eac1e622..000000000 --- a/src/thirdparty/dyndetours/AsmJit/LoggerX86X64.h +++ /dev/null @@ -1,185 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_LOGGERX86X64_H -#define _ASMJIT_LOGGERX86X64_H - -#if !defined(_ASMJIT_LOGGER_H) -#warning "AsmJit/LoggerX86X64 can be only included by AsmJit/Logger.h" -#endif // _ASMJIT_LOGGER_H - -// [Dependencies] -#include "Defs.h" -#include "Serializer.h" - -#include -#include -#include - -// [Warnings-Push] -#include "WarningsPush.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_Logging -//! @{ - -//! @brief Abstract logging class. -//! -//! This class can be inherited and reimplemented to fit into your logging -//! subsystem. When reimplementing use @c AsmJit::Logger::log() method to -//! log into your stream. -//! -//! This class also contain @c _enabled member that can be used to enable -//! or disable logging. -struct ASMJIT_API Logger -{ - // [Construction / Destruction] - - //! @brief Create logger. - Logger() ASMJIT_NOTHROW; - //! @brief Destroy logger. - virtual ~Logger() ASMJIT_NOTHROW; - - // [Methods] - - //! @brief Abstract method to log output. - //! - //! Default implementation that is in @c AsmJit::Logger is to do nothing. - //! It's virtual to fit to your logging system. - virtual void log(const char* buf) ASMJIT_NOTHROW; - - //! @brief Log instruction with operands. - virtual void logInstruction(UInt32 code, - const Operand* o1, - const Operand* o2, - const Operand* o3, - const char* inlineComment = NULL) ASMJIT_NOTHROW; - - //! @brief Log .align directive. - virtual void logAlign(SysInt m) ASMJIT_NOTHROW; - - //! @brief Log label. - virtual void logLabel(const Label* label) ASMJIT_NOTHROW; - - //! @brief Log printf like message. - virtual void logFormat(const char* fmt, ...) ASMJIT_NOTHROW; - - //! @brief Return @c true if logging is enabled. - inline bool enabled() const ASMJIT_NOTHROW - { return _enabled; } - - //! @brief Set logging to enabled or disabled. - inline void setEnabled(bool enabled) ASMJIT_NOTHROW - { _enabled = enabled; } - - // [Statics] - - //! @brief Dump instruction @a code to @a buf and return destination size. - //! - //! @note Output is not @c NULL terminated. - static char* dumpInstruction(char* buf, UInt32 code) ASMJIT_NOTHROW; - - //! @brief Dump operand @a op to @a buf and returns destination size. - //! - //! @note Output is not @c NULL terminated. - static char* dumpOperand(char* buf, const Operand* op) ASMJIT_NOTHROW; - - //! @brief Dump register to @a buf and returns destination size. - //! - //! @note Output is not @c NULL terminated. - static char* dumpRegister(char* buf, UInt8 type, UInt8 index) ASMJIT_NOTHROW; - - //! @brief Dump label @a label to @a buf and returns destination size. - //! - //! @note Output is not @c NULL terminated. - static char* dumpLabel(char* buf, const Label* label) ASMJIT_NOTHROW; - - // [Variables] - -protected: - //! @brief Whether logger is enabled or disabled. - //! - //! Default @c true. - bool _enabled; - - //! @brief Whether logger have logging stream. - //! - //! This value can be set by inherited classes to inform @c Logger that - //! assigned stream is invalid. If @c _haveStream is false it means that - //! logging messages from helper functions (@c logInstruction, @c logAlign, - //! @c logLabel and @c logFormat) are not sent to main @c log() method. - //! - //! This is designed only to optimize cases that logger exists, but its - //! stream not. - //! - //! Default @c true. - bool _haveStream; - -private: - // Disable copy. - ASMJIT_DISABLE_COPY(Logger); -}; - -//! @brief Logger that can log to standard C @c FILE* stream. -struct ASMJIT_API FileLogger : public Logger -{ - // [Construction / Destruction] - - //! @brief Create new @c FileLogger. - //! @param stream FILE stream where logging will be sent (can be @c NULL - //! to disable logging). - FileLogger(FILE* stream = NULL) ASMJIT_NOTHROW; - - // [Methods] - - virtual void log(const char* buf) ASMJIT_NOTHROW; - - //! @brief Get file stream. - //! @note Return value can be @c NULL. - inline FILE* stream() const ASMJIT_NOTHROW - { return _stream; } - - //! @brief Set file stream. - //! @param stream FILE stream where logging will be sent (can be @c NULL - //! to disable logging). - void setStream(FILE* stream) ASMJIT_NOTHROW; - - // [Variables] - -private: - FILE* _stream; -}; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_LOGGERX86X64_H diff --git a/src/thirdparty/dyndetours/AsmJit/MemoryManager.h b/src/thirdparty/dyndetours/AsmJit/MemoryManager.h deleted file mode 100644 index 843967c22..000000000 --- a/src/thirdparty/dyndetours/AsmJit/MemoryManager.h +++ /dev/null @@ -1,120 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_MEMORYMANAGER_H -#define _ASMJIT_MEMORYMANAGER_H - -// [Dependencies] -#include "Build.h" - -// [Warnings-Push] -#include "WarningsPush.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_MemoryManagement -//! @{ - -// ============================================================================ -// [AsmJit::MemoryManager] -// ============================================================================ - -//! @brief Types of allocation used by @c AsmJit::MemoryManager::alloc() method. -enum MEMORY_ALLOC_TYPE -{ - //! @brief Allocate memory that can be freed by @c AsmJit::MemoryManager::free() - //! method. - MEMORY_ALLOC_FREEABLE, - //! @brief Allocate pernament memory that will be never freed. - MEMORY_ALLOC_PERNAMENT -}; - -//! @brief Virtual memory manager interface. -//! -//! This class is pure virtual. You can get default virtual memory manager using -//! @c global() method. If you want to create more memory managers with same -//! functionality as global memory manager use @c DefaultMemoryManager class. -struct ASMJIT_API MemoryManager -{ - //! @brief Create memory manager instance. - MemoryManager() ASMJIT_NOTHROW; - //! @brief Destroy memory manager instance, this means also to free all memory - //! blocks. - virtual ~MemoryManager() ASMJIT_NOTHROW; - - //! @brief Allocate a @a size bytes of virtual memory. - //! - //! Note that if you are implementing your own virtual memory manager then you - //! can quitly ignore type of allocation. This is mainly for AsmJit to memory - //! manager that allocated memory will be never freed. - virtual void* alloc(SysUInt size, UInt32 type = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW = 0; - //! @brief Free previously allocated memory at a given @a address. - virtual bool free(void* address) ASMJIT_NOTHROW = 0; - - //! @brief Tell how many bytes are currently used. - virtual SysUInt used() ASMJIT_NOTHROW = 0; - //! @brief Tell how many bytes are currently allocated. - virtual SysUInt allocated() ASMJIT_NOTHROW = 0; - - //! @brief Get global memory manager instance. - //! - //! Global instance is instance of @c DefaultMemoryManager class. - static MemoryManager* global() ASMJIT_NOTHROW; -}; - -//! @brief Reference implementation of memory manager that uses -//! AsmJit::VirtualMemory class to allocate chunks of virtual memory and bit -//! arrays to manage it. -struct ASMJIT_API DefaultMemoryManager : public MemoryManager -{ - //! @brief Create memory manager instance. - DefaultMemoryManager() ASMJIT_NOTHROW; - //! @brief Destroy memory manager instance, this means also to free all blocks. - virtual ~DefaultMemoryManager() ASMJIT_NOTHROW; - - //! @brief Allocate a @a size bytes of virtual memory. - virtual void* alloc(SysUInt size, UInt32 type = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW; - //! @brief Free previously allocated memory at a given @a address. - virtual bool free(void* address) ASMJIT_NOTHROW; - - //! @brief Tell how many bytes are currently used. - virtual SysUInt used() ASMJIT_NOTHROW; - //! @brief Tell how many bytes are currently allocated. - virtual SysUInt allocated() ASMJIT_NOTHROW; - -private: - void* _d; -}; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_MEMORYMANAGER_H diff --git a/src/thirdparty/dyndetours/AsmJit/Serializer.h b/src/thirdparty/dyndetours/AsmJit/Serializer.h deleted file mode 100644 index b2de68cc1..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Serializer.h +++ /dev/null @@ -1,70 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_SERIALIZER_H -#define _ASMJIT_SERIALIZER_H - -// [Dependencies] -#include "Build.h" - -namespace AsmJit { - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -struct Label; -struct Logger; -struct Assembler; -struct Compiler; - -//! @addtogroup AsmJit_Serializer -//! @{ - -// ============================================================================ -// [Constants] -// ============================================================================ - -enum { - //! @brief Maximum size of inlined comment (see @c SerializerCore::_inlineComment() method). - MAX_INLINE_COMMENT_SIZE = 256 -}; - -//! @} - -} // AsmJit namespace. - -// ============================================================================ -// [Platform Specific] -// ============================================================================ - -// [X86 / X64] -#if defined(ASMJIT_X86) || defined(ASMJIT_X64) -#include "SerializerX86X64.h" -#endif // ASMJIT_X86 || ASMJIT_X64 - -// [Guard] -#endif // _ASMJIT_SERIALIZER_H diff --git a/src/thirdparty/dyndetours/AsmJit/SerializerX86X64.h b/src/thirdparty/dyndetours/AsmJit/SerializerX86X64.h deleted file mode 100644 index 693e949b0..000000000 --- a/src/thirdparty/dyndetours/AsmJit/SerializerX86X64.h +++ /dev/null @@ -1,8148 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_SERIALIZERX86X64_H -#define _ASMJIT_SERIALIZERX86X64_H - -#if !defined(_ASMJIT_SERIALIZER_H) -#warning "AsmJit/SerializerX86X64 can be only included by AsmJit/Serializer.h" -#endif // _ASMJIT_SERIALIZER_H - -// [Dependencies] -#include "Build.h" -#include "Defs.h" -#include "MemoryManager.h" -#include "Util.h" - -// [Warnings-Push] -#include "WarningsPush.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_Serializer -//! @{ - -// ============================================================================ -// [AsmJit::Operand] -// ============================================================================ - -//! @brief Operand, abstract class for register, memory location and immediate -//! value operands. -struct ASMJIT_HIDDEN Operand -{ - inline Operand() ASMJIT_NOTHROW - { memset(this, 0, sizeof(Operand)); } - - inline Operand(const Operand& other) ASMJIT_NOTHROW : - _compilerData(NULL), _operandId(0) - { _init(other); } - - inline Operand(const _DontInitialize&) ASMJIT_NOTHROW : - _compilerData(NULL), _operandId(0) - {} - - //! @brief Return type of operand, see @c OP. - inline UInt8 op() const ASMJIT_NOTHROW - { return _base.op; } - - //! @brief Return @c true if operand is none (@c OP_NONE). - inline UInt8 isNone() const ASMJIT_NOTHROW - { return _base.op == OP_NONE; } - - //! @brief Return @c true if operand is any (general purpose, mmx or sse) register (@c OP_REG). - inline UInt8 isReg() const ASMJIT_NOTHROW - { return _base.op == OP_REG; } - - //! @brief Return @c true if operand is memory address (@c OP_MEM). - inline UInt8 isMem() const ASMJIT_NOTHROW - { return _base.op == OP_MEM; } - - //! @brief Return @c true if operand is immediate (@c OP_IMM). - inline UInt8 isImm() const ASMJIT_NOTHROW - { return _base.op == OP_IMM; } - - //! @brief Return @c true if operand is label (@c OP_LABEL). - inline UInt8 isLabel() const ASMJIT_NOTHROW - { return _base.op == OP_LABEL; } - - //! @brief Return @c true if operand is register and type of register is @a regType. - inline UInt8 isRegType(UInt8 regType) const ASMJIT_NOTHROW - { return isReg() & ((_reg.code & REGTYPE_MASK) == regType); } - - //! @brief Return @c true if operand is register and code of register is @a regCode. - inline UInt8 isRegCode(UInt8 regCode) const ASMJIT_NOTHROW - { return isReg() & (_reg.code == regCode); } - - //! @brief Return @c true if operand is register and index of register is @a regIndex. - inline UInt8 isRegIndex(UInt8 regIndex) const ASMJIT_NOTHROW - { return isReg() & ((_reg.code & REGCODE_MASK) == (regIndex & REGCODE_MASK)); } - - //! @brief Return @c true if operand is any register or memory. - inline UInt8 isRegMem() const ASMJIT_NOTHROW - { return isMem() | isReg(); } - - //! @brief Return @c true if operand is register of @a regType type or memory. - inline UInt8 isRegMem(UInt8 regType) const ASMJIT_NOTHROW - { return isMem() | isRegType(regType); } - - //! @brief Return size of operand in bytes. - inline UInt8 size() const ASMJIT_NOTHROW - { return _base.size; } - - inline void* compilerData() const ASMJIT_NOTHROW - { return _compilerData; } - - //! @brief Return operand Id (Operand Id's are for @c Compiler class). - inline UInt32 operandId() const ASMJIT_NOTHROW - { return _operandId; } - - //! @brief Return clears operand Id (@c Compiler will not recognize it after clearing). - inline void clearId() ASMJIT_NOTHROW - { _operandId = 0; } - - //! @brief Base operand data shared between all operands. - struct BaseData - { - //! @brief Type of operand, see @c OP. - UInt8 op; - //! @brief Size of operand (register, address or immediate size). - UInt8 size; - }; - - //! @brief Register data. - struct RegData - { - //! @brief Type of operand, see @c OP. - UInt8 op; - //! @brief Size of register. - UInt8 size; - - //! @brief Register code, see @c REG. - UInt8 code; - //! @brief Not used. - UInt8 reserved; - }; - - //! @brief Memory address data. - struct MemData - { - //! @brief Type of operand, see @c OP. - UInt8 op; - //! @brief Size of pointer. - UInt8 size; - - //! @brief Base register index, see @c REG. - UInt8 base; - //! @brief Index register index, see @c REG. - UInt8 index; - //! @brief Index register shift (0 to 3 included). - UInt8 shift; - //! @brief Segment override prefix, see @c AsmJit::SEGMENT. - UInt8 segmentPrefix; - //! @brief Set to @c true if this operand is address to @c AsmJit::Label. - UInt8 hasLabel; - //! @brief Reserved (padding). - UInt8 reserved; - - //! @brief Displacement or target absolute address. - union { - //! @brief Target (for 32 bit, absolute address). - void* target; - - //! @brief Label (if memory operand is used with @c Label). - Label* label; - }; - - //! @brief Displacement. - SysInt displacement; - }; - - //! @brief Immediate value data. - struct ImmData - { - //! @brief Type of operand, see @c OP. - UInt8 op; - //! @brief Size of immediate (or 0 to autodetect). - UInt8 size; - - //! @brief @c true if immediate is unsigned. - UInt8 isUnsigned; - //! @brief Not used. - UInt8 relocMode; - //! @brief Immediate value. - SysInt value; - }; - - //! @brief Label data. - struct LblData - { - //! @brief Type of operand, see @c OP. - UInt8 op; - //! @brief Size of label, currently not used. - UInt8 size; - //! @brief State of label, see @c LABEL_STATE. - UInt8 state; - //! @brief Reserved (padding). - UInt8 reserved; - //! @brief Label Id (0 means unknown). - UInt32 id; - //! @brief Position (always positive, information depends to @c state). - SysInt position; - //! @brief Previous link (used by @c AsmJit::Assembler). - void* link; - }; - - enum { BufSize = 64 - (2 * sizeof(void*)) }; - - union - { - //! @brief Generic operand data. - BaseData _base; - //! @brief Register operand data. - RegData _reg; - //! @brief Memory operand data. - MemData _mem; - //! @brief Immediate operand data. - ImmData _imm; - //! @brief Label data. - LblData _lbl; - //! @brief Operand buffer. - UInt8 _buf[BufSize]; - }; - - //! @brief Compiler specific data. - void *_compilerData; - - //! @brief Compiler operand id (do not modify manually). - UInt32 _operandId; - -#if defined(ASMJIT_X64) - UInt32 _x64padding; -#endif // ASMJIT_X64 - - inline void _init(const Operand& other) ASMJIT_NOTHROW - { memcpy(this, &other, sizeof(Operand)); } - - inline void _copy(const Operand& other) ASMJIT_NOTHROW - { memcpy(this, &other, sizeof(Operand)); } - - friend struct Compiler; -}; - -// ============================================================================ -// [AsmJit::BaseReg] -// ============================================================================ - -//! @brief Base class for all registers. -struct ASMJIT_HIDDEN BaseReg : public Operand -{ - inline BaseReg(UInt8 code, UInt8 size) ASMJIT_NOTHROW : - Operand(_DontInitialize()) - { - _reg.op = OP_REG; - _reg.size = size; - _reg.code = code; - } - - inline BaseReg(const BaseReg& other) ASMJIT_NOTHROW : - Operand(other) - {} - - inline BaseReg(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW : - Operand(dontInitialize) - {} - - //! @brief Return register type, see @c REG. - inline UInt8 type() const ASMJIT_NOTHROW - { return (UInt8)(_reg.code & REGTYPE_MASK); } - - //! @brief Return register code, see @c REG. - inline UInt8 code() const ASMJIT_NOTHROW - { return (UInt8)(_reg.code); } - - //! @brief Return register index (value from 0 to 7/15). - inline UInt8 index() const ASMJIT_NOTHROW - { return (UInt8)(_reg.code & REGCODE_MASK); } - - inline UInt8 isRegCode(UInt8 code) const ASMJIT_NOTHROW - { return _reg.code == code; } - - inline UInt8 isRegType(UInt8 type) const ASMJIT_NOTHROW - { return (_reg.code & REGTYPE_MASK) == type; } - - inline UInt8 isRegIndex(UInt8 index) const ASMJIT_NOTHROW - { return (_reg.code & REGCODE_MASK) == index; } - - //! @brief Set register code. - inline void setCode(UInt8 code) ASMJIT_NOTHROW - { _reg.code = code; } - - inline void setSize(UInt8 size) ASMJIT_NOTHROW - { _reg.size = size; } - - inline BaseReg& operator=(const BaseReg& other) ASMJIT_NOTHROW - { _copy(other); return *this; } - - inline bool operator==(const BaseReg& other) ASMJIT_NOTHROW - { return code() == other.code(); } - - inline bool operator!=(const BaseReg& other) ASMJIT_NOTHROW - { return code() != other.code(); } -}; - -// ============================================================================ -// [AsmJit::Register] -// ============================================================================ - -//! @brief General purpose register. -//! -//! This class is for all general purpose registers (64, 32, 16 and 8 bit). -struct ASMJIT_HIDDEN Register : public BaseReg -{ - inline Register() ASMJIT_NOTHROW : BaseReg(NO_REG, 0) {} - inline Register(const Register& other) ASMJIT_NOTHROW : BaseReg(other) {} - inline Register(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW : - BaseReg(dontInitialize) {} - inline Register(const _Initialize&, UInt8 code) ASMJIT_NOTHROW : - BaseReg(code, static_cast(1U << ((code & REGTYPE_MASK) >> 4))) {} - - inline Register& operator=(const Register& other) ASMJIT_NOTHROW { _copy(other); return *this; } - inline bool operator==(const Register& other) const ASMJIT_NOTHROW { return code() == other.code(); } - inline bool operator!=(const Register& other) const ASMJIT_NOTHROW { return code() != other.code(); } -}; - -// ============================================================================ -// [AsmJit::X87Register] -// ============================================================================ - -//! @brief 80-bit x87 floating point register. -//! -//! To create instance of x87 register, use @c st() function. -struct ASMJIT_HIDDEN X87Register : public BaseReg -{ - inline X87Register() ASMJIT_NOTHROW : BaseReg(NO_REG, 0) {} - inline X87Register(const X87Register& other) ASMJIT_NOTHROW : BaseReg(other) {} - inline X87Register(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW : - BaseReg(dontInitialize) {} - inline X87Register(const _Initialize&, UInt8 code) ASMJIT_NOTHROW : BaseReg(code | REG_X87, 10) {} - - inline X87Register& operator=(const X87Register& other) ASMJIT_NOTHROW { _copy(other); return *this; } - inline bool operator==(const X87Register& other) const ASMJIT_NOTHROW { return code() == other.code(); } - inline bool operator!=(const X87Register& other) const ASMJIT_NOTHROW { return code() != other.code(); } -}; - -// ============================================================================ -// [AsmJit::MMRegister] -// ============================================================================ - -//! @brief 64 bit MMX register. -struct ASMJIT_HIDDEN MMRegister : public BaseReg -{ - inline MMRegister() ASMJIT_NOTHROW : BaseReg(NO_REG, 0) {} - inline MMRegister(const MMRegister& other) ASMJIT_NOTHROW : BaseReg(other) {} - inline MMRegister(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW : - BaseReg(dontInitialize) {} - inline MMRegister(const _Initialize&, UInt8 code) ASMJIT_NOTHROW : BaseReg(code, 8) {} - - inline MMRegister& operator=(const MMRegister& other) ASMJIT_NOTHROW { _copy(other); return *this; } - inline bool operator==(const MMRegister& other) const ASMJIT_NOTHROW { return code() == other.code(); } - inline bool operator!=(const MMRegister& other) const ASMJIT_NOTHROW { return code() != other.code(); } -}; - -// ============================================================================ -// [AsmJit::XMMRegister] -// ============================================================================ - -//! @brief 128 bit SSE register. -struct ASMJIT_HIDDEN XMMRegister : public BaseReg -{ - inline XMMRegister() ASMJIT_NOTHROW : BaseReg(NO_REG, 0) {} - inline XMMRegister(const _Initialize&, UInt8 code) ASMJIT_NOTHROW : BaseReg(code, 16) {} - inline XMMRegister(const _DontInitialize& dontInitialize) ASMJIT_NOTHROW : - BaseReg(dontInitialize) {} - inline XMMRegister(const XMMRegister& other) ASMJIT_NOTHROW : BaseReg(other) {} - - inline XMMRegister& operator=(const XMMRegister& other) ASMJIT_NOTHROW { _copy(other); return *this; } - inline bool operator==(const XMMRegister& other) const ASMJIT_NOTHROW { return code() == other.code(); } - inline bool operator!=(const XMMRegister& other) const ASMJIT_NOTHROW { return code() != other.code(); } -}; - -// ============================================================================ -// [AsmJit::Registers] -// ============================================================================ - -//! @brief No register, can be used only in @c Mem operand. -static const Register no_reg(_Initialize(), NO_REG); - -//! @brief 8 bit General purpose register. -static const Register al(_Initialize(), REG_AL); -//! @brief 8 bit General purpose register. -static const Register cl(_Initialize(), REG_CL); -//! @brief 8 bit General purpose register. -static const Register dl(_Initialize(), REG_DL); -//! @brief 8 bit General purpose register. -static const Register bl(_Initialize(), REG_BL); -//! @brief 8 bit General purpose register. -static const Register ah(_Initialize(), REG_AH); -//! @brief 8 bit General purpose register. -static const Register ch(_Initialize(), REG_CH); -//! @brief 8 bit General purpose register. -static const Register dh(_Initialize(), REG_DH); -//! @brief 8 bit General purpose register. -static const Register bh(_Initialize(), REG_BH); - -#if defined(ASMJIT_X64) -//! @brief 8 bit General purpose register (64 bit mode only). -static const Register r8b(_Initialize(), REG_R8B); -//! @brief 8 bit General purpose register (64 bit mode only). -static const Register r9b(_Initialize(), REG_R9B); -//! @brief 8 bit General purpose register (64 bit mode only). -static const Register r10b(_Initialize(), REG_R10B); -//! @brief 8 bit General purpose register (64 bit mode only). -static const Register r11b(_Initialize(), REG_R11B); -//! @brief 8 bit General purpose register (64 bit mode only). -static const Register r12b(_Initialize(), REG_R12B); -//! @brief 8 bit General purpose register (64 bit mode only). -static const Register r13b(_Initialize(), REG_R13B); -//! @brief 8 bit General purpose register (64 bit mode only). -static const Register r14b(_Initialize(), REG_R14B); -//! @brief 8 bit General purpose register (64 bit mode only). -static const Register r15b(_Initialize(), REG_R15B); -#endif // ASMJIT_X64 - -//! @brief 16 bit General purpose register. -static const Register ax(_Initialize(), REG_AX); -//! @brief 16 bit General purpose register. -static const Register cx(_Initialize(), REG_CX); -//! @brief 16 bit General purpose register. -static const Register dx(_Initialize(), REG_DX); -//! @brief 16 bit General purpose register. -static const Register bx(_Initialize(), REG_BX); -//! @brief 16 bit General purpose register. -static const Register sp(_Initialize(), REG_SP); -//! @brief 16 bit General purpose register. -static const Register bp(_Initialize(), REG_BP); -//! @brief 16 bit General purpose register. -static const Register si(_Initialize(), REG_SI); -//! @brief 16 bit General purpose register. -static const Register di(_Initialize(), REG_DI); - -#if defined(ASMJIT_X64) -//! @brief 16 bit General purpose register (64 bit mode only). -static const Register r8w(_Initialize(), REG_R8W); -//! @brief 16 bit General purpose register (64 bit mode only). -static const Register r9w(_Initialize(), REG_R9W); -//! @brief 16 bit General purpose register (64 bit mode only). -static const Register r10w(_Initialize(), REG_R10W); -//! @brief 16 bit General purpose register (64 bit mode only). -static const Register r11w(_Initialize(), REG_R11W); -//! @brief 16 bit General purpose register (64 bit mode only). -static const Register r12w(_Initialize(), REG_R12W); -//! @brief 16 bit General purpose register (64 bit mode only). -static const Register r13w(_Initialize(), REG_R13W); -//! @brief 16 bit General purpose register (64 bit mode only). -static const Register r14w(_Initialize(), REG_R14W); -//! @brief 16 bit General purpose register (64 bit mode only). -static const Register r15w(_Initialize(), REG_R15W); -#endif // ASMJIT_X64 - -//! @brief 32 bit General purpose register. -static const Register eax(_Initialize(), REG_EAX); -//! @brief 32 bit General purpose register. -static const Register ecx(_Initialize(), REG_ECX); -//! @brief 32 bit General purpose register. -static const Register edx(_Initialize(), REG_EDX); -//! @brief 32 bit General purpose register. -static const Register ebx(_Initialize(), REG_EBX); -//! @brief 32 bit General purpose register. -static const Register esp(_Initialize(), REG_ESP); -//! @brief 32 bit General purpose register. -static const Register ebp(_Initialize(), REG_EBP); -//! @brief 32 bit General purpose register. -static const Register esi(_Initialize(), REG_ESI); -//! @brief 32 bit General purpose register. -static const Register edi(_Initialize(), REG_EDI); - -#if defined(ASMJIT_X64) -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register rax(_Initialize(), REG_RAX); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register rcx(_Initialize(), REG_RCX); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register rdx(_Initialize(), REG_RDX); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register rbx(_Initialize(), REG_RBX); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register rsp(_Initialize(), REG_RSP); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register rbp(_Initialize(), REG_RBP); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register rsi(_Initialize(), REG_RSI); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register rdi(_Initialize(), REG_RDI); - -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register r8(_Initialize(), REG_R8); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register r9(_Initialize(), REG_R9); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register r10(_Initialize(), REG_R10); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register r11(_Initialize(), REG_R11); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register r12(_Initialize(), REG_R12); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register r13(_Initialize(), REG_R13); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register r14(_Initialize(), REG_R14); -//! @brief 64 bit General purpose register (64 bit mode only). -static const Register r15(_Initialize(), REG_R15); -#endif // ASMJIT_X64 - -//! @brief 32 bit General purpose register. -static const Register nax(_Initialize(), REG_NAX); -//! @brief 32 bit General purpose register. -static const Register ncx(_Initialize(), REG_NCX); -//! @brief 32 bit General purpose register. -static const Register ndx(_Initialize(), REG_NDX); -//! @brief 32 bit General purpose register. -static const Register nbx(_Initialize(), REG_NBX); -//! @brief 32 bit General purpose register. -static const Register nsp(_Initialize(), REG_NSP); -//! @brief 32 bit General purpose register. -static const Register nbp(_Initialize(), REG_NBP); -//! @brief 32 bit General purpose register. -static const Register nsi(_Initialize(), REG_NSI); -//! @brief 32 bit General purpose register. -static const Register ndi(_Initialize(), REG_NDI); - -//! @brief 64 bit MMX register. -static const MMRegister mm0(_Initialize(), REG_MM0); -//! @brief 64 bit MMX register. -static const MMRegister mm1(_Initialize(), REG_MM1); -//! @brief 64 bit MMX register. -static const MMRegister mm2(_Initialize(), REG_MM2); -//! @brief 64 bit MMX register. -static const MMRegister mm3(_Initialize(), REG_MM3); -//! @brief 64 bit MMX register. -static const MMRegister mm4(_Initialize(), REG_MM4); -//! @brief 64 bit MMX register. -static const MMRegister mm5(_Initialize(), REG_MM5); -//! @brief 64 bit MMX register. -static const MMRegister mm6(_Initialize(), REG_MM6); -//! @brief 64 bit MMX register. -static const MMRegister mm7(_Initialize(), REG_MM7); - -//! @brief 128 bit SSE register. -static const XMMRegister xmm0(_Initialize(), REG_XMM0); -//! @brief 128 bit SSE register. -static const XMMRegister xmm1(_Initialize(), REG_XMM1); -//! @brief 128 bit SSE register. -static const XMMRegister xmm2(_Initialize(), REG_XMM2); -//! @brief 128 bit SSE register. -static const XMMRegister xmm3(_Initialize(), REG_XMM3); -//! @brief 128 bit SSE register. -static const XMMRegister xmm4(_Initialize(), REG_XMM4); -//! @brief 128 bit SSE register. -static const XMMRegister xmm5(_Initialize(), REG_XMM5); -//! @brief 128 bit SSE register. -static const XMMRegister xmm6(_Initialize(), REG_XMM6); -//! @brief 128 bit SSE register. -static const XMMRegister xmm7(_Initialize(), REG_XMM7); - -#if defined(ASMJIT_X64) -//! @brief 128 bit SSE register (64 bit mode only). -static const XMMRegister xmm8(_Initialize(), REG_XMM8); -//! @brief 128 bit SSE register (64 bit mode only). -static const XMMRegister xmm9(_Initialize(), REG_XMM9); -//! @brief 128 bit SSE register (64 bit mode only). -static const XMMRegister xmm10(_Initialize(), REG_XMM10); -//! @brief 128 bit SSE register (64 bit mode only). -static const XMMRegister xmm11(_Initialize(), REG_XMM11); -//! @brief 128 bit SSE register (64 bit mode only). -static const XMMRegister xmm12(_Initialize(), REG_XMM12); -//! @brief 128 bit SSE register (64 bit mode only). -static const XMMRegister xmm13(_Initialize(), REG_XMM13); -//! @brief 128 bit SSE register (64 bit mode only). -static const XMMRegister xmm14(_Initialize(), REG_XMM14); -//! @brief 128 bit SSE register (64 bit mode only). -static const XMMRegister xmm15(_Initialize(), REG_XMM15); -#endif // ASMJIT_X64 - -//! @brief Return general purpose register of byte size. -static inline Register mk_gpb(UInt8 index) ASMJIT_NOTHROW -{ return Register(_Initialize(), static_cast(index | REG_GPB)); } - -//! @brief Return general purpose register of word size. -static inline Register mk_gpw(UInt8 index) ASMJIT_NOTHROW -{ return Register(_Initialize(), static_cast(index | REG_GPW)); } - -//! @brief Return general purpose register of dword size. -static inline Register mk_gpd(UInt8 index) ASMJIT_NOTHROW -{ return Register(_Initialize(), static_cast(index | REG_GPD)); } - -#if defined(ASMJIT_X64) -//! @brief Return general purpose register of qword size (64 bit only). -static inline Register mk_gpq(UInt8 index) ASMJIT_NOTHROW -{ return Register(_Initialize(), static_cast(index | REG_GPQ)); } -#endif - -//! @brief Return general purpose dword/qword register (depending to architecture). -static inline Register mk_gpn(UInt8 index) ASMJIT_NOTHROW -{ return Register(_Initialize(), static_cast(index | REG_GPN)); } - -//! @brief Return MMX (MM) register . -static inline MMRegister mk_mm(UInt8 index) ASMJIT_NOTHROW -{ return MMRegister(_Initialize(), static_cast(index | REG_MM)); } - -//! @brief Return SSE (XMM) register. -static inline XMMRegister mk_xmm(UInt8 index) ASMJIT_NOTHROW -{ return XMMRegister(_Initialize(), static_cast(index | REG_XMM)); } - -//! @brief returns x87 register with index @a i. -static inline X87Register st(int i) ASMJIT_NOTHROW -{ - ASMJIT_ASSERT(i >= 0 && i < 8); - return X87Register(_Initialize(), static_cast(i)); -} - -// ============================================================================ -// [AsmJit::Mem] -// ============================================================================ - -//! @brief Memory location operand. -struct ASMJIT_HIDDEN Mem : public Operand -{ - inline Mem() ASMJIT_NOTHROW : - Operand(_DontInitialize()) - { - memset(&_mem, 0, sizeof(MemData)); - _mem.op = OP_MEM; - } - - inline Mem(Label* label, SysInt displacement, UInt8 size = 0) ASMJIT_NOTHROW : - Operand(_DontInitialize()) - { - _mem.op = OP_MEM; - _mem.size = size; - _mem.base = NO_REG; - _mem.index = NO_REG; - _mem.shift = 0; - _mem.segmentPrefix = SEGMENT_NONE; - _mem.hasLabel = true; - _mem.label = label; - _mem.displacement = displacement; - } - - inline Mem(const Register& base, SysInt displacement, UInt8 size = 0) ASMJIT_NOTHROW : - Operand(_DontInitialize()) - { - _mem.op = OP_MEM; - _mem.size = size; - _mem.base = base.code() & REGCODE_MASK; - _mem.index = NO_REG; - _mem.shift = 0; - _mem.segmentPrefix = SEGMENT_NONE; - _mem.hasLabel = false; - _mem.target = NULL; - _mem.displacement = displacement; - } - - inline Mem(const Register& base, const Register& index, UInt32 shift, SysInt displacement, UInt8 size = 0) ASMJIT_NOTHROW : - Operand(_DontInitialize()) - { - ASMJIT_ASSERT(shift <= 3); - _mem.op = OP_MEM; - _mem.size = size; - _mem.base = base.code() & REGCODE_MASK; - _mem.index = index.code() & REGCODE_MASK; - _mem.shift = (UInt8)shift; - _mem.segmentPrefix = SEGMENT_NONE; - _mem.hasLabel = false; - _mem.target = NULL; - _mem.displacement = displacement; - } - - inline Mem(const Mem& other) ASMJIT_NOTHROW : - Operand(other) - {} - - inline Mem& operator=(const Mem& other) ASMJIT_NOTHROW { _copy(other); return *this; } - - //! @brief Return if address has base register. - inline bool hasBase() const ASMJIT_NOTHROW - { return _mem.base != NO_REG; } - - //! @brief Return if address has index register. - inline bool hasIndex() const ASMJIT_NOTHROW - { return _mem.index != NO_REG; } - - //! @brief Address base register or @c NO_REG. - inline UInt8 base() const ASMJIT_NOTHROW - { return _mem.base; } - - //! @brief Address index register or @c NO_REG. - inline UInt8 index() const ASMJIT_NOTHROW - { return _mem.index; } - - //! @brief Address index scale (0, 1, 2 or 3). - inline UInt32 shift() const ASMJIT_NOTHROW - { return _mem.shift; } - - inline UInt8 segmentPrefix() const ASMJIT_NOTHROW - { return _mem.segmentPrefix; } - - inline UInt8 hasLabel() const ASMJIT_NOTHROW - { return _mem.hasLabel; } - - inline UInt8 hasTarget() const ASMJIT_NOTHROW - { return !_mem.hasLabel; } - - //! @brief Return Target. - //! - //! @note You should always check if operand is target by @c isTarget() - //! method, because labels and targets sharing data. - inline Label* label() const ASMJIT_NOTHROW - { return _mem.label; } - - //! @brief - //! - //! @note You should always check if operand is label based by @c isLabel() - //! method, because labels and targets sharing data. - inline void* target() const ASMJIT_NOTHROW - { return _mem.target; } - - //! @brief Address relative displacement. - inline SysInt displacement() const ASMJIT_NOTHROW - { return _mem.displacement; } - - //! @brief Set address relative displacement. - inline void setDisplacement(SysInt displacement) ASMJIT_NOTHROW - { _mem.displacement = displacement; } -}; - -// ============================================================================ -// [AsmJit::Mem - ptr[displacement]] -// ============================================================================ - -ASMJIT_API Mem _ptr_build(Label* label, SysInt disp, UInt8 ptrSize) ASMJIT_NOTHROW; - -//! @brief Create pointer operand with not specified size. -static inline Mem ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, 0); } - -//! @brief Create byte pointer operand. -static inline Mem byte_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, SIZE_BYTE); } - -//! @brief Create word (2 Bytes) pointer operand. -static inline Mem word_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, SIZE_WORD); } - -//! @brief Create dword (4 Bytes) pointer operand. -static inline Mem dword_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, SIZE_DWORD); } - -//! @brief Create qword (8 Bytes) pointer operand. -static inline Mem qword_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, SIZE_QWORD); } - -//! @brief Create tword (10 Bytes) pointer operand (used for 80 bit floating points). -static inline Mem tword_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, SIZE_TWORD); } - -//! @brief Create dqword (16 Bytes) pointer operand. -static inline Mem dqword_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, SIZE_DQWORD); } - -//! @brief Create mmword (8 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for mmx programming. -static inline Mem mmword_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, SIZE_QWORD); } - -//! @brief Create xmmword (16 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for sse programming. -static inline Mem xmmword_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, SIZE_DQWORD); } - -//! @brief Create system dependent pointer operand (32 bit or 64 bit). -static inline Mem sysint_ptr(Label* label, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, disp, sizeof(SysInt)); } - -ASMJIT_API Mem _ptr_build(Label* label, const Register& index, UInt32 shift, SysInt disp, UInt8 ptrSize) ASMJIT_NOTHROW; - -//! @brief Create pointer operand with not specified size. -static inline Mem ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, 0); } - -//! @brief Create byte pointer operand. -static inline Mem byte_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, SIZE_BYTE); } - -//! @brief Create word (2 Bytes) pointer operand. -static inline Mem word_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, SIZE_WORD); } - -//! @brief Create dword (4 Bytes) pointer operand. -static inline Mem dword_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, SIZE_DWORD); } - -//! @brief Create qword (8 Bytes) pointer operand. -static inline Mem qword_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, SIZE_QWORD); } - -//! @brief Create tword (10 Bytes) pointer operand (used for 80 bit floating points). -static inline Mem tword_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, SIZE_TWORD); } - -//! @brief Create dqword (16 Bytes) pointer operand. -static inline Mem dqword_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, SIZE_DQWORD); } - -//! @brief Create mmword (8 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for mmx programming. -static inline Mem mmword_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, SIZE_QWORD); } - -//! @brief Create xmmword (16 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for sse programming. -static inline Mem xmmword_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, SIZE_DQWORD); } - -//! @brief Create system dependent pointer operand (32 bit or 64 bit). -static inline Mem sysint_ptr(Label* label, const Register& index, UInt32 shift, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(label, index, shift, disp, sizeof(SysInt)); } - - -// --- absolute addressing --- -ASMJIT_API Mem _ptr_build_abs( - void* target, - SysInt disp, - UInt32 segmentPrefix, UInt8 ptrSize) ASMJIT_NOTHROW; - -//! @brief Create pointer operand with not specified size. -static inline Mem ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, 0); } - -//! @brief Create byte pointer operand. -static inline Mem byte_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, SIZE_BYTE); } - -//! @brief Create word (2 Bytes) pointer operand. -static inline Mem word_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, SIZE_WORD); } - -//! @brief Create dword (4 Bytes) pointer operand. -static inline Mem dword_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, SIZE_DWORD); } - -//! @brief Create qword (8 Bytes) pointer operand. -static inline Mem qword_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, SIZE_QWORD); } - -//! @brief Create tword (10 Bytes) pointer operand (used for 80 bit floating points). -static inline Mem tword_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, SIZE_TWORD); } - -//! @brief Create dqword (16 Bytes) pointer operand. -static inline Mem dqword_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, SIZE_DQWORD); } - -//! @brief Create mmword (8 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for mmx programming. -static inline Mem mmword_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, SIZE_QWORD); } - -//! @brief Create xmmword (16 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for sse programming. -static inline Mem xmmword_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, SIZE_DQWORD); } - -//! @brief Create system dependent pointer operand (32 bit or 64 bit). -static inline Mem sysint_ptr_abs(void* target, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, disp, segmentPrefix, sizeof(SysInt)); } - -ASMJIT_API Mem _ptr_build_abs( - void* target, - const Register& index, UInt32 shift, SysInt disp, - UInt32 segmentPrefix, UInt8 ptrSize) ASMJIT_NOTHROW; - -//! @brief Create pointer operand with not specified size. -static inline Mem ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, 0); } - -//! @brief Create byte pointer operand. -static inline Mem byte_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, SIZE_BYTE); } - -//! @brief Create word (2 Bytes) pointer operand. -static inline Mem word_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, SIZE_WORD); } - -//! @brief Create dword (4 Bytes) pointer operand. -static inline Mem dword_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, SIZE_DWORD); } - -//! @brief Create qword (8 Bytes) pointer operand. -static inline Mem qword_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, SIZE_QWORD); } - -//! @brief Create tword (10 Bytes) pointer operand (used for 80 bit floating points). -static inline Mem tword_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, SIZE_TWORD); } - -//! @brief Create dqword (16 Bytes) pointer operand. -static inline Mem dqword_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, SIZE_DQWORD); } - -//! @brief Create mmword (8 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for mmx programming. -static inline Mem mmword_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, SIZE_QWORD); } - -//! @brief Create xmmword (16 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for sse programming. -static inline Mem xmmword_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, SIZE_DQWORD); } - -//! @brief Create system dependent pointer operand (32 bit or 64 bit). -static inline Mem sysint_ptr_abs(void* target, const Register& index, UInt32 shift, SysInt disp = 0, UInt32 segmentPrefix = SEGMENT_NONE) ASMJIT_NOTHROW -{ return _ptr_build_abs(target, index, shift, disp, segmentPrefix, sizeof(SysInt)); } -// --- absolute addressing --- - - -// ============================================================================ -// [AsmJit::Mem - ptr[base + displacement]] -// ============================================================================ - -ASMJIT_API Mem _ptr_build(const Register& base, SysInt disp, UInt8 ptrSize) ASMJIT_NOTHROW; - -//! @brief Create pointer operand with not specified size. -static inline Mem ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, 0); } - -//! @brief Create byte pointer operand. -static inline Mem byte_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, SIZE_BYTE); } - -//! @brief Create word (2 Bytes) pointer operand. -static inline Mem word_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, SIZE_WORD); } - -//! @brief Create dword (4 Bytes) pointer operand. -static inline Mem dword_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, SIZE_DWORD); } - -//! @brief Create qword (8 Bytes) pointer operand. -static inline Mem qword_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, SIZE_QWORD); } - -//! @brief Create tword (10 Bytes) pointer operand (used for 80 bit floating points). -static inline Mem tword_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, SIZE_TWORD); } - -//! @brief Create dqword (16 Bytes) pointer operand. -static inline Mem dqword_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, SIZE_DQWORD); } - -//! @brief Create mmword (8 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for mmx programming. -static inline Mem mmword_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, SIZE_QWORD); } - -//! @brief Create xmmword (16 bytes) pointer operand -//! -//! @note This constructor is provided only for convenience for sse programming. -static inline Mem xmmword_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, SIZE_DQWORD); } - -//! @brief Create system dependent pointer operand (32 bit or 64 bit). -static inline Mem sysint_ptr(const Register& base, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, disp, sizeof(SysInt)); } - -// ============================================================================ -// [AsmJit::Mem - ptr[base + (index << shift) + displacement]] -// ============================================================================ - -ASMJIT_API Mem _ptr_build(const Register& base, const Register& index, UInt32 shift, SysInt disp, UInt8 ptrSize) ASMJIT_NOTHROW; - -//! @brief Create pointer operand with not specified size. -static inline Mem ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, 0); } - -//! @brief Create byte pointer operand. -static inline Mem byte_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, SIZE_BYTE); } - -//! @brief Create word (2 Bytes) pointer operand. -static inline Mem word_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, SIZE_WORD); } - -//! @brief Create dword (4 Bytes) pointer operand. -static inline Mem dword_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, SIZE_DWORD); } - -//! @brief Create qword (8 Bytes) pointer operand. -static inline Mem qword_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, SIZE_QWORD); } - -//! @brief Create tword (10 Bytes) pointer operand (used for 80 bit floating points). -static inline Mem tword_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, SIZE_TWORD); } - -//! @brief Create dqword (16 Bytes) pointer operand. -static inline Mem dqword_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, SIZE_DQWORD); } - -//! @brief Create mmword (8 Bytes) pointer operand). -//! -//! @note This constructor is provided only for convenience for mmx programming. -static inline Mem mmword_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, SIZE_QWORD); } - -//! @brief Create xmmword (16 Bytes) pointer operand. -//! -//! @note This constructor is provided only for convenience for sse programming. -static inline Mem xmmword_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, SIZE_DQWORD); } - -//! @brief Create system dependent pointer operand (32 bit or 64 bit). -static inline Mem sysint_ptr(const Register& base, const Register& index, UInt32 shift = 0, SysInt disp = 0) ASMJIT_NOTHROW -{ return _ptr_build(base, index, shift, disp, sizeof(SysInt)); } - -// ============================================================================ -// [AsmJit::Immediate] -// ============================================================================ - -//! @brief Immediate operand. -//! -//! Immediate operand is value that is inlined in binary instruction stream. -//! -//! To create immediate operand, use @c imm() and @c uimm() constructors -//! or constructors provided by @c Immediate class itself. -struct ASMJIT_HIDDEN Immediate : public Operand -{ - Immediate() ASMJIT_NOTHROW : Operand(_DontInitialize()) - { - memset(&_imm, 0, sizeof(ImmData)); - _imm.op = OP_IMM; - } - - Immediate(SysInt i) ASMJIT_NOTHROW : Operand(_DontInitialize()) - { - memset(&_imm, 0, sizeof(ImmData)); - _imm.op = OP_IMM; - _imm.value = i; - } - - Immediate(SysInt i, UInt8 isUnsigned) ASMJIT_NOTHROW : Operand(_DontInitialize()) - { - memset(&_imm, 0, sizeof(ImmData)); - _imm.op = OP_IMM; - _imm.isUnsigned = isUnsigned; - _imm.value = i; - } - - inline Immediate(const Immediate& other) ASMJIT_NOTHROW : Operand(other) {} - - inline Immediate& operator=(SysInt val) ASMJIT_NOTHROW - { setValue(val); return *this; } - - inline Immediate& operator=(const Immediate& other) ASMJIT_NOTHROW - { _copy(other); return *this; } - - //! @brief Return true if immediate is unsigned value. - inline UInt8 isUnsigned() const ASMJIT_NOTHROW { return _imm.isUnsigned; } - - //! @brief Return relocation mode. - inline UInt8 relocMode() const ASMJIT_NOTHROW { return _imm.relocMode; } - - //! @brief Return signed immediate value. - inline SysInt value() const ASMJIT_NOTHROW { return _imm.value; } - - //! @brief Return unsigned immediate value. - inline SysUInt uvalue() const ASMJIT_NOTHROW { return (SysUInt)_imm.value; } - - //! @brief Set immediate value as signed type to @a val. - inline void setValue(SysInt val, UInt8 isUnsigned = false) ASMJIT_NOTHROW - { - _imm.value = val; - _imm.isUnsigned = isUnsigned; - } - - //! @brief Set immediate value as unsigned type to @a val. - inline void setUValue(SysUInt val) ASMJIT_NOTHROW - { - _imm.value = (SysInt)val; - _imm.isUnsigned = true; - } -}; - -//! @brief Create signed immediate value operand. -ASMJIT_API Immediate imm(SysInt i) ASMJIT_NOTHROW; - -//! @brief Create unsigned immediate value operand. -ASMJIT_API Immediate uimm(SysUInt i) ASMJIT_NOTHROW; - -// ============================================================================ -// [AsmJit::Label] -// ============================================================================ - -//! @brief Label (jump target or data location). -//! -//! Label represents locations typically used as jump targets, but may be also -//! used as position where are stored constants or static variables. There are -//! different rules to use labels by @c Assembler and @c Compiler. -//! -//! If you are using low level @c Assembler class to generate machine code, you -//! are probably creating labels statically while @c Compiler needs to create -//! label dynamically by @c AsmJit::Compiler::newLabel() method. Never use -//! statically created labels with @c Compiler or you get to unexpected -//! behavior. -//! -//! Example of using labels with @c Assembler: -//! @code -//! // Assembler instance -//! Assembler a; -//! -//! // Your label (there is no problem to allocate it on the stack). -//! Label L_1; -//! -//! // ... your code ... -//! -//! // Using label, see @c AsmJit::Serializer instrinsics. -//! a.jump(&L_1); -//! -//! // ... your code ... -//! -//! // Bind label to current position, see @c AsmJit::Serializer::bind(). -//! a.bind(&L_1); -//! @endcode -//! -//! Example of using labels with @c Compiler: -//! @code -//! // Compiler instance -//! Compiler a; -//! -//! // Your label (must be created by @c Compiler). -//! Label* L_1 = c.newLabel(); -//! -//! // ... your code ... -//! -//! // Using label, see @c AsmJit::Serializer instrinsics. -//! a.jump(L_1); -//! -//! // ... your code ... -//! -//! // Bind label to current position, see @c AsmJit::Serializer::bind(). -//! a.bind(L_1); -//! @endcode -struct ASMJIT_HIDDEN Label : public Operand -{ - //! @brief Create new unused label. - inline Label(UInt32 id = 0) ASMJIT_NOTHROW - { - _lbl.op = OP_LABEL; - _lbl.size = 4; - _lbl.state = LABEL_STATE_UNUSED; - _lbl.id = id; - _lbl.position = -1; - _lbl.link = NULL; - } - - //! @brief Destroy label. If label is linked to some location (not bound), - //! assertion is raised (because generated code is invalid in this case). - inline ~Label() ASMJIT_NOTHROW - { ASMJIT_ASSERT(!isLinked()); } - - //! @brief Unuse label (unbound or unlink) - Use with caution. - inline void unuse() ASMJIT_NOTHROW - { - memset(&_lbl, 0, sizeof(LblData)); - _lbl.op = OP_LABEL; - _lbl.position = -1; - } - - //! @brief Return label state, see @c LABEL_STATE. */ - inline UInt8 state() const ASMJIT_NOTHROW - { return _lbl.state; } - - //! @brief Return label Id. - inline UInt32 labelId() const ASMJIT_NOTHROW - { return _lbl.id; } - - //! @brief Returns @c true if label is unused (not bound or linked). - inline bool isUnused() const ASMJIT_NOTHROW - { return _lbl.state == LABEL_STATE_UNUSED; } - - //! @brief Returns @c true if label is linked. - inline bool isLinked() const ASMJIT_NOTHROW - { return _lbl.state == LABEL_STATE_LINKED; } - - //! @brief Returns @c true if label is bound. - inline bool isBound() const ASMJIT_NOTHROW - { return _lbl.state == LABEL_STATE_BOUND; } - - //! @brief Returns the position of bound or linked labels, -1 if label - //! is unused. - inline SysInt position() const ASMJIT_NOTHROW - { return _lbl.position; } - - //! @brief Set label Id. - inline void setId(UInt32 id) ASMJIT_NOTHROW - { _lbl.id = id; } - - //! @brief Set state and position - inline void setStatePos(UInt8 state, SysInt position) ASMJIT_NOTHROW - { - _lbl.state = state; - _lbl.position = position; - } -}; - -// ============================================================================ -// [AsmJit::mm_shuffle] -// ============================================================================ - -//! @brief Create Shuffle Constant for MMX/SSE shuffle instrutions. -//! @param z First component position, number at interval [0, 3]. -//! @param x Second component position, number at interval [0, 3]. -//! @param y Third component position, number at interval [0, 3]. -//! @param w Fourth component position, number at interval [0, 3]. -//! -//! Shuffle constants are used in these instructions: -//! - @c AsmJit::SerializerIntrinsics::pshufw() -//! - @c AsmJit::SerializerIntrinsics::pshufd() -//! - @c AsmJit::SerializerIntrinsics::pshufhw() -//! - @c AsmJit::SerializerIntrinsics::pshuflw() -//! - @c AsmJit::SerializerIntrinsics::shufps() -static inline UInt8 mm_shuffle(UInt8 z, UInt8 y, UInt8 x, UInt8 w) ASMJIT_NOTHROW -{ return (z << 6) | (y << 4) | (x << 2) | w; } - -// ============================================================================ -// [AsmJit::SerializerCore] -// ============================================================================ - -//! @brief Assembler intrinsics seralizer. -//! -//! SerializerCore is abstract class that is used by @c Assembler and @a Compiler. -//! You probably never use this class directly, instead you use it to serialize -//! intrinsics to @c Assembler or @c Compiler. @c SerializerIntrinsics implements -//! all intruction intrinsics thats used and @c Serializer is public serializer -//! class that should be used (instead of @c SerializerCore or @c SerializerInstrinsics). -//! -//! @note Use always @c Serializer class, this class is only designed to -//! decrease code size when exporting AsmJit library symbols. Some compilers -//! (for example MSVC) are exporting inline symbols when class is declared -//! to export them and @c Serializer class contains really huge count of -//! symbols that will be never used (everything is inlined). -struct ASMJIT_API SerializerCore -{ - // ------------------------------------------------------------------------- - // [Construction / Destruction] - // ------------------------------------------------------------------------- - - //! @brief Create SerializerCore instance. - SerializerCore() ASMJIT_NOTHROW; - //! @brief Destroy SerializerCore instance. - virtual ~SerializerCore() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Properties] - // ------------------------------------------------------------------------- - - //! @brief Get property @a key from serializer. - //! - //! Method returns old property value on success, otherwise 0xFFFFFFFF. - virtual UInt32 getProperty(UInt32 key) ASMJIT_NOTHROW; - - //! @brief Set property @a key to @a value. - virtual UInt32 setProperty(UInt32 key, UInt32 value) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Logging] - // ------------------------------------------------------------------------- - - //! @brief Return logger or @c NULL (if none). - inline Logger* logger() const ASMJIT_NOTHROW - { return _logger; } - - //! @brief Set logger to @a logger. - virtual void setLogger(Logger* logger) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Abstract Emitters] - // ------------------------------------------------------------------------- - - //! @brief Adds inline comment to next generated instruction. - //! - //! This method is only iseful when debugging (present Logger). If Logger is - //! not set, it does nothing. - //! - //! @param text String that contains comment. - //! @param len Length of that string or -1 to detect it using @c strlen(). - virtual void _inlineComment(const char* text, SysInt len) ASMJIT_NOTHROW = 0; - - //! @brief Emits X86/FPU or MM instruction. - //! - //! Operands @a o1, @a o2 or @a o3 can be @c NULL if they are not used. - //! - //! Hint: Use @c emitX86() helpers to emit instructions. - virtual void _emitX86(UInt32 code, const Operand* o1, const Operand* o2, const Operand* o3) ASMJIT_NOTHROW = 0; - - // Helpers to decrease binary code size. These four emit methods are just - // helpers thats used by serializer. They call _emitX86() adding NULLs - // to first, second and third operand if needed. - - //! @brief Emits instruction with no operand. - //! - //! Should be use as an alternative to @c _emitX86() method. - void emitX86(UInt32 code) ASMJIT_NOTHROW; - //! @brief Emits instruction with one operand. - //! - //! Should be use as an alternative to @c _emitX86() method. - void emitX86(UInt32 code, const Operand* o1) ASMJIT_NOTHROW; - //! @brief Emits instruction with two operands. - //! - //! Should be use as an alternative to @c _emitX86() method. - void emitX86(UInt32 code, const Operand* o1, const Operand* o2) ASMJIT_NOTHROW; - //! @brief Emits instruction with three operands. - //! - //! Should be use as an alternative to @c _emitX86() method. - void emitX86(UInt32 code, const Operand* o1, const Operand* o2, const Operand* o3) ASMJIT_NOTHROW; - - //! @brief Private method for emitting jcc. - //! @internal This should be probably private. - void _emitJcc(UInt32 code, Label* label, UInt32 hint) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Embed] - // ------------------------------------------------------------------------- - - //! @brief Embed data into instruction stream. - virtual void _embed(const void* dataPtr, SysUInt dataLen) ASMJIT_NOTHROW = 0; - - // ------------------------------------------------------------------------- - // [Align] - // ------------------------------------------------------------------------- - - //! @brief Align buffer to @a m bytes. - //! - //! Typical usage of this is to align labels at start of inner loops. - //! - //! Inserts @c nop() instructions. - virtual void align(SysInt m) ASMJIT_NOTHROW = 0; - - // ------------------------------------------------------------------------- - // [Bind] - // ------------------------------------------------------------------------- - - //! @brief Bind label to the current offset. - //! - //! @note Label can be bound only once! - virtual void bind(Label* label) ASMJIT_NOTHROW = 0; - - // ------------------------------------------------------------------------- - // [Memory Management] - // ------------------------------------------------------------------------- - - //! @brief Allocate memory using Assembler or Compiler internal memory manager. - void* _zoneAlloc(SysUInt size) ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Error Handling] - // ------------------------------------------------------------------------- - - //! @brief Return last assembler error code. - inline UInt32 error() const ASMJIT_NOTHROW - { return _error; } - - //! @brief Set assembler/compiler error code. - //! - //! This method is virtual, because code generator can use it to catch - //! all errors. - virtual void setError(UInt32 error) ASMJIT_NOTHROW; - - //! @brief Clear assembler/compiler error code. - virtual void clearError() ASMJIT_NOTHROW; - - // ------------------------------------------------------------------------- - // [Make] - // ------------------------------------------------------------------------- - - //! @brief Make is convenience method to make currently serialized code and - //! return pointer to generated function. - //! - //! What you need is only to cast this pointer to your function type and call - //! it. Note that if there was an error and calling @c error() method not - //! returns @c ERROR_NONE (zero) then this function always return @c NULL and - //! error will value remains the same. - //! - //! As a convenience you can pass your own memory manager that will be used - //! to allocate virtual memory, default NULL value means to use default memory - //! manager that can be get by @c AsmJit::MemoryManager::global() method. - //! - //! Default allocation type is @c MEMORY_ALLOC_FREEABLE. If you need pernament - //! allocation you should use MEMORY_ALLOC_PERNAMENT instead. - virtual void* make(MemoryManager* memoryManager = NULL, UInt32 allocType = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW = 0; - - // ------------------------------------------------------------------------- - // [Constants] - // ------------------------------------------------------------------------- - - //! @brief Map used for jcc instructions. - static const UInt32 _jcctable[16]; - //! @brief Map used for cmovcc instructions. - static const UInt32 _cmovcctable[16]; - //! @brief Map used for setcc instructions. - static const UInt32 _setcctable[16]; - - //! @brief Translate condition code @a CC to AsmJit jump (jcc) instruction code. - //! @sa @c INST_CODE, @c INST_J. - static inline UInt32 conditionToJCC(CONDITION cc) ASMJIT_NOTHROW - { - ASMJIT_ASSERT(static_cast(cc) <= 0xF); - return _jcctable[cc]; - } - - //! @brief Translate condition code @a CC to AsmJit cmov (cmovcc) instruction code. - //! @sa @c INST_CODE, @c INST_CMOV. - static inline UInt32 conditionToCMovCC(CONDITION cc) ASMJIT_NOTHROW - { - ASMJIT_ASSERT(static_cast(cc) <= 0xF); - return _cmovcctable[cc]; - } - - //! @brief Translate condition code @a CC to AsmJit set (setcc) instruction code. - //! @sa @c INST_CODE, @c INST_SET. - static inline UInt32 conditionToSetCC(CONDITION cc) ASMJIT_NOTHROW - { - ASMJIT_ASSERT(static_cast(cc) <= 0xF); - return _setcctable[cc]; - } - - // ------------------------------------------------------------------------- - // [Members] - // ------------------------------------------------------------------------- -protected: - - //! @brief Logger. - Logger* _logger; - - //! @brief Zone memory management. - Zone _zone; - - //! @brief Properties. - UInt32 _properties; - - //! @brief Last error code. - UInt32 _error; - -private: - friend struct AssemblerCore; - friend struct CompilerCore; - - // Disable copy. - ASMJIT_DISABLE_COPY(SerializerCore); -}; - -// ============================================================================ -// [AsmJit::Serializer] -// ============================================================================ - -//! @brief Assembler instruction serializer. -struct ASMJIT_HIDDEN SerializerIntrinsics : public SerializerCore -{ - inline SerializerIntrinsics() ASMJIT_NOTHROW {} - - // ------------------------------------------------------------------------- - // [Embed] - // ------------------------------------------------------------------------- - - inline void db(UInt8 x) ASMJIT_NOTHROW { _embed(&x, 1); } - inline void dw(UInt16 x) ASMJIT_NOTHROW { _embed(&x, 2); } - inline void dd(UInt32 x) ASMJIT_NOTHROW { _embed(&x, 4); } - inline void dq(UInt64 x) ASMJIT_NOTHROW { _embed(&x, 8); } - - inline void dint8(Int8 x) ASMJIT_NOTHROW { _embed(&x, sizeof(Int8)); } - inline void duint8(UInt8 x) ASMJIT_NOTHROW { _embed(&x, sizeof(UInt8)); } - - inline void dint16(Int16 x) ASMJIT_NOTHROW { _embed(&x, sizeof(Int16)); } - inline void duint16(UInt16 x) ASMJIT_NOTHROW { _embed(&x, sizeof(UInt16)); } - - inline void dint32(Int32 x) ASMJIT_NOTHROW { _embed(&x, sizeof(Int32)); } - inline void duint32(UInt32 x) ASMJIT_NOTHROW { _embed(&x, sizeof(UInt32)); } - - inline void dint64(Int64 x) ASMJIT_NOTHROW { _embed(&x, sizeof(Int64)); } - inline void duint64(UInt64 x) ASMJIT_NOTHROW { _embed(&x, sizeof(UInt64)); } - - inline void dsysint(SysInt x) ASMJIT_NOTHROW { _embed(&x, sizeof(SysInt)); } - inline void dsysuint(SysUInt x) ASMJIT_NOTHROW { _embed(&x, sizeof(SysUInt)); } - - inline void dfloat(float x) ASMJIT_NOTHROW { _embed(&x, sizeof(float)); } - inline void ddouble(double x) ASMJIT_NOTHROW { _embed(&x, sizeof(double)); } - - inline void dptr(void* x) ASMJIT_NOTHROW { _embed(&x, sizeof(void*)); } - - inline void dmm(const MMData& x) ASMJIT_NOTHROW { _embed(&x, sizeof(MMData)); } - inline void dxmm(const XMMData& x) ASMJIT_NOTHROW { _embed(&x, sizeof(XMMData)); } - - inline void data(const void* data, SysUInt size) ASMJIT_NOTHROW { _embed(data, size); } - - template - inline void dstruct(const T& x) ASMJIT_NOTHROW { _embed(&x, sizeof(T)); } - - // ------------------------------------------------------------------------- - // [X86 Instructions] - // ------------------------------------------------------------------------- - - //! @brief Add with Carry. - inline void adc(const Register& dst, const Register& src) - { - emitX86(INST_ADC, &dst, &src); - } - //! @brief Add with Carry. - inline void adc(const Register& dst, const Mem& src) - { - emitX86(INST_ADC, &dst, &src); - } - //! @brief Add with Carry. - inline void adc(const Register& dst, const Immediate& src) - { - emitX86(INST_ADC, &dst, &src); - } - //! @brief Add with Carry. - inline void adc(const Mem& dst, const Register& src) - { - emitX86(INST_ADC, &dst, &src); - } - //! @brief Add with Carry. - inline void adc(const Mem& dst, const Immediate& src) - { - emitX86(INST_ADC, &dst, &src); - } - - //! @brief Add. - inline void add(const Register& dst, const Register& src) - { - emitX86(INST_ADD, &dst, &src); - } - //! @brief Add. - inline void add(const Register& dst, const Mem& src) - { - emitX86(INST_ADD, &dst, &src); - } - //! @brief Add. - inline void add(const Register& dst, const Immediate& src) - { - emitX86(INST_ADD, &dst, &src); - } - //! @brief Add. - inline void add(const Mem& dst, const Register& src) - { - emitX86(INST_ADD, &dst, &src); - } - //! @brief Add. - inline void add(const Mem& dst, const Immediate& src) - { - emitX86(INST_ADD, &dst, &src); - } - - //! @brief Logical And. - inline void and_(const Register& dst, const Register& src) - { - emitX86(INST_AND, &dst, &src); - } - //! @brief Logical And. - inline void and_(const Register& dst, const Mem& src) - { - emitX86(INST_AND, &dst, &src); - } - //! @brief Logical And. - inline void and_(const Register& dst, const Immediate& src) - { - emitX86(INST_AND, &dst, &src); - } - //! @brief Logical And. - inline void and_(const Mem& dst, const Register& src) - { - emitX86(INST_AND, &dst, &src); - } - //! @brief Logical And. - inline void and_(const Mem& dst, const Immediate& src) - { - emitX86(INST_AND, &dst, &src); - } - - //! @brief Bit Scan Forward. - inline void bsf(const Register& dst, const Register& src) - { - ASMJIT_ASSERT(!dst.isRegType(REG_GPB)); - emitX86(INST_BSF, &dst, &src); - } - //! @brief Bit Scan Forward. - inline void bsf(const Register& dst, const Mem& src) - { - ASMJIT_ASSERT(!dst.isRegType(REG_GPB)); - emitX86(INST_BSF, &dst, &src); - } - - //! @brief Bit Scan Reverse. - inline void bsr(const Register& dst, const Register& src) - { - ASMJIT_ASSERT(!dst.isRegType(REG_GPB)); - emitX86(INST_BSR, &dst, &src); - } - //! @brief Bit Scan Reverse. - inline void bsr(const Register& dst, const Mem& src) - { - ASMJIT_ASSERT(!dst.isRegType(REG_GPB)); - emitX86(INST_BSR, &dst, &src); - } - - //! @brief Byte swap (32 bit or 64 bit registers only) (i486). - inline void bswap(const Register& dst) - { - ASMJIT_ASSERT(dst.type() == REG_GPD || dst.type() == REG_GPQ); - emitX86(INST_BSWAP, &dst); - } - - //! @brief Bit test. - inline void bt(const Register& dst, const Register& src) - { - emitX86(INST_BT, &dst, &src); - } - //! @brief Bit test. - inline void bt(const Register& dst, const Immediate& src) - { - emitX86(INST_BT, &dst, &src); - } - //! @brief Bit test. - inline void bt(const Mem& dst, const Register& src) - { - emitX86(INST_BT, &dst, &src); - } - //! @brief Bit test. - inline void bt(const Mem& dst, const Immediate& src) - { - emitX86(INST_BT, &dst, &src); - } - - //! @brief Bit test and complement. - inline void btc(const Register& dst, const Register& src) - { - emitX86(INST_BTC, &dst, &src); - } - //! @brief Bit test and complement. - inline void btc(const Register& dst, const Immediate& src) - { - emitX86(INST_BTC, &dst, &src); - } - //! @brief Bit test and complement. - inline void btc(const Mem& dst, const Register& src) - { - emitX86(INST_BTC, &dst, &src); - } - //! @brief Bit test and complement. - inline void btc(const Mem& dst, const Immediate& src) - { - emitX86(INST_BTC, &dst, &src); - } - - //! @brief Bit test and reset. - inline void btr(const Register& dst, const Register& src) - { - emitX86(INST_BTR, &dst, &src); - } - //! @brief Bit test and reset. - inline void btr(const Register& dst, const Immediate& src) - { - emitX86(INST_BTR, &dst, &src); - } - //! @brief Bit test and reset. - inline void btr(const Mem& dst, const Register& src) - { - emitX86(INST_BTR, &dst, &src); - } - //! @brief Bit test and reset. - inline void btr(const Mem& dst, const Immediate& src) - { - emitX86(INST_BTR, &dst, &src); - } - - //! @brief Bit test and set. - inline void bts(const Register& dst, const Register& src) - { - emitX86(INST_BTS, &dst, &src); - } - //! @brief Bit test and set. - inline void bts(const Register& dst, const Immediate& src) - { - emitX86(INST_BTS, &dst, &src); - } - //! @brief Bit test and set. - inline void bts(const Mem& dst, const Register& src) - { - emitX86(INST_BTS, &dst, &src); - } - //! @brief Bit test and set. - inline void bts(const Mem& dst, const Immediate& src) - { - emitX86(INST_BTS, &dst, &src); - } - - //! @brief Call Procedure. - inline void call(const Register& dst) - { - ASMJIT_ASSERT(dst.isRegType(REG_GPN)); - emitX86(INST_CALL, &dst); - } - //! @brief Call Procedure. - inline void call(const Mem& dst) - { - emitX86(INST_CALL, &dst); - } - //! @brief Call Procedure. - inline void call(const Immediate& dst) - { - emitX86(INST_CALL, &dst); - } - //! @brief Jump. - //! @overload - inline void call(void* dst) - { - Immediate imm((SysInt)dst); - emitX86(INST_CALL, &imm); - } - - //! @brief Call Procedure. - inline void call(Label* label) - { - emitX86(INST_CALL, label); - } - - //! @brief Convert Byte to Word (Sign Extend). - //! - //! AX <- Sign Extend AL - inline void cbw() - { - emitX86(INST_CBW); - } - - //! @brief Convert Word to DWord (Sign Extend). - //! - //! EAX <- Sign Extend AX - inline void cwde() - { - emitX86(INST_CWDE); - } - -#if defined(ASMJIT_X64) - //! @brief Convert DWord to QWord (Sign Extend). - //! - //! RAX <- Sign Extend EAX - inline void cdqe() - { - emitX86(INST_CDQE); - } -#endif // ASMJIT_X64 - - //! @brief Clear CARRY flag - //! - //! This instruction clears the CF flag in the EFLAGS register. - inline void clc() - { - emitX86(INST_CLC); - } - - //! @brief Clear Direction flag - //! - //! This instruction clears the DF flag in the EFLAGS register. - inline void cld() - { - emitX86(INST_CLD); - } - - //! @brief Complement Carry Flag. - //! - //! This instruction complements the CF flag in the EFLAGS register. - //! (CF = NOT CF) - inline void cmc() - { - emitX86(INST_CMC); - } - - //! @brief Conditional Move. - inline void cmov(CONDITION cc, const Register& dst, const Register& src) - { - emitX86(conditionToCMovCC(cc), &dst, &src); - } - - //! @brief Conditional Move. - inline void cmov(CONDITION cc, const Register& dst, const Mem& src) - { - emitX86(conditionToCMovCC(cc), &dst, &src); - } - - //! @brief Conditional Move. - inline void cmova (const Register& dst, const Register& src) { emitX86(INST_CMOVA , &dst, &src); } - //! @brief Conditional Move. - inline void cmova (const Register& dst, const Mem& src) { emitX86(INST_CMOVA , &dst, &src); } - //! @brief Conditional Move. - inline void cmovae (const Register& dst, const Register& src) { emitX86(INST_CMOVAE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovae (const Register& dst, const Mem& src) { emitX86(INST_CMOVAE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovb (const Register& dst, const Register& src) { emitX86(INST_CMOVB , &dst, &src); } - //! @brief Conditional Move. - inline void cmovb (const Register& dst, const Mem& src) { emitX86(INST_CMOVB , &dst, &src); } - //! @brief Conditional Move. - inline void cmovbe (const Register& dst, const Register& src) { emitX86(INST_CMOVBE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovbe (const Register& dst, const Mem& src) { emitX86(INST_CMOVBE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovc (const Register& dst, const Register& src) { emitX86(INST_CMOVC , &dst, &src); } - //! @brief Conditional Move. - inline void cmovc (const Register& dst, const Mem& src) { emitX86(INST_CMOVC , &dst, &src); } - //! @brief Conditional Move. - inline void cmove (const Register& dst, const Register& src) { emitX86(INST_CMOVE , &dst, &src); } - //! @brief Conditional Move. - inline void cmove (const Register& dst, const Mem& src) { emitX86(INST_CMOVE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovg (const Register& dst, const Register& src) { emitX86(INST_CMOVG , &dst, &src); } - //! @brief Conditional Move. - inline void cmovg (const Register& dst, const Mem& src) { emitX86(INST_CMOVG , &dst, &src); } - //! @brief Conditional Move. - inline void cmovge (const Register& dst, const Register& src) { emitX86(INST_CMOVGE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovge (const Register& dst, const Mem& src) { emitX86(INST_CMOVGE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovl (const Register& dst, const Register& src) { emitX86(INST_CMOVL , &dst, &src); } - //! @brief Conditional Move. - inline void cmovl (const Register& dst, const Mem& src) { emitX86(INST_CMOVL , &dst, &src); } - //! @brief Conditional Move. - inline void cmovle (const Register& dst, const Register& src) { emitX86(INST_CMOVLE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovle (const Register& dst, const Mem& src) { emitX86(INST_CMOVLE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovna (const Register& dst, const Register& src) { emitX86(INST_CMOVNA , &dst, &src); } - //! @brief Conditional Move. - inline void cmovna (const Register& dst, const Mem& src) { emitX86(INST_CMOVNA , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnae(const Register& dst, const Register& src) { emitX86(INST_CMOVNAE, &dst, &src); } - //! @brief Conditional Move. - inline void cmovnae(const Register& dst, const Mem& src) { emitX86(INST_CMOVNAE, &dst, &src); } - //! @brief Conditional Move. - inline void cmovnb (const Register& dst, const Register& src) { emitX86(INST_CMOVNB , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnb (const Register& dst, const Mem& src) { emitX86(INST_CMOVNB , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnbe(const Register& dst, const Register& src) { emitX86(INST_CMOVNBE, &dst, &src); } - //! @brief Conditional Move. - inline void cmovnbe(const Register& dst, const Mem& src) { emitX86(INST_CMOVNBE, &dst, &src); } - //! @brief Conditional Move. - inline void cmovnc (const Register& dst, const Register& src) { emitX86(INST_CMOVNC , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnc (const Register& dst, const Mem& src) { emitX86(INST_CMOVNC , &dst, &src); } - //! @brief Conditional Move. - inline void cmovne (const Register& dst, const Register& src) { emitX86(INST_CMOVNE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovne (const Register& dst, const Mem& src) { emitX86(INST_CMOVNE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovng (const Register& dst, const Register& src) { emitX86(INST_CMOVNG , &dst, &src); } - //! @brief Conditional Move. - inline void cmovng (const Register& dst, const Mem& src) { emitX86(INST_CMOVNG , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnge(const Register& dst, const Register& src) { emitX86(INST_CMOVNGE, &dst, &src); } - //! @brief Conditional Move. - inline void cmovnge(const Register& dst, const Mem& src) { emitX86(INST_CMOVNGE, &dst, &src); } - //! @brief Conditional Move. - inline void cmovnl (const Register& dst, const Register& src) { emitX86(INST_CMOVNL , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnl (const Register& dst, const Mem& src) { emitX86(INST_CMOVNL , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnle(const Register& dst, const Register& src) { emitX86(INST_CMOVNLE, &dst, &src); } - //! @brief Conditional Move. - inline void cmovnle(const Register& dst, const Mem& src) { emitX86(INST_CMOVNLE, &dst, &src); } - //! @brief Conditional Move. - inline void cmovno (const Register& dst, const Register& src) { emitX86(INST_CMOVNO , &dst, &src); } - //! @brief Conditional Move. - inline void cmovno (const Register& dst, const Mem& src) { emitX86(INST_CMOVNO , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnp (const Register& dst, const Register& src) { emitX86(INST_CMOVNP , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnp (const Register& dst, const Mem& src) { emitX86(INST_CMOVNP , &dst, &src); } - //! @brief Conditional Move. - inline void cmovns (const Register& dst, const Register& src) { emitX86(INST_CMOVNS , &dst, &src); } - //! @brief Conditional Move. - inline void cmovns (const Register& dst, const Mem& src) { emitX86(INST_CMOVNS , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnz (const Register& dst, const Register& src) { emitX86(INST_CMOVNZ , &dst, &src); } - //! @brief Conditional Move. - inline void cmovnz (const Register& dst, const Mem& src) { emitX86(INST_CMOVNZ , &dst, &src); } - //! @brief Conditional Move. - inline void cmovo (const Register& dst, const Register& src) { emitX86(INST_CMOVO , &dst, &src); } - //! @brief Conditional Move. - inline void cmovo (const Register& dst, const Mem& src) { emitX86(INST_CMOVO , &dst, &src); } - //! @brief Conditional Move. - inline void cmovp (const Register& dst, const Register& src) { emitX86(INST_CMOVP , &dst, &src); } - //! @brief Conditional Move. - inline void cmovp (const Register& dst, const Mem& src) { emitX86(INST_CMOVP , &dst, &src); } - //! @brief Conditional Move. - inline void cmovpe (const Register& dst, const Register& src) { emitX86(INST_CMOVPE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovpe (const Register& dst, const Mem& src) { emitX86(INST_CMOVPE , &dst, &src); } - //! @brief Conditional Move. - inline void cmovpo (const Register& dst, const Register& src) { emitX86(INST_CMOVPO , &dst, &src); } - //! @brief Conditional Move. - inline void cmovpo (const Register& dst, const Mem& src) { emitX86(INST_CMOVPO , &dst, &src); } - //! @brief Conditional Move. - inline void cmovs (const Register& dst, const Register& src) { emitX86(INST_CMOVS , &dst, &src); } - //! @brief Conditional Move. - inline void cmovs (const Register& dst, const Mem& src) { emitX86(INST_CMOVS , &dst, &src); } - //! @brief Conditional Move. - inline void cmovz (const Register& dst, const Register& src) { emitX86(INST_CMOVZ , &dst, &src); } - //! @brief Conditional Move. - inline void cmovz (const Register& dst, const Mem& src) { emitX86(INST_CMOVZ , &dst, &src); } - - //! @brief Compare Two Operands. - inline void cmp(const Register& dst, const Register& src) - { - emitX86(INST_CMP, &dst, &src); - } - //! @brief Compare Two Operands. - inline void cmp(const Register& dst, const Mem& src) - { - emitX86(INST_CMP, &dst, &src); - } - //! @brief Compare Two Operands. - inline void cmp(const Register& dst, const Immediate& src) - { - emitX86(INST_CMP, &dst, &src); - } - //! @brief Compare Two Operands. - inline void cmp(const Mem& dst, const Register& src) - { - emitX86(INST_CMP, &dst, &src); - } - //! @brief Compare Two Operands. - inline void cmp(const Mem& dst, const Immediate& src) - { - emitX86(INST_CMP, &dst, &src); - } - - //! @brief Compare and Exchange (i486). - inline void cmpxchg(const Register& dst, const Register& src) - { - emitX86(INST_CMPXCHG, &dst, &src); - } - //! @brief Compare and Exchange (i486). - inline void cmpxchg(const Mem& dst, const Register& src) - { - emitX86(INST_CMPXCHG, &dst, &src); - } - - //! @brief Compares the 64-bit value in EDX:EAX with the memory operand (Pentium). - //! - //! If the values are equal, then this instruction stores the 64-bit value - //! in ECX:EBX into the memory operand and sets the zero flag. Otherwise, - //! this instruction copies the 64-bit memory operand into the EDX:EAX - //! registers and clears the zero flag. - inline void cmpxchg8b(const Mem& dst) - { - emitX86(INST_CMPXCHG8B, &dst); - } - -#if defined(ASMJIT_X64) - //! @brief Compares the 128-bit value in RDX:RAX with the memory operand. - //! - //! If the values are equal, then this instruction stores the 128-bit value - //! in RCX:RBX into the memory operand and sets the zero flag. Otherwise, - //! this instruction copies the 128-bit memory operand into the RDX:RAX - //! registers and clears the zero flag. - inline void cmpxchg16b(const Mem& dst) - { - emitX86(INST_CMPXCHG16B, &dst); - } -#endif // ASMJIT_X64 - - //! @brief CPU Identification (i486). - inline void cpuid() - { - emitX86(INST_CPUID); - } - -#if defined(ASMJIT_X86) - //! @brief Decimal adjust AL after addition - //! - //! This instruction adjusts the sum of two packed BCD values to create - //! a packed BCD result. - //! - //! @note This instruction is only available in 32 bit mode. - inline void daa() - { - emitX86(INST_DAA); - } -#endif // ASMJIT_X86 - -#if defined(ASMJIT_X86) - //! @brief Decimal adjust AL after subtraction - //! - //! This instruction adjusts the result of the subtraction of two packed - //! BCD values to create a packed BCD result. - //! - //! @note This instruction is only available in 32 bit mode. - inline void das() - { - emitX86(INST_DAS); - } -#endif // ASMJIT_X86 - - //! @brief Decrement by 1. - //! @note This instruction can be slower than sub(dst, 1) - inline void dec(const Register& dst) - { - emitX86(INST_DEC, &dst); - } - //! @brief Decrement by 1. - //! @note This instruction can be slower than sub(dst, 1) - inline void dec(const Mem& dst) - { - emitX86(INST_DEC, &dst); - } - - //! @brief Unsigned divide. - //! - //! This instruction divides (unsigned) the value in the AL, AX, or EAX - //! register by the source operand and stores the result in the AX, - //! DX:AX, or EDX:EAX registers. - inline void div(const Register& src) - { - emitX86(INST_DIV, &src); - } - //! @brief Unsigned divide. - //! @overload - inline void div(const Mem& src) - { - emitX86(INST_DIV, &src); - } - - //! @brief Make Stack Frame for Procedure Parameters. - inline void enter(const Immediate& imm16, const Immediate& imm8) - { - emitX86(INST_ENTER, &imm16, &imm8); - } - - //! @brief Signed divide. - //! - //! This instruction divides (signed) the value in the AL, AX, or EAX - //! register by the source operand and stores the result in the AX, - //! DX:AX, or EDX:EAX registers. - inline void idiv(const Register& src) - { - emitX86(INST_IDIV, &src); - } - //! @brief Signed divide. - //! @overload - inline void idiv(const Mem& src) - { - emitX86(INST_IDIV, &src); - } - - //! @brief Signed multiply. - //! - //! Source operand (in a general-purpose register or memory location) - //! is multiplied by the value in the AL, AX, or EAX register (depending - //! on the operand size) and the product is stored in the AX, DX:AX, or - //! EDX:EAX registers, respectively. - inline void imul(const Register& src) - { - emitX86(INST_IMUL, &src); - } - //! @overload - inline void imul(const Mem& src) - { - emitX86(INST_IMUL, &src); - } - - //! @brief Signed multiply. - //! - //! Destination operand (the first operand) is multiplied by the source - //! operand (second operand). The destination operand is a generalpurpose - //! register and the source operand is an immediate value, a general-purpose - //! register, or a memory location. The product is then stored in the - //! destination operand location. - inline void imul(const Register& dst, const Register& src) - { - emitX86(INST_IMUL, &dst, &src); - } - //! @brief Signed multiply. - //! @overload - inline void imul(const Register& dst, const Mem& src) - { - emitX86(INST_IMUL, &dst, &src); - } - //! @brief Signed multiply. - //! @overload - inline void imul(const Register& dst, const Immediate& src) - { - emitX86(INST_IMUL, &dst, &src); - } - - //! @brief Signed multiply. - //! - //! source operand (which can be a general-purpose register or a memory - //! location) is multiplied by the second source operand (an immediate - //! value). The product is then stored in the destination operand - //! (a general-purpose register). - inline void imul(const Register& dst, const Register& src, const Immediate& imm) - { - emitX86(INST_IMUL, &dst, &src, &imm); - } - //! @overload - inline void imul(const Register& dst, const Mem& src, const Immediate& imm) - { - emitX86(INST_IMUL, &dst, &src, &imm); - } - - //! @brief Increment by 1. - //! @note This instruction can be slower than add(dst, 1) - inline void inc(const Register& dst) - { - emitX86(INST_INC, &dst); - } - //! @brief Increment by 1. - //! @note This instruction can be slower than add(dst, 1) - inline void inc(const Mem& dst) - { - emitX86(INST_INC, &dst); - } - - //! @brief Interrupt 3 � trap to debugger. - inline void int3() - { - emitX86(INST_INT3); - } - - //! @brief Jump to label @a label if condition @a cc is met. - //! - //! This instruction checks the state of one or more of the status flags in - //! the EFLAGS register (CF, OF, PF, SF, and ZF) and, if the flags are in the - //! specified state (condition), performs a jump to the target instruction - //! specified by the destination operand. A condition code (cc) is associated - //! with each instruction to indicate the condition being tested for. If the - //! condition is not satisfied, the jump is not performed and execution - //! continues with the instruction following the Jcc instruction. - inline void j(CONDITION cc, Label* label, UInt32 hint = HINT_NONE) - { - _emitJcc(conditionToJCC(cc), label, hint); - } - - //! @brief Jump to label @a label if condition is met. - inline void ja (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JA , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jae (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JAE , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jb (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JB , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jbe (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JBE , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jc (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JC , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void je (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JE , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jg (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JG , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jge (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JGE , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jl (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JL , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jle (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JLE , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jna (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNA , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnae(Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNAE, label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnb (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNB , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnbe(Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNBE, label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnc (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNC , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jne (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNE , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jng (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNG , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnge(Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNGE, label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnl (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNL , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnle(Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNLE, label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jno (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNO , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnp (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNP , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jns (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNS , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnz (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNZ , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jo (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JO , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jp (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JP , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jpe (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JPE , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jpo (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JPO , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void js (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JS , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jz (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JZ , label, hint); } - - //! @brief Jump to label @a label if condition @a cc is met. - //! - //! This instruction checks the state of one or more of the status flags in - //! the EFLAGS register (CF, OF, PF, SF, and ZF) and, if the flags are in the - //! specified state (condition), performs a jump to the target instruction - //! specified by the destination operand. A condition code (cc) is associated - //! with each instruction to indicate the condition being tested for. If the - //! condition is not satisfied, the jump is not performed and execution - //! continues with the instruction following the Jcc instruction. - inline void j_short(CONDITION cc, Label* label, UInt32 hint = HINT_NONE) - { - // Adjust returned condition to jxx_short version. - _emitJcc(conditionToJCC(cc) + (INST_J_SHORT - INST_J), label, hint); - } - - //! @brief Jump to label @a label if condition is met. - inline void ja_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JA_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jae_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JAE_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jb_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JB_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jbe_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JBE_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jc_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JC_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void je_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JE_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jg_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JG_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jge_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JGE_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jl_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JL_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jle_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JLE_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jna_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNA_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnae_short(Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNAE_SHORT, label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnb_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNB_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnbe_short(Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNBE_SHORT, label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnc_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNC_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jne_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNE_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jng_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNG_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnge_short(Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNGE_SHORT, label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnl_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNL_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnle_short(Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNLE_SHORT, label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jno_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNO_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnp_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNP_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jns_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNS_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jnz_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JNZ_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jo_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JO_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jp_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JP_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jpe_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JPE_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jpo_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JPO_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void js_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JS_SHORT , label, hint); } - //! @brief Jump to label @a label if condition is met. - inline void jz_short (Label* label, UInt32 hint = HINT_NONE) { _emitJcc(INST_JZ_SHORT , label, hint); } - - //! @brief Jump. - //! @overload - inline void jmp(const Register& dst) - { - emitX86(INST_JMP, &dst); - } - //! @brief Jump. - //! @overload - inline void jmp(const Mem& dst) - { - emitX86(INST_JMP, &dst); - } - //! @brief Jump. - //! @overload - inline void jmp(const Immediate& dst) - { - emitX86(INST_JMP, &dst); - } - - //! @brief Jump. - //! @overload - inline void jmp(void* dst) - { - Immediate imm((SysInt)dst); - emitX86(INST_JMP, &imm); - } - - //! @brief Jump. - //! - //! This instruction transfers program control to a different point - //! in the instruction stream without recording return information. - //! The destination (target) operand specifies the label of the - //! instruction being jumped to. - inline void jmp(Label* label) - { - emitX86(INST_JMP, label); - } - //! @brief Jump, see @c jmp(). - inline void jmp_short(Label* label) - { - emitX86(INST_JMP_SHORT, label); - } - - //! @brief Load Effective Address - //! - //! This instruction computes the effective address of the second - //! operand (the source operand) and stores it in the first operand - //! (destination operand). The source operand is a memory address - //! (offset part) specified with one of the processors addressing modes. - //! The destination operand is a general-purpose register. - inline void lea(const Register& dst, const Mem& src) - { - emitX86(INST_LEA, &dst, &src); - } - - //! @brief High Level Procedure Exit. - inline void leave() - { - emitX86(INST_LEAVE); - } - - //! @brief Assert LOCK# Signal Prefix. - //! - //! This instruction causes the processor�s LOCK# signal to be asserted - //! during execution of the accompanying instruction (turns the - //! instruction into an atomic instruction). In a multiprocessor environment, - //! the LOCK# signal insures that the processor has exclusive use of any shared - //! memory while the signal is asserted. - //! - //! The LOCK prefix can be prepended only to the following instructions and - //! to those forms of the instructions that use a memory operand: ADD, ADC, - //! AND, BTC, BTR, BTS, CMPXCHG, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, - //! and XCHG. An undefined opcode exception will be generated if the LOCK - //! prefix is used with any other instruction. The XCHG instruction always - //! asserts the LOCK# signal regardless of the presence or absence of the LOCK - //! prefix. - inline void lock() - { - emitX86(INST_LOCK); - } - - //! @brief Move. - //! - //! This instruction copies the second operand (source operand) to the first - //! operand (destination operand). The source operand can be an immediate - //! value, general-purpose register, segment register, or memory location. - //! The destination register can be a general-purpose register, segment - //! register, or memory location. Both operands must be the same size, which - //! can be a byte, a word, or a DWORD. - //! - //! @note To move MMX or SSE registers to/from GP registers or memory, use - //! corresponding functions: @c movd(), @c movq(), etc. Passing MMX or SSE - //! registers to @c mov() is illegal. - inline void mov(const Register& dst, const Register& src) - { - emitX86(INST_MOV, &dst, &src); - } - //! @brief Move. - //! @overload - inline void mov(const Register& dst, const Mem& src) - { - emitX86(INST_MOV, &dst, &src); - } - //! @brief Move. - //! @overload - inline void mov(const Register& dst, const Immediate& src) - { - emitX86(INST_MOV, &dst, &src); - } - //! @brief Move. - //! @overload - inline void mov(const Mem& dst, const Register& src) - { - emitX86(INST_MOV, &dst, &src); - } - //! @brief Move. - //! @overload - inline void mov(const Mem& dst, const Immediate& src) - { - emitX86(INST_MOV, &dst, &src); - } - - //! @brief Move byte, word, dword or qword from absolute address @a src to - //! AL, AX, EAX or RAX register. - inline void mov_ptr(const Register& dst, void* src) - { - ASMJIT_ASSERT(dst.index() == 0); - Immediate imm((SysInt)src); - emitX86(INST_MOV_PTR, &dst, &imm); - } - - //! @brief Move byte, word, dword or qword from AL, AX, EAX or RAX register - //! to absolute address @a dst. - inline void mov_ptr(void* dst, const Register& src) - { - ASMJIT_ASSERT(src.index() == 0); - Immediate imm((SysInt)dst); - emitX86(INST_MOV_PTR, &imm, &src); - } - - //! @brief Move with Sign-Extension. - //! - //! This instruction copies the contents of the source operand (register - //! or memory location) to the destination operand (register) and sign - //! extends the value to 16, 32 or 64 bits. - //! - //! @sa movsxd(). - void movsx(const Register& dst, const Register& src) - { - emitX86(INST_MOVSX, &dst, &src); - } - //! @brief Move with Sign-Extension. - //! @overload - void movsx(const Register& dst, const Mem& src) - { - emitX86(INST_MOVSX, &dst, &src); - } - -#if defined(ASMJIT_X64) - //! @brief Move DWord to QWord with sign-extension. - inline void movsxd(const Register& dst, const Register& src) - { - emitX86(INST_MOVSXD, &dst, &src); - } - //! @brief Move DWord to QWord with sign-extension. - //! @overload - inline void movsxd(const Register& dst, const Mem& src) - { - emitX86(INST_MOVSXD, &dst, &src); - } -#endif // ASMJIT_X64 - - //! @brief Move with Zero-Extend. - //! - //! This instruction copies the contents of the source operand (register - //! or memory location) to the destination operand (register) and zero - //! extends the value to 16 or 32 bits. The size of the converted value - //! depends on the operand-size attribute. - inline void movzx(const Register& dst, const Register& src) - { - emitX86(INST_MOVZX, &dst, &src); - } - //! @brief Move with Zero-Extend. - //! @brief Overload - inline void movzx(const Register& dst, const Mem& src) - { - emitX86(INST_MOVZX, &dst, &src); - } - - //! @brief Unsigned multiply. - //! - //! Source operand (in a general-purpose register or memory location) - //! is multiplied by the value in the AL, AX, or EAX register (depending - //! on the operand size) and the product is stored in the AX, DX:AX, or - //! EDX:EAX registers, respectively. - inline void mul(const Register& src) - { - emitX86(INST_MUL, &src); - } - //! @brief Unsigned multiply. - //! @overload - inline void mul(const Mem& src) - { - emitX86(INST_MUL, &src); - } - - //! @brief Two's Complement Negation. - inline void neg(const Register& dst) - { - emitX86(INST_NEG, &dst); - } - //! @brief Two's Complement Negation. - inline void neg(const Mem& dst) - { - emitX86(INST_NEG, &dst); - } - - //! @brief No Operation. - //! - //! This instruction performs no operation. This instruction is a one-byte - //! instruction that takes up space in the instruction stream but does not - //! affect the machine context, except the EIP register. The NOP instruction - //! is an alias mnemonic for the XCHG (E)AX, (E)AX instruction. - inline void nop() - { - emitX86(INST_NOP); - } - - //! @brief One's Complement Negation. - inline void not_(const Register& dst) - { - emitX86(INST_NOT, &dst); - } - //! @brief One's Complement Negation. - inline void not_(const Mem& dst) - { - emitX86(INST_NOT, &dst); - } - - //! @brief Logical Inclusive OR. - inline void or_(const Register& dst, const Register& src) - { - emitX86(INST_OR, &dst, &src); - } - //! @brief Logical Inclusive OR. - inline void or_(const Register& dst, const Mem& src) - { - emitX86(INST_OR, &dst, &src); - } - //! @brief Logical Inclusive OR. - inline void or_(const Register& dst, const Immediate& src) - { - emitX86(INST_OR, &dst, &src); - } - //! @brief Logical Inclusive OR. - inline void or_(const Mem& dst, const Register& src) - { - emitX86(INST_OR, &dst, &src); - } - //! @brief Logical Inclusive OR. - inline void or_(const Mem& dst, const Immediate& src) - { - emitX86(INST_OR, &dst, &src); - } - - //! @brief Pop a Value from the Stack. - //! - //! This instruction loads the value from the top of the stack to the location - //! specified with the destination operand and then increments the stack pointer. - //! The destination operand can be a general purpose register, memory location, - //! or segment register. - inline void pop(const Register& dst) - { - ASMJIT_ASSERT(dst.isRegType(REG_GPW) || dst.isRegType(REG_GPN)); - emitX86(INST_POP, &dst); - } - - inline void pop(const Mem& dst) - { - ASMJIT_ASSERT(dst.size() == 2 || dst.size() == sizeof(SysInt)); - emitX86(INST_POP, &dst); - } - -#if defined(ASMJIT_X86) - //! @brief Pop All General-Purpose Registers. - //! - //! Pop EDI, ESI, EBP, EBX, EDX, ECX, and EAX. - inline void popad() - { - emitX86(INST_POPAD); - } -#endif // ASMJIT_X86 - - //! @brief Pop Stack into EFLAGS Register (32 bit or 64 bit). - inline void popf() - { -#if defined(ASMJIT_X86) - popfd(); -#else - popfq(); -#endif - } - -#if defined(ASMJIT_X86) - //! @brief Pop Stack into EFLAGS Register (32 bit). - inline void popfd() { emitX86(INST_POPFD); } -#else - //! @brief Pop Stack into EFLAGS Register (64 bit). - inline void popfq() { emitX86(INST_POPFQ); } -#endif - - //! @brief Push WORD/DWORD/QWORD Onto the Stack. - //! - //! @note 32 bit architecture pushed DWORD while 64 bit - //! pushes QWORD. 64 bit mode not provides instruction to - //! push 32 bit register/memory. - inline void push(const Register& src) - { - ASMJIT_ASSERT(src.isRegType(REG_GPW) || src.isRegType(REG_GPN)); - emitX86(INST_PUSH, &src); - } - //! @brief Push WORD/DWORD/QWORD Onto the Stack. - inline void push(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == sizeof(SysInt)); - emitX86(INST_PUSH, &src); - } - //! @brief Push WORD/DWORD/QWORD Onto the Stack. - inline void push(const Immediate& src) - { - emitX86(INST_PUSH, &src); - } - -#if defined(ASMJIT_X86) - //! @brief Push All General-Purpose Registers. - //! - //! Push EAX, ECX, EDX, EBX, original ESP, EBP, ESI, and EDI. - inline void pushad() - { - emitX86(INST_PUSHAD); - } -#endif // ASMJIT_X86 - - //! @brief Push EFLAGS Register (32 bit or 64 bit) onto the Stack. - inline void pushf() - { -#if defined(ASMJIT_X86) - pushfd(); -#else - pushfq(); -#endif - } - -#if defined(ASMJIT_X86) - //! @brief Push EFLAGS Register (32 bit) onto the Stack. - inline void pushfd() { emitX86(INST_PUSHFD); } -#else - //! @brief Push EFLAGS Register (64 bit) onto the Stack. - inline void pushfq() { emitX86(INST_PUSHFQ); } -#endif // ASMJIT_X86 - - //! @brief Rotate Bits Left. - //! @note @a src register can be only @c cl. - inline void rcl(const Register& dst, const Register& src) - { - emitX86(INST_RCL, &dst, &src); - } - //! @brief Rotate Bits Left. - inline void rcl(const Register& dst, const Immediate& src) - { - emitX86(INST_RCL, &dst, &src); - } - //! @brief Rotate Bits Left. - //! @note @a src register can be only @c cl. - inline void rcl(const Mem& dst, const Register& src) - { - emitX86(INST_RCL, &dst, &src); - } - //! @brief Rotate Bits Left. - inline void rcl(const Mem& dst, const Immediate& src) - { - emitX86(INST_RCL, &dst, &src); - } - - //! @brief Rotate Bits Right. - //! @note @a src register can be only @c cl. - inline void rcr(const Register& dst, const Register& src) - { - emitX86(INST_RCR, &dst, &src); - } - //! @brief Rotate Bits Right. - inline void rcr(const Register& dst, const Immediate& src) - { - emitX86(INST_RCR, &dst, &src); - } - //! @brief Rotate Bits Right. - //! @note @a src register can be only @c cl. - inline void rcr(const Mem& dst, const Register& src) - { - emitX86(INST_RCR, &dst, &src); - } - //! @brief Rotate Bits Right. - inline void rcr(const Mem& dst, const Immediate& src) - { - emitX86(INST_RCR, &dst, &src); - } - - //! @brief Read Time-Stamp Counter (Pentium). - inline void rdtsc() - { - emitX86(INST_RDTSC); - } - - //! @brief Read Time-Stamp Counter and Processor ID (New). - inline void rdtscp() - { - emitX86(INST_RDTSCP); - } - - //! @brief Return from Procedure. - inline void ret() - { - emitX86(INST_RET); - } - - //! @brief Return from Procedure. - inline void ret(const Immediate& imm16) - { - emitX86(INST_RET, &imm16); - } - - //! @brief Rotate Bits Left. - //! @note @a src register can be only @c cl. - inline void rol(const Register& dst, const Register& src) - { - emitX86(INST_ROL, &dst, &src); - } - //! @brief Rotate Bits Left. - inline void rol(const Register& dst, const Immediate& src) - { - emitX86(INST_ROL, &dst, &src); - } - //! @brief Rotate Bits Left. - //! @note @a src register can be only @c cl. - inline void rol(const Mem& dst, const Register& src) - { - emitX86(INST_ROL, &dst, &src); - } - //! @brief Rotate Bits Left. - inline void rol(const Mem& dst, const Immediate& src) - { - emitX86(INST_ROL, &dst, &src); - } - - //! @brief Rotate Bits Right. - //! @note @a src register can be only @c cl. - inline void ror(const Register& dst, const Register& src) - { - emitX86(INST_ROR, &dst, &src); - } - //! @brief Rotate Bits Right. - inline void ror(const Register& dst, const Immediate& src) - { - emitX86(INST_ROR, &dst, &src); - } - //! @brief Rotate Bits Right. - //! @note @a src register can be only @c cl. - inline void ror(const Mem& dst, const Register& src) - { - emitX86(INST_ROR, &dst, &src); - } - //! @brief Rotate Bits Right. - inline void ror(const Mem& dst, const Immediate& src) - { - emitX86(INST_ROR, &dst, &src); - } - -#if defined(ASMJIT_X86) - //! @brief Store AH into Flags. - inline void sahf() - { - emitX86(INST_SAHF); - } -#endif // ASMJIT_X86 - - //! @brief Integer subtraction with borrow. - inline void sbb(const Register& dst, const Register& src) - { - emitX86(INST_SBB, &dst, &src); - } - //! @brief Integer subtraction with borrow. - inline void sbb(const Register& dst, const Mem& src) - { - emitX86(INST_SBB, &dst, &src); - } - //! @brief Integer subtraction with borrow. - inline void sbb(const Register& dst, const Immediate& src) - { - emitX86(INST_SBB, &dst, &src); - } - //! @brief Integer subtraction with borrow. - inline void sbb(const Mem& dst, const Register& src) - { - emitX86(INST_SBB, &dst, &src); - } - //! @brief Integer subtraction with borrow. - inline void sbb(const Mem& dst, const Immediate& src) - { - emitX86(INST_SBB, &dst, &src); - } - - //! @brief Shift Bits Left. - //! @note @a src register can be only @c cl. - inline void sal(const Register& dst, const Register& src) - { - emitX86(INST_SAL, &dst, &src); - } - //! @brief Shift Bits Left. - inline void sal(const Register& dst, const Immediate& src) - { - emitX86(INST_SAL, &dst, &src); - } - //! @brief Shift Bits Left. - //! @note @a src register can be only @c cl. - inline void sal(const Mem& dst, const Register& src) - { - emitX86(INST_SAL, &dst, &src); - } - //! @brief Shift Bits Left. - inline void sal(const Mem& dst, const Immediate& src) - { - emitX86(INST_SAL, &dst, &src); - } - - //! @brief Shift Bits Right. - //! @note @a src register can be only @c cl. - inline void sar(const Register& dst, const Register& src) - { - emitX86(INST_SAR, &dst, &src); - } - //! @brief Shift Bits Right. - inline void sar(const Register& dst, const Immediate& src) - { - emitX86(INST_SAR, &dst, &src); - } - //! @brief Shift Bits Right. - //! @note @a src register can be only @c cl. - inline void sar(const Mem& dst, const Register& src) - { - emitX86(INST_SAR, &dst, &src); - } - //! @brief Shift Bits Right. - inline void sar(const Mem& dst, const Immediate& src) - { - emitX86(INST_SAR, &dst, &src); - } - - //! @brief Set Byte on Condition. - inline void set(CONDITION cc, const Register& dst) - { - emitX86(conditionToSetCC(cc), &dst); - } - - //! @brief Set Byte on Condition. - inline void set(CONDITION cc, const Mem& dst) - { - emitX86(conditionToSetCC(cc), &dst); - } - - //! @brief Set Byte on Condition. - inline void seta (const Register& dst) { emitX86(INST_SETA , &dst); } - //! @brief Set Byte on Condition. - inline void seta (const Mem& dst) { emitX86(INST_SETA , &dst); } - //! @brief Set Byte on Condition. - inline void setae (const Register& dst) { emitX86(INST_SETAE , &dst); } - //! @brief Set Byte on Condition. - inline void setae (const Mem& dst) { emitX86(INST_SETAE , &dst); } - //! @brief Set Byte on Condition. - inline void setb (const Register& dst) { emitX86(INST_SETB , &dst); } - //! @brief Set Byte on Condition. - inline void setb (const Mem& dst) { emitX86(INST_SETB , &dst); } - //! @brief Set Byte on Condition. - inline void setbe (const Register& dst) { emitX86(INST_SETBE , &dst); } - //! @brief Set Byte on Condition. - inline void setbe (const Mem& dst) { emitX86(INST_SETBE , &dst); } - //! @brief Set Byte on Condition. - inline void setc (const Register& dst) { emitX86(INST_SETC , &dst); } - //! @brief Set Byte on Condition. - inline void setc (const Mem& dst) { emitX86(INST_SETC , &dst); } - //! @brief Set Byte on Condition. - inline void sete (const Register& dst) { emitX86(INST_SETE , &dst); } - //! @brief Set Byte on Condition. - inline void sete (const Mem& dst) { emitX86(INST_SETE , &dst); } - //! @brief Set Byte on Condition. - inline void setg (const Register& dst) { emitX86(INST_SETG , &dst); } - //! @brief Set Byte on Condition. - inline void setg (const Mem& dst) { emitX86(INST_SETG , &dst); } - //! @brief Set Byte on Condition. - inline void setge (const Register& dst) { emitX86(INST_SETGE , &dst); } - //! @brief Set Byte on Condition. - inline void setge (const Mem& dst) { emitX86(INST_SETGE , &dst); } - //! @brief Set Byte on Condition. - inline void setl (const Register& dst) { emitX86(INST_SETL , &dst); } - //! @brief Set Byte on Condition. - inline void setl (const Mem& dst) { emitX86(INST_SETL , &dst); } - //! @brief Set Byte on Condition. - inline void setle (const Register& dst) { emitX86(INST_SETLE , &dst); } - //! @brief Set Byte on Condition. - inline void setle (const Mem& dst) { emitX86(INST_SETLE , &dst); } - //! @brief Set Byte on Condition. - inline void setna (const Register& dst) { emitX86(INST_SETNA , &dst); } - //! @brief Set Byte on Condition. - inline void setna (const Mem& dst) { emitX86(INST_SETNA , &dst); } - //! @brief Set Byte on Condition. - inline void setnae(const Register& dst) { emitX86(INST_SETNAE, &dst); } - //! @brief Set Byte on Condition. - inline void setnae(const Mem& dst) { emitX86(INST_SETNAE, &dst); } - //! @brief Set Byte on Condition. - inline void setnb (const Register& dst) { emitX86(INST_SETNB , &dst); } - //! @brief Set Byte on Condition. - inline void setnb (const Mem& dst) { emitX86(INST_SETNB , &dst); } - //! @brief Set Byte on Condition. - inline void setnbe(const Register& dst) { emitX86(INST_SETNBE, &dst); } - //! @brief Set Byte on Condition. - inline void setnbe(const Mem& dst) { emitX86(INST_SETNBE, &dst); } - //! @brief Set Byte on Condition. - inline void setnc (const Register& dst) { emitX86(INST_SETNC , &dst); } - //! @brief Set Byte on Condition. - inline void setnc (const Mem& dst) { emitX86(INST_SETNC , &dst); } - //! @brief Set Byte on Condition. - inline void setne (const Register& dst) { emitX86(INST_SETNE , &dst); } - //! @brief Set Byte on Condition. - inline void setne (const Mem& dst) { emitX86(INST_SETNE , &dst); } - //! @brief Set Byte on Condition. - inline void setng (const Register& dst) { emitX86(INST_SETNG , &dst); } - //! @brief Set Byte on Condition. - inline void setng (const Mem& dst) { emitX86(INST_SETNG , &dst); } - //! @brief Set Byte on Condition. - inline void setnge(const Register& dst) { emitX86(INST_SETNGE, &dst); } - //! @brief Set Byte on Condition. - inline void setnge(const Mem& dst) { emitX86(INST_SETNGE, &dst); } - //! @brief Set Byte on Condition. - inline void setnl (const Register& dst) { emitX86(INST_SETNL , &dst); } - //! @brief Set Byte on Condition. - inline void setnl (const Mem& dst) { emitX86(INST_SETNL , &dst); } - //! @brief Set Byte on Condition. - inline void setnle(const Register& dst) { emitX86(INST_SETNLE, &dst); } - //! @brief Set Byte on Condition. - inline void setnle(const Mem& dst) { emitX86(INST_SETNLE, &dst); } - //! @brief Set Byte on Condition. - inline void setno (const Register& dst) { emitX86(INST_SETNO , &dst); } - //! @brief Set Byte on Condition. - inline void setno (const Mem& dst) { emitX86(INST_SETNO , &dst); } - //! @brief Set Byte on Condition. - inline void setnp (const Register& dst) { emitX86(INST_SETNP , &dst); } - //! @brief Set Byte on Condition. - inline void setnp (const Mem& dst) { emitX86(INST_SETNP , &dst); } - //! @brief Set Byte on Condition. - inline void setns (const Register& dst) { emitX86(INST_SETNS , &dst); } - //! @brief Set Byte on Condition. - inline void setns (const Mem& dst) { emitX86(INST_SETNS , &dst); } - //! @brief Set Byte on Condition. - inline void setnz (const Register& dst) { emitX86(INST_SETNZ , &dst); } - //! @brief Set Byte on Condition. - inline void setnz (const Mem& dst) { emitX86(INST_SETNZ , &dst); } - //! @brief Set Byte on Condition. - inline void seto (const Register& dst) { emitX86(INST_SETO , &dst); } - //! @brief Set Byte on Condition. - inline void seto (const Mem& dst) { emitX86(INST_SETO , &dst); } - //! @brief Set Byte on Condition. - inline void setp (const Register& dst) { emitX86(INST_SETP , &dst); } - //! @brief Set Byte on Condition. - inline void setp (const Mem& dst) { emitX86(INST_SETP , &dst); } - //! @brief Set Byte on Condition. - inline void setpe (const Register& dst) { emitX86(INST_SETPE , &dst); } - //! @brief Set Byte on Condition. - inline void setpe (const Mem& dst) { emitX86(INST_SETPE , &dst); } - //! @brief Set Byte on Condition. - inline void setpo (const Register& dst) { emitX86(INST_SETPO , &dst); } - //! @brief Set Byte on Condition. - inline void setpo (const Mem& dst) { emitX86(INST_SETPO , &dst); } - //! @brief Set Byte on Condition. - inline void sets (const Register& dst) { emitX86(INST_SETS , &dst); } - //! @brief Set Byte on Condition. - inline void sets (const Mem& dst) { emitX86(INST_SETS , &dst); } - //! @brief Set Byte on Condition. - inline void setz (const Register& dst) { emitX86(INST_SETZ , &dst); } - //! @brief Set Byte on Condition. - inline void setz (const Mem& dst) { emitX86(INST_SETZ , &dst); } - - //! @brief Shift Bits Left. - //! @note @a src register can be only @c cl. - inline void shl(const Register& dst, const Register& src) - { - emitX86(INST_SHL, &dst, &src); - } - //! @brief Shift Bits Left. - inline void shl(const Register& dst, const Immediate& src) - { - emitX86(INST_SHL, &dst, &src); - } - //! @brief Shift Bits Left. - //! @note @a src register can be only @c cl. - inline void shl(const Mem& dst, const Register& src) - { - emitX86(INST_SHL, &dst, &src); - } - //! @brief Shift Bits Left. - inline void shl(const Mem& dst, const Immediate& src) - { - emitX86(INST_SHL, &dst, &src); - } - - //! @brief Shift Bits Right. - //! @note @a src register can be only @c cl. - inline void shr(const Register& dst, const Register& src) - { - emitX86(INST_SHR, &dst, &src); - } - //! @brief Shift Bits Right. - inline void shr(const Register& dst, const Immediate& src) - { - emitX86(INST_SHR, &dst, &src); - } - //! @brief Shift Bits Right. - //! @note @a src register can be only @c cl. - inline void shr(const Mem& dst, const Register& src) - { - emitX86(INST_SHR, &dst, &src); - } - //! @brief Shift Bits Right. - inline void shr(const Mem& dst, const Immediate& src) - { - emitX86(INST_SHR, &dst, &src); - } - - //! @brief Double Precision Shift Left. - //! @note src2 register can be only @c cl register. - inline void shld(const Register& dst, const Register& src1, const Register& src2) - { - emitX86(INST_SHLD, &dst, &src1, &src2); - } - //! @brief Double Precision Shift Left. - inline void shld(const Register& dst, const Register& src1, const Immediate& src2) - { - emitX86(INST_SHLD, &dst, &src1, &src2); - } - //! @brief Double Precision Shift Left. - //! @note src2 register can be only @c cl register. - inline void shld(const Mem& dst, const Register& src1, const Register& src2) - { - emitX86(INST_SHLD, &dst, &src1, &src2); - } - //! @brief Double Precision Shift Left. - inline void shld(const Mem& dst, const Register& src1, const Immediate& src2) - { - emitX86(INST_SHLD, &dst, &src1, &src2); - } - - //! @brief Double Precision Shift Right. - //! @note src2 register can be only @c cl register. - inline void shrd(const Register& dst, const Register& src1, const Register& src2) - { - emitX86(INST_SHRD, &dst, &src1, &src2); - } - //! @brief Double Precision Shift Right. - inline void shrd(const Register& dst, const Register& src1, const Immediate& src2) - { - emitX86(INST_SHRD, &dst, &src1, &src2); - } - //! @brief Double Precision Shift Right. - //! @note src2 register can be only @c cl register. - inline void shrd(const Mem& dst, const Register& src1, const Register& src2) - { - emitX86(INST_SHRD, &dst, &src1, &src2); - } - //! @brief Double Precision Shift Right. - inline void shrd(const Mem& dst, const Register& src1, const Immediate& src2) - { - emitX86(INST_SHRD, &dst, &src1, &src2); - } - - //! @brief Set Carry Flag to 1. - inline void stc() - { - emitX86(INST_STC); - } - - //! @brief Set Direction Flag to 1. - inline void std() - { - emitX86(INST_STD); - } - - //! @brief Subtract. - inline void sub(const Register& dst, const Register& src) - { - emitX86(INST_SUB, &dst, &src); - } - //! @brief Subtract. - inline void sub(const Register& dst, const Mem& src) - { - emitX86(INST_SUB, &dst, &src); - } - //! @brief Subtract. - inline void sub(const Register& dst, const Immediate& src) - { - emitX86(INST_SUB, &dst, &src); - } - //! @brief Subtract. - inline void sub(const Mem& dst, const Register& src) - { - emitX86(INST_SUB, &dst, &src); - } - //! @brief Subtract. - inline void sub(const Mem& dst, const Immediate& src) - { - emitX86(INST_SUB, &dst, &src); - } - - //! @brief Logical Compare. - inline void test(const Register& op1, const Register& op2) - { - emitX86(INST_TEST, &op1, &op2); - } - //! @brief Logical Compare. - inline void test(const Register& op1, const Immediate& op2) - { - emitX86(INST_TEST, &op1, &op2); - } - //! @brief Logical Compare. - inline void test(const Mem& op1, const Register& op2) - { - emitX86(INST_TEST, &op1, &op2); - } - //! @brief Logical Compare. - inline void test(const Mem& op1, const Immediate& op2) - { - emitX86(INST_TEST, &op1, &op2); - } - - //! @brief Undefined instruction - Raise invalid opcode exception. - inline void ud2() - { - emitX86(INST_UD2); - } - - //! @brief Exchange and Add. - inline void xadd(const Register& dst, const Register& src) - { - emitX86(INST_XADD, &dst, &src); - } - //! @brief Exchange and Add. - inline void xadd(const Mem& dst, const Register& src) - { - emitX86(INST_XADD, &dst, &src); - } - - //! @brief Exchange Register/Memory with Register. - inline void xchg(const Register& dst, const Register& src) - { - emitX86(INST_XCHG, &dst, &src); - } - //! @brief Exchange Register/Memory with Register. - inline void xchg(const Mem& dst, const Register& src) - { - emitX86(INST_XCHG, &dst, &src); - } - //! @brief Exchange Register/Memory with Register. - inline void xchg(const Register& dst, const Mem& src) - { - emitX86(INST_XCHG, &src, &dst); - } - - //! @brief Exchange Register/Memory with Register. - inline void xor_(const Register& dst, const Register& src) - { - emitX86(INST_XOR, &dst, &src); - } - //! @brief Exchange Register/Memory with Register. - inline void xor_(const Register& dst, const Mem& src) - { - emitX86(INST_XOR, &dst, &src); - } - //! @brief Exchange Register/Memory with Register. - inline void xor_(const Register& dst, const Immediate& src) - { - emitX86(INST_XOR, &dst, &src); - } - //! @brief Exchange Register/Memory with Register. - inline void xor_(const Mem& dst, const Register& src) - { - emitX86(INST_XOR, &dst, &src); - } - //! @brief Exchange Register/Memory with Register. - inline void xor_(const Mem& dst, const Immediate& src) - { - emitX86(INST_XOR, &dst, &src); - } - - // ------------------------------------------------------------------------- - // [X87 Instructions (FPU)] - // ------------------------------------------------------------------------- - - //! @brief Compute 2^x - 1 (FPU). - inline void f2xm1() - { - emitX86(INST_F2XM1); - } - - //! @brief Absolute Value of st(0) (FPU). - inline void fabs() - { - emitX86(INST_FABS); - } - - //! @brief Add @a src to @a dst and store result in @a dst (FPU). - //! - //! @note One of dst or src must be st(0). - inline void fadd(const X87Register& dst, const X87Register& src) - { - ASMJIT_ASSERT(dst.index() == 0 || src.index() == 0); - emitX86(INST_FADD, &dst, &src); - } - - //! @brief Add @a src to st(0) and store result in st(0) (FPU). - //! - //! @note SP-FP or DP-FP determined by @a adr size. - inline void fadd(const Mem& src) - { - emitX86(INST_FADD, &src); - } - - //! @brief Add st(0) to @a dst and POP register stack (FPU). - inline void faddp(const X87Register& dst = st(1)) - { - emitX86(INST_FADDP, &dst); - } - - //! @brief Load Binary Coded Decimal (FPU). - inline void fbld(const Mem& src) - { - emitX86(INST_FBLD, &src); - } - - //! @brief Store BCD Integer and Pop (FPU). - inline void fbstp(const Mem& dst) - { - emitX86(INST_FBSTP, &dst); - } - - //! @brief Change st(0) Sign (FPU). - inline void fchs() - { - emitX86(INST_FCHS); - } - - //! @brief Clear Exceptions (FPU). - //! - //! Clear floating-point exception flags after checking for pending unmasked - //! floatingpoint exceptions. - //! - //! Clears the floating-point exception flags (PE, UE, OE, ZE, DE, and IE), - //! the exception summary status flag (ES), the stack fault flag (SF), and - //! the busy flag (B) in the FPU status word. The FCLEX instruction checks - //! for and handles any pending unmasked floating-point exceptions before - //! clearing the exception flags. - inline void fclex() - { - emitX86(INST_FCLEX); - } - - //! @brief FP Conditional Move (FPU). - inline void fcmovb(const X87Register& src) - { - emitX86(INST_FCMOVB, &src); - } - //! @brief FP Conditional Move (FPU). - inline void fcmovbe(const X87Register& src) - { - emitX86(INST_FCMOVBE, &src); - } - //! @brief FP Conditional Move (FPU). - inline void fcmove(const X87Register& src) - { - emitX86(INST_FCMOVE, &src); - } - //! @brief FP Conditional Move (FPU). - inline void fcmovnb(const X87Register& src) - { - emitX86(INST_FCMOVNB, &src); - } - //! @brief FP Conditional Move (FPU). - inline void fcmovnbe(const X87Register& src) - { - emitX86(INST_FCMOVNBE, &src); - } - //! @brief FP Conditional Move (FPU). - inline void fcmovne(const X87Register& src) - { - emitX86(INST_FCMOVNE, &src); - } - //! @brief FP Conditional Move (FPU). - inline void fcmovnu(const X87Register& src) - { - emitX86(INST_FCMOVNU, &src); - } - //! @brief FP Conditional Move (FPU). - inline void fcmovu(const X87Register& src) - { - emitX86(INST_FCMOVU, &src); - } - - //! @brief Compare st(0) with @a reg (FPU). - inline void fcom(const X87Register& reg = st(1)) - { - emitX86(INST_FCOM, ®); - } - //! @brief Compare st(0) with 4 byte or 8 byte FP at @a src (FPU). - inline void fcom(const Mem& src) - { - emitX86(INST_FCOM, &src); - } - - //! @brief Compare st(0) with @a reg and pop the stack (FPU). - inline void fcomp(const X87Register& reg = st(1)) - { - emitX86(INST_FCOMP, ®); - } - //! @brief Compare st(0) with 4 byte or 8 byte FP at @a adr and pop the - //! stack (FPU). - inline void fcomp(const Mem& mem) - { - emitX86(INST_FCOMP, &mem); - } - - //! @brief Compare st(0) with st(1) and pop register stack twice (FPU). - inline void fcompp() - { - emitX86(INST_FCOMPP); - } - - //! @brief Compare st(0) and @a reg and Set EFLAGS (FPU). - inline void fcomi(const X87Register& reg) - { - emitX86(INST_FCOMI, ®); - } - - //! @brief Compare st(0) and @a reg and Set EFLAGS and pop the stack (FPU). - inline void fcomip(const X87Register& reg) - { - emitX86(INST_FCOMIP, ®); - } - - //! @brief Cosine (FPU). - //! - //! This instruction calculates the cosine of the source operand in - //! register st(0) and stores the result in st(0). - inline void fcos() - { - emitX86(INST_FCOS); - } - - //! @brief Decrement Stack-Top Pointer (FPU). - //! - //! Subtracts one from the TOP field of the FPU status word (decrements - //! the top-ofstack pointer). If the TOP field contains a 0, it is set - //! to 7. The effect of this instruction is to rotate the stack by one - //! position. The contents of the FPU data registers and tag register - //! are not affected. - inline void fdecstp() - { - emitX86(INST_FDECSTP); - } - - //! @brief Divide @a dst by @a src (FPU). - //! - //! @note One of @a dst or @a src register must be st(0). - inline void fdiv(const X87Register& dst, const X87Register& src) - { - ASMJIT_ASSERT(dst.index() == 0 || src.index() == 0); - emitX86(INST_FDIV, &dst, &src); - } - //! @brief Divide st(0) by 32 bit or 64 bit FP value (FPU). - inline void fdiv(const Mem& src) - { - emitX86(INST_FDIV, &src); - } - - //! @brief Divide @a reg by st(0) (FPU). - inline void fdivp(const X87Register& reg = st(1)) - { - emitX86(INST_FDIVP, ®); - } - - //! @brief Reverse Divide @a dst by @a src (FPU). - //! - //! @note One of @a dst or @a src register must be st(0). - inline void fdivr(const X87Register& dst, const X87Register& src) - { - ASMJIT_ASSERT(dst.index() == 0 || src.index() == 0); - emitX86(INST_FDIVR, &dst, &src); - } - //! @brief Reverse Divide st(0) by 32 bit or 64 bit FP value (FPU). - inline void fdivr(const Mem& src) - { - emitX86(INST_FDIVR, &src); - } - - //! @brief Reverse Divide @a reg by st(0) (FPU). - inline void fdivrp(const X87Register& reg = st(1)) - { - emitX86(INST_FDIVRP, ®); - } - - //! @brief Free Floating-Point Register (FPU). - //! - //! Sets the tag in the FPU tag register associated with register @a reg - //! to empty (11B). The contents of @a reg and the FPU stack-top pointer - //! (TOP) are not affected. - inline void ffree(const X87Register& reg) - { - emitX86(INST_FFREE, ®); - } - - //! @brief Add 16 bit or 32 bit integer to st(0) (FPU). - inline void fiadd(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4); - emitX86(INST_FIADD, &src); - } - - //! @brief Compare st(0) with 16 bit or 32 bit Integer (FPU). - inline void ficom(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4); - emitX86(INST_FICOM, &src); - } - - //! @brief Compare st(0) with 16 bit or 32 bit Integer and pop the stack (FPU). - inline void ficomp(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4); - emitX86(INST_FICOMP, &src); - } - - //! @brief Divide st(0) by 32 bit or 16 bit integer (@a src) (FPU). - inline void fidiv(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4); - emitX86(INST_FIDIV, &src); - } - - //! @brief Reverse Divide st(0) by 32 bit or 16 bit integer (@a src) (FPU). - inline void fidivr(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4); - emitX86(INST_FIDIVR, &src); - } - - //! @brief Load 16 bit, 32 bit or 64 bit Integer and push it to the stack (FPU). - //! - //! Converts the signed-integer source operand into double extended-precision - //! floating point format and pushes the value onto the FPU register stack. - //! The source operand can be a word, doubleword, or quadword integer. It is - //! loaded without rounding errors. The sign of the source operand is - //! preserved. - inline void fild(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4 || src.size() == 8); - emitX86(INST_FILD, &src); - } - - //! @brief Multiply st(0) by 16 bit or 32 bit integer and store it - //! to st(0) (FPU). - inline void fimul(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4); - emitX86(INST_FIMUL, &src); - } - - //! @brief Increment Stack-Top Pointer (FPU). - //! - //! Adds one to the TOP field of the FPU status word (increments the - //! top-of-stack pointer). If the TOP field contains a 7, it is set to 0. - //! The effect of this instruction is to rotate the stack by one position. - //! The contents of the FPU data registers and tag register are not affected. - //! This operation is not equivalent to popping the stack, because the tag - //! for the previous top-of-stack register is not marked empty. - inline void fincstp() - { - emitX86(INST_FINCSTP); - } - - //! @brief Initialize Floating-Point Unit (FPU). - //! - //! Initialize FPU after checking for pending unmasked floating-point - //! exceptions. - inline void finit() - { - emitX86(INST_FINIT); - } - - //! @brief Subtract 16 bit or 32 bit integer from st(0) and store result to - //! st(0) (FPU). - inline void fisub(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4); - emitX86(INST_FISUB, &src); - } - - //! @brief Reverse Subtract 16 bit or 32 bit integer from st(0) and - //! store result to st(0) (FPU). - inline void fisubr(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 2 || src.size() == 4); - emitX86(INST_FISUBR, &src); - } - - //! @brief Initialize Floating-Point Unit (FPU). - //! - //! Initialize FPU without checking for pending unmasked floating-point - //! exceptions. - inline void fninit() - { - emitX86(INST_FNINIT); - } - - //! @brief Store st(0) as 16 bit or 32 bit Integer to @a dst (FPU). - inline void fist(const Mem& dst) - { - ASMJIT_ASSERT(dst.size() == 2 || dst.size() == 4); - emitX86(INST_FIST, &dst); - } - - //! @brief Store st(0) as 16 bit, 32 bit or 64 bit Integer to @a dst and pop - //! stack (FPU). - inline void fistp(const Mem& dst) - { - ASMJIT_ASSERT(dst.size() == 2 || dst.size() == 4 || dst.size() == 8); - emitX86(INST_FISTP, &dst); - } - - //! @brief Push 32 bit, 64 bit or 80 bit Floating Point Value onto the FPU - //! register stack (FPU). - inline void fld(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 4 || src.size() == 8 || src.size() == 10); - emitX86(INST_FLD, &src); - } - - //! @brief Push @a reg onto the FPU register stack (FPU). - inline void fld(const X87Register& reg) - { - emitX86(INST_FLD, ®); - } - - //! @brief Push +1.0 onto the FPU register stack (FPU). - inline void fld1() - { - emitX86(INST_FLD1); - } - - //! @brief Push log2(10) onto the FPU register stack (FPU). - inline void fldl2t() - { - emitX86(INST_FLDL2T); - } - - //! @brief Push log2(e) onto the FPU register stack (FPU). - inline void fldl2e() - { - emitX86(INST_FLDL2E); - } - - //! @brief Push pi onto the FPU register stack (FPU). - inline void fldpi() - { - emitX86(INST_FLDPI); - } - - //! @brief Push log10(2) onto the FPU register stack (FPU). - inline void fldlg2() - { - emitX86(INST_FLDLG2); - } - - //! @brief Push ln(2) onto the FPU register stack (FPU). - inline void fldln2() - { - emitX86(INST_FLDLN2); - } - - //! @brief Push +0.0 onto the FPU register stack (FPU). - inline void fldz() - { - emitX86(INST_FLDZ); - } - - //! @brief Load x87 FPU Control Word (2 bytes) (FPU). - inline void fldcw(const Mem& src) - { - emitX86(INST_FLDCW, &src); - } - - //! @brief Load x87 FPU Environment (14 or 28 bytes) (FPU). - inline void fldenv(const Mem& src) - { - emitX86(INST_FLDENV, &src); - } - - //! @brief Multiply @a dst by @a src and store result in @a dst (FPU). - //! - //! @note One of dst or src must be st(0). - inline void fmul(const X87Register& dst, const X87Register& src) - { - ASMJIT_ASSERT(dst.index() == 0 || src.index() == 0); - emitX86(INST_FMUL, &dst, &src); - } - //! @brief Multiply st(0) by @a src and store result in st(0) (FPU). - //! - //! @note SP-FP or DP-FP determined by @a adr size. - inline void fmul(const Mem& src) - { - emitX86(INST_FMUL, &src); - } - - //! @brief Multiply st(0) by @a dst and POP register stack (FPU). - inline void fmulp(const X87Register& dst = st(1)) - { - emitX86(INST_FMULP, &dst); - } - - //! @brief Clear Exceptions (FPU). - //! - //! Clear floating-point exception flags without checking for pending - //! unmasked floating-point exceptions. - //! - //! Clears the floating-point exception flags (PE, UE, OE, ZE, DE, and IE), - //! the exception summary status flag (ES), the stack fault flag (SF), and - //! the busy flag (B) in the FPU status word. The FCLEX instruction does - //! not checks for and handles any pending unmasked floating-point exceptions - //! before clearing the exception flags. - inline void fnclex() - { - emitX86(INST_FNCLEX); - } - - //! @brief No Operation (FPU). - inline void fnop() - { - emitX86(INST_FNOP); - } - - //! @brief Save FPU State (FPU). - //! - //! Store FPU environment to m94byte or m108byte without - //! checking for pending unmasked FP exceptions. - //! Then re-initialize the FPU. - inline void fnsave(const Mem& dst) - { - emitX86(INST_FNSAVE, &dst); - } - - //! @brief Store x87 FPU Environment (FPU). - //! - //! Store FPU environment to @a dst (14 or 28 Bytes) without checking for - //! pending unmasked floating-point exceptions. Then mask all floating - //! point exceptions. - inline void fnstenv(const Mem& dst) - { - emitX86(INST_FNSTENV, &dst); - } - - //! @brief Store x87 FPU Control Word (FPU). - //! - //! Store FPU control word to @a dst (2 Bytes) without checking for pending - //! unmasked floating-point exceptions. - inline void fnstcw(const Mem& dst) - { - emitX86(INST_FNSTCW, &dst); - } - - //! @brief Store x87 FPU Status Word (2 Bytes) (FPU). - inline void fnstsw(const Register& dst) - { - ASMJIT_ASSERT(dst.isRegCode(REG_AX)); - emitX86(INST_FNSTSW, &dst); - } - //! @brief Store x87 FPU Status Word (2 Bytes) (FPU). - inline void fnstsw(const Mem& dst) - { - emitX86(INST_FNSTSW, &dst); - } - - //! @brief Partial Arctangent (FPU). - //! - //! Replace st(1) with arctan(st(1)/st(0)) and pop the register stack. - inline void fpatan() - { - emitX86(INST_FPATAN); - } - - //! @brief Partial Remainder (FPU). - //! - //! Replace st(0) with the remainder obtained from dividing st(0) by st(1). - inline void fprem() - { - emitX86(INST_FPREM); - } - - //! @brief Partial Remainder (FPU). - //! - //! Replace st(0) with the IEEE remainder obtained from dividing st(0) by - //! st(1). - inline void fprem1() - { - emitX86(INST_FPREM1); - } - - //! @brief Partial Tangent (FPU). - //! - //! Replace st(0) with its tangent and push 1 onto the FPU stack. - inline void fptan() - { - emitX86(INST_FPTAN); - } - - //! @brief Round to Integer (FPU). - //! - //! Rount st(0) to an Integer. - inline void frndint() - { - emitX86(INST_FRNDINT); - } - - //! @brief Restore FPU State (FPU). - //! - //! Load FPU state from src (94 bytes or 108 bytes). - inline void frstor(const Mem& src) - { - emitX86(INST_FRSTOR, &src); - } - - //! @brief Save FPU State (FPU). - //! - //! Store FPU state to 94 or 108 bytes after checking for - //! pending unmasked FP exceptions. Then reinitialize - //! the FPU. - inline void fsave(const Mem& dst) - { - emitX86(INST_FSAVE, &dst); - } - - //! @brief Scale (FPU). - //! - //! Scale st(0) by st(1). - inline void fscale() - { - emitX86(INST_FSCALE); - } - - //! @brief Sine (FPU). - //! - //! This instruction calculates the sine of the source operand in - //! register st(0) and stores the result in st(0). - inline void fsin() - { - emitX86(INST_FSIN); - } - - //! @brief Sine and Cosine (FPU). - //! - //! Compute the sine and cosine of st(0); replace st(0) with - //! the sine, and push the cosine onto the register stack. - inline void fsincos() - { - emitX86(INST_FSINCOS); - } - - //! @brief Square Root (FPU). - //! - //! Calculates square root of st(0) and stores the result in st(0). - inline void fsqrt() - { - emitX86(INST_FSQRT); - } - - //! @brief Store Floating Point Value (FPU). - //! - //! Store st(0) as 32 bit or 64 bit floating point value to @a dst. - inline void fst(const Mem& dst) - { - ASMJIT_ASSERT(dst.size() == 4 || dst.size() == 8); - emitX86(INST_FST, &dst); - } - - //! @brief Store Floating Point Value (FPU). - //! - //! Store st(0) to !a reg. - inline void fst(const X87Register& reg) - { - emitX86(INST_FST, ®); - } - - //! @brief Store Floating Point Value and Pop Register Stack (FPU). - //! - //! Store st(0) as 32 bit or 64 bit floating point value to @a dst - //! and pop register stack. - inline void fstp(const Mem& dst) - { - ASMJIT_ASSERT(dst.size() == 4 || dst.size() == 8 || dst.size() == 10); - emitX86(INST_FSTP, &dst); - } - - //! @brief Store Floating Point Value and Pop Register Stack (FPU). - //! - //! Store st(0) to !a reg and pop register stack. - inline void fstp(const X87Register& reg) - { - emitX86(INST_FSTP, ®); - } - - //! @brief Store x87 FPU Control Word (FPU). - //! - //! Store FPU control word to @a dst (2 Bytes) after checking for pending - //! unmasked floating-point exceptions. - inline void fstcw(const Mem& dst) - { - emitX86(INST_FSTCW, &dst); - } - - //! @brief Store x87 FPU Environment (FPU). - //! - //! Store FPU environment to @a dst (14 or 28 Bytes) after checking for - //! pending unmasked floating-point exceptions. Then mask all floating - //! point exceptions. - inline void fstenv(const Mem& dst) - { - emitX86(INST_FSTENV, &dst); - } - - //! @brief Store x87 FPU Status Word (2 Bytes) (FPU). - inline void fstsw(const Register& dst) - { - ASMJIT_ASSERT(dst.isRegCode(REG_AX)); - emitX86(INST_FSTSW, &dst); - } - //! @brief Store x87 FPU Status Word (2 Bytes) (FPU). - inline void fstsw(const Mem& dst) - { - emitX86(INST_FSTSW, &dst); - } - - //! @brief Subtract @a src from @a dst and store result in @a dst (FPU). - //! - //! @note One of dst or src must be st(0). - inline void fsub(const X87Register& dst, const X87Register& src) - { - ASMJIT_ASSERT(dst.index() == 0 || src.index() == 0); - emitX86(INST_FSUB, &dst, &src); - } - //! @brief Subtract @a src from st(0) and store result in st(0) (FPU). - //! - //! @note SP-FP or DP-FP determined by @a adr size. - inline void fsub(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 4 || src.size() == 8); - emitX86(INST_FSUB, &src); - } - - //! @brief Subtract st(0) from @a dst and POP register stack (FPU). - inline void fsubp(const X87Register& dst = st(1)) - { - emitX86(INST_FSUBP, &dst); - } - - //! @brief Reverse Subtract @a src from @a dst and store result in @a dst (FPU). - //! - //! @note One of dst or src must be st(0). - inline void fsubr(const X87Register& dst, const X87Register& src) - { - ASMJIT_ASSERT(dst.index() == 0 || src.index() == 0); - emitX86(INST_FSUBR, &dst, &src); - } - - //! @brief Reverse Subtract @a src from st(0) and store result in st(0) (FPU). - //! - //! @note SP-FP or DP-FP determined by @a adr size. - inline void fsubr(const Mem& src) - { - ASMJIT_ASSERT(src.size() == 4 || src.size() == 8); - emitX86(INST_FSUBR, &src); - } - - //! @brief Reverse Subtract st(0) from @a dst and POP register stack (FPU). - inline void fsubrp(const X87Register& dst = st(1)) - { - emitX86(INST_FSUBRP, &dst); - } - - //! @brief Floating point test - Compare st(0) with 0.0. (FPU). - inline void ftst() - { - emitX86(INST_FTST); - } - - //! @brief Unordered Compare st(0) with @a reg (FPU). - inline void fucom(const X87Register& reg = st(1)) - { - emitX86(INST_FUCOM, ®); - } - - //! @brief Unordered Compare st(0) and @a reg, check for ordered values - //! and Set EFLAGS (FPU). - inline void fucomi(const X87Register& reg) - { - emitX86(INST_FUCOMI, ®); - } - - //! @brief UnorderedCompare st(0) and @a reg, Check for ordered values - //! and Set EFLAGS and pop the stack (FPU). - inline void fucomip(const X87Register& reg = st(1)) - { - emitX86(INST_FUCOMIP, ®); - } - - //! @brief Unordered Compare st(0) with @a reg and pop register stack (FPU). - inline void fucomp(const X87Register& reg = st(1)) - { - emitX86(INST_FUCOMP, ®); - } - - //! @brief Unordered compare st(0) with st(1) and pop register stack twice - //! (FPU). - inline void fucompp() - { - emitX86(INST_FUCOMPP); - } - - inline void fwait() - { - emitX86(INST_FWAIT); - } - - //! @brief Examine st(0) (FPU). - //! - //! Examines the contents of the ST(0) register and sets the condition code - //! flags C0, C2, and C3 in the FPU status word to indicate the class of - //! value or number in the register. - inline void fxam() - { - emitX86(INST_FXAM); - } - - //! @brief Exchange Register Contents (FPU). - //! - //! Exchange content of st(0) with @a reg. - inline void fxch(const X87Register& reg = st(1)) - { - emitX86(INST_FXCH, ®); - } - - //! @brief Restore FP And MMX(tm) State And Streaming SIMD Extension State - //! (FPU, MMX, SSE). - //! - //! Load FP and MMX(tm) technology and Streaming SIMD Extension state from - //! src (512 bytes). - inline void fxrstor(const Mem& src) - { - emitX86(INST_FXRSTOR, &src); - } - - //! @brief Store FP and MMX(tm) State and Streaming SIMD Extension State - //! (FPU, MMX, SSE). - //! - //! Store FP and MMX(tm) technology state and Streaming SIMD Extension state - //! to dst (512 bytes). - inline void fxsave(const Mem& dst) - { - emitX86(INST_FXSAVE, &dst); - } - - //! @brief Extract Exponent and Significand (FPU). - //! - //! Separate value in st(0) into exponent and significand, store exponent - //! in st(0), and push the significand onto the register stack. - inline void fxtract() - { - emitX86(INST_FXTRACT); - } - - //! @brief Compute y * log2(x). - //! - //! Replace st(1) with (st(1) * log2st(0)) and pop the register stack. - inline void fyl2x() - { - emitX86(INST_FYL2X); - } - - //! @brief Compute y * log_2(x+1). - //! - //! Replace st(1) with (st(1) * (log2st(0) + 1.0)) and pop the register stack. - inline void fyl2xp1() - { - emitX86(INST_FYL2XP1); - } - - // ------------------------------------------------------------------------- - // [MMX] - // ------------------------------------------------------------------------- - - //! @brief Empty MMX state. - inline void emms() - { - emitX86(INST_EMMS); - } - - //! @brief Move DWord (MMX). - inline void movd(const Mem& dst, const MMRegister& src) - { - emitX86(INST_MOVD, &dst, &src); - } - //! @brief Move DWord (MMX). - inline void movd(const Register& dst, const MMRegister& src) - { - emitX86(INST_MOVD, &dst, &src); - } - //! @brief Move DWord (MMX). - inline void movd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_MOVD, &dst, &src); - } - //! @brief Move DWord (MMX). - inline void movd(const MMRegister& dst, const Register& src) - { - emitX86(INST_MOVD, &dst, &src); - } - - //! @brief Move QWord (MMX). - inline void movq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_MOVQ, &dst, &src); - } - //! @brief Move QWord (MMX). - inline void movq(const Mem& dst, const MMRegister& src) - { - emitX86(INST_MOVQ, &dst, &src); - } -#if defined(ASMJIT_X64) - //! @brief Move QWord (MMX). - inline void movq(const Register& dst, const MMRegister& src) - { - emitX86(INST_MOVQ, &dst, &src); - } -#endif - //! @brief Move QWord (MMX). - inline void movq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_MOVQ, &dst, &src); - } -#if defined(ASMJIT_X64) - //! @brief Move QWord (MMX). - inline void movq(const MMRegister& dst, const Register& src) - { - emitX86(INST_MOVQ, &dst, &src); - } -#endif - - //! @brief Pack with Unsigned Saturation (MMX). - inline void packuswb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PACKUSWB, &dst, &src); - } - //! @brief Pack with Unsigned Saturation (MMX). - inline void packuswb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PACKUSWB, &dst, &src); - } - - //! @brief Packed BYTE Add (MMX). - inline void paddb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PADDB, &dst, &src); - } - //! @brief Packed BYTE Add (MMX). - inline void paddb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PADDB, &dst, &src); - } - - //! @brief Packed WORD Add (MMX). - inline void paddw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PADDW, &dst, &src); - } - //! @brief Packed WORD Add (MMX). - inline void paddw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PADDW, &dst, &src); - } - - //! @brief Packed DWORD Add (MMX). - inline void paddd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PADDD, &dst, &src); - } - //! @brief Packed DWORD Add (MMX). - inline void paddd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PADDD, &dst, &src); - } - - //! @brief Packed Add with Saturation (MMX). - inline void paddsb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PADDSB, &dst, &src); - } - //! @brief Packed Add with Saturation (MMX). - inline void paddsb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PADDSB, &dst, &src); - } - - //! @brief Packed Add with Saturation (MMX). - inline void paddsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PADDSW, &dst, &src); - } - //! @brief Packed Add with Saturation (MMX). - inline void paddsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PADDSW, &dst, &src); - } - - //! @brief Packed Add Unsigned with Saturation (MMX). - inline void paddusb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PADDUSB, &dst, &src); - } - //! @brief Packed Add Unsigned with Saturation (MMX). - inline void paddusb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PADDUSB, &dst, &src); - } - - //! @brief Packed Add Unsigned with Saturation (MMX). - inline void paddusw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PADDUSW, &dst, &src); - } - //! @brief Packed Add Unsigned with Saturation (MMX). - inline void paddusw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PADDUSW, &dst, &src); - } - - //! @brief Logical AND (MMX). - inline void pand(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PAND, &dst, &src); - } - //! @brief Logical AND (MMX). - inline void pand(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PAND, &dst, &src); - } - - //! @brief Logical AND Not (MMX). - inline void pandn(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PANDN, &dst, &src); - } - //! @brief Logical AND Not (MMX). - inline void pandn(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PANDN, &dst, &src); - } - - //! @brief Packed Compare for Equal (BYTES) (MMX). - inline void pcmpeqb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PCMPEQB, &dst, &src); - } - //! @brief Packed Compare for Equal (BYTES) (MMX). - inline void pcmpeqb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPEQB, &dst, &src); - } - - //! @brief Packed Compare for Equal (WORDS) (MMX). - inline void pcmpeqw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PCMPEQW, &dst, &src); - } - //! @brief Packed Compare for Equal (WORDS) (MMX). - inline void pcmpeqw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPEQW, &dst, &src); - } - - //! @brief Packed Compare for Equal (DWORDS) (MMX). - inline void pcmpeqd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PCMPEQD, &dst, &src); - } - //! @brief Packed Compare for Equal (DWORDS) (MMX). - inline void pcmpeqd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPEQD, &dst, &src); - } - - //! @brief Packed Compare for Greater Than (BYTES) (MMX). - inline void pcmpgtb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PCMPGTB, &dst, &src); - } - //! @brief Packed Compare for Greater Than (BYTES) (MMX). - inline void pcmpgtb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPGTB, &dst, &src); - } - - //! @brief Packed Compare for Greater Than (WORDS) (MMX). - inline void pcmpgtw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PCMPGTW, &dst, &src); - } - //! @brief Packed Compare for Greater Than (WORDS) (MMX). - inline void pcmpgtw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPGTW, &dst, &src); - } - - //! @brief Packed Compare for Greater Than (DWORDS) (MMX). - inline void pcmpgtd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PCMPGTD, &dst, &src); - } - //! @brief Packed Compare for Greater Than (DWORDS) (MMX). - inline void pcmpgtd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPGTD, &dst, &src); - } - - //! @brief Packed Multiply High (MMX). - inline void pmulhw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMULHW, &dst, &src); - } - //! @brief Packed Multiply High (MMX). - inline void pmulhw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMULHW, &dst, &src); - } - - //! @brief Packed Multiply Low (MMX). - inline void pmullw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMULLW, &dst, &src); - } - //! @brief Packed Multiply Low (MMX). - inline void pmullw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMULLW, &dst, &src); - } - - //! @brief Bitwise Logical OR (MMX). - inline void por(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_POR, &dst, &src); - } - //! @brief Bitwise Logical OR (MMX). - inline void por(const MMRegister& dst, const Mem& src) - { - emitX86(INST_POR, &dst, &src); - } - - //! @brief Packed Multiply and Add (MMX). - inline void pmaddwd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMADDWD, &dst, &src); - } - //! @brief Packed Multiply and Add (MMX). - inline void pmaddwd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMADDWD, &dst, &src); - } - - //! @brief Packed Shift Left Logical (MMX). - inline void pslld(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSLLD, &dst, &src); - } - //! @brief Packed Shift Left Logical (MMX). - inline void pslld(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSLLD, &dst, &src); - } - //! @brief Packed Shift Left Logical (MMX). - inline void pslld(const MMRegister& dst, const Immediate& src) - { - emitX86(INST_PSLLD, &dst, &src); - } - - //! @brief Packed Shift Left Logical (MMX). - inline void psllq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSLLQ, &dst, &src); - } - //! @brief Packed Shift Left Logical (MMX). - inline void psllq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSLLQ, &dst, &src); - } - //! @brief Packed Shift Left Logical (MMX). - inline void psllq(const MMRegister& dst, const Immediate& src) - { - emitX86(INST_PSLLQ, &dst, &src); - } - - //! @brief Packed Shift Left Logical (MMX). - inline void psllw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSLLW, &dst, &src); - } - //! @brief Packed Shift Left Logical (MMX). - inline void psllw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSLLW, &dst, &src); - } - //! @brief Packed Shift Left Logical (MMX). - inline void psllw(const MMRegister& dst, const Immediate& src) - { - emitX86(INST_PSLLW, &dst, &src); - } - - //! @brief Packed Shift Right Arithmetic (MMX). - inline void psrad(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSRAD, &dst, &src); - } - //! @brief Packed Shift Right Arithmetic (MMX). - inline void psrad(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSRAD, &dst, &src); - } - //! @brief Packed Shift Right Arithmetic (MMX). - inline void psrad(const MMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRAD, &dst, &src); - } - - //! @brief Packed Shift Right Arithmetic (MMX). - inline void psraw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSRAW, &dst, &src); - } - //! @brief Packed Shift Right Arithmetic (MMX). - inline void psraw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSRAW, &dst, &src); - } - //! @brief Packed Shift Right Arithmetic (MMX). - inline void psraw(const MMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRAW, &dst, &src); - } - - //! @brief Packed Shift Right Logical (MMX). - inline void psrld(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSRLD, &dst, &src); - } - //! @brief Packed Shift Right Logical (MMX). - inline void psrld(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSRLD, &dst, &src); - } - //! @brief Packed Shift Right Logical (MMX). - inline void psrld(const MMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRLD, &dst, &src); - } - - //! @brief Packed Shift Right Logical (MMX). - inline void psrlq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSRLQ, &dst, &src); - } - //! @brief Packed Shift Right Logical (MMX). - inline void psrlq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSRLQ, &dst, &src); - } - //! @brief Packed Shift Right Logical (MMX). - inline void psrlq(const MMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRLQ, &dst, &src); - } - - //! @brief Packed Shift Right Logical (MMX). - inline void psrlw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSRLW, &dst, &src); - } - //! @brief Packed Shift Right Logical (MMX). - inline void psrlw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSRLW, &dst, &src); - } - //! @brief Packed Shift Right Logical (MMX). - inline void psrlw(const MMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRLW, &dst, &src); - } - - //! @brief Packed Subtract (MMX). - inline void psubb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSUBB, &dst, &src); - } - //! @brief Packed Subtract (MMX). - inline void psubb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBB, &dst, &src); - } - - //! @brief Packed Subtract (MMX). - inline void psubw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSUBW, &dst, &src); - } - //! @brief Packed Subtract (MMX). - inline void psubw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBW, &dst, &src); - } - - //! @brief Packed Subtract (MMX). - inline void psubd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSUBD, &dst, &src); - } - //! @brief Packed Subtract (MMX). - inline void psubd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBD, &dst, &src); - } - - //! @brief Packed Subtract with Saturation (MMX). - inline void psubsb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSUBSB, &dst, &src); - } - //! @brief Packed Subtract with Saturation (MMX). - inline void psubsb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBSB, &dst, &src); - } - - //! @brief Packed Subtract with Saturation (MMX). - inline void psubsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSUBSW, &dst, &src); - } - //! @brief Packed Subtract with Saturation (MMX). - inline void psubsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBSW, &dst, &src); - } - - //! @brief Packed Subtract with Unsigned Saturation (MMX). - inline void psubusb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSUBUSB, &dst, &src); - } - //! @brief Packed Subtract with Unsigned Saturation (MMX). - inline void psubusb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBUSB, &dst, &src); - } - - //! @brief Packed Subtract with Unsigned Saturation (MMX). - inline void psubusw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSUBUSW, &dst, &src); - } - //! @brief Packed Subtract with Unsigned Saturation (MMX). - inline void psubusw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBUSW, &dst, &src); - } - - //! @brief Unpack High Packed Data (MMX). - inline void punpckhbw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PUNPCKHBW, &dst, &src); - } - //! @brief Unpack High Packed Data (MMX). - inline void punpckhbw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKHBW, &dst, &src); - } - - //! @brief Unpack High Packed Data (MMX). - inline void punpckhwd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PUNPCKHWD, &dst, &src); - } - //! @brief Unpack High Packed Data (MMX). - inline void punpckhwd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKHWD, &dst, &src); - } - - //! @brief Unpack High Packed Data (MMX). - inline void punpckhdq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PUNPCKHDQ, &dst, &src); - } - //! @brief Unpack High Packed Data (MMX). - inline void punpckhdq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKHDQ, &dst, &src); - } - - //! @brief Unpack High Packed Data (MMX). - inline void punpcklbw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PUNPCKLBW, &dst, &src); - } - //! @brief Unpack High Packed Data (MMX). - inline void punpcklbw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKLBW, &dst, &src); - } - - //! @brief Unpack High Packed Data (MMX). - inline void punpcklwd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PUNPCKLWD, &dst, &src); - } - //! @brief Unpack High Packed Data (MMX). - inline void punpcklwd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKLWD, &dst, &src); - } - - //! @brief Unpack High Packed Data (MMX). - inline void punpckldq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PUNPCKLDQ, &dst, &src); - } - //! @brief Unpack High Packed Data (MMX). - inline void punpckldq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKLDQ, &dst, &src); - } - - //! @brief Bitwise Exclusive OR (MMX). - inline void pxor(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PXOR, &dst, &src); - } - //! @brief Bitwise Exclusive OR (MMX). - inline void pxor(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PXOR, &dst, &src); - } - - // ------------------------------------------------------------------------- - // [3dNow] - // ------------------------------------------------------------------------- - - //! @brief Faster EMMS (3dNow!). - //! - //! @note Use only for early AMD processors where is only 3dNow! or SSE. If - //! CPU contains SSE2, it's better to use @c emms() ( @c femms() is mapped - //! to @c emms() ). - inline void femms() - { - emitX86(INST_FEMMS); - } - - //! @brief Packed SP-FP to Integer Convert (3dNow!). - inline void pf2id(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PF2ID, &dst, &src); - } - //! @brief Packed SP-FP to Integer Convert (3dNow!). - inline void pf2id(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PF2ID, &dst, &src); - } - - //! @brief Packed SP-FP to Integer Word Convert (3dNow!). - inline void pf2iw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PF2IW, &dst, &src); - } - //! @brief Packed SP-FP to Integer Word Convert (3dNow!). - inline void pf2iw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PF2IW, &dst, &src); - } - - //! @brief Packed SP-FP Accumulate (3dNow!). - inline void pfacc(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFACC, &dst, &src); - } - //! @brief Packed SP-FP Accumulate (3dNow!). - inline void pfacc(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFACC, &dst, &src); - } - - //! @brief Packed SP-FP Addition (3dNow!). - inline void pfadd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFADD, &dst, &src); - } - //! @brief Packed SP-FP Addition (3dNow!). - inline void pfadd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFADD, &dst, &src); - } - - //! @brief Packed SP-FP Compare - dst == src (3dNow!). - inline void pfcmpeq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFCMPEQ, &dst, &src); - } - //! @brief Packed SP-FP Compare - dst == src (3dNow!). - inline void pfcmpeq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFCMPEQ, &dst, &src); - } - - //! @brief Packed SP-FP Compare - dst >= src (3dNow!). - inline void pfcmpge(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFCMPGE, &dst, &src); - } - //! @brief Packed SP-FP Compare - dst >= src (3dNow!). - inline void pfcmpge(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFCMPGE, &dst, &src); - } - - //! @brief Packed SP-FP Compare - dst > src (3dNow!). - inline void pfcmpgt(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFCMPGT, &dst, &src); - } - //! @brief Packed SP-FP Compare - dst > src (3dNow!). - inline void pfcmpgt(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFCMPGT, &dst, &src); - } - - //! @brief Packed SP-FP Maximum (3dNow!). - inline void pfmax(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFMAX, &dst, &src); - } - //! @brief Packed SP-FP Maximum (3dNow!). - inline void pfmax(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFMAX, &dst, &src); - } - - //! @brief Packed SP-FP Minimum (3dNow!). - inline void pfmin(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFMIN, &dst, &src); - } - //! @brief Packed SP-FP Minimum (3dNow!). - inline void pfmin(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFMIN, &dst, &src); - } - - //! @brief Packed SP-FP Multiply (3dNow!). - inline void pfmul(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFMUL, &dst, &src); - } - //! @brief Packed SP-FP Multiply (3dNow!). - inline void pfmul(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFMUL, &dst, &src); - } - - //! @brief Packed SP-FP Negative Accumulate (3dNow!). - inline void pfnacc(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFNACC, &dst, &src); - } - //! @brief Packed SP-FP Negative Accumulate (3dNow!). - inline void pfnacc(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFNACC, &dst, &src); - } - - //! @brief Packed SP-FP Mixed Accumulate (3dNow!). - inline void pfpnaxx(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFPNACC, &dst, &src); - } - //! @brief Packed SP-FP Mixed Accumulate (3dNow!). - inline void pfpnacc(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFPNACC, &dst, &src); - } - - //! @brief Packed SP-FP Reciprocal Approximation (3dNow!). - inline void pfrcp(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFRCP, &dst, &src); - } - //! @brief Packed SP-FP Reciprocal Approximation (3dNow!). - inline void pfrcp(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFRCP, &dst, &src); - } - - //! @brief Packed SP-FP Reciprocal, First Iteration Step (3dNow!). - inline void pfrcpit1(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFRCPIT1, &dst, &src); - } - //! @brief Packed SP-FP Reciprocal, First Iteration Step (3dNow!). - inline void pfrcpit1(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFRCPIT1, &dst, &src); - } - - //! @brief Packed SP-FP Reciprocal, Second Iteration Step (3dNow!). - inline void pfrcpit2(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFRCPIT2, &dst, &src); - } - //! @brief Packed SP-FP Reciprocal, Second Iteration Step (3dNow!). - inline void pfrcpit2(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFRCPIT2, &dst, &src); - } - - //! @brief Packed SP-FP Reciprocal Square Root, First Iteration Step (3dNow!). - inline void pfrsqit1(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFRSQIT1, &dst, &src); - } - //! @brief Packed SP-FP Reciprocal Square Root, First Iteration Step (3dNow!). - inline void pfrsqit1(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFRSQIT1, &dst, &src); - } - - //! @brief Packed SP-FP Reciprocal Square Root Approximation (3dNow!). - inline void pfrsqrt(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFRSQRT, &dst, &src); - } - //! @brief Packed SP-FP Reciprocal Square Root Approximation (3dNow!). - inline void pfrsqrt(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFRSQRT, &dst, &src); - } - - //! @brief Packed SP-FP Subtract (3dNow!). - inline void pfsub(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFSUB, &dst, &src); - } - //! @brief Packed SP-FP Subtract (3dNow!). - inline void pfsub(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFSUB, &dst, &src); - } - - //! @brief Packed SP-FP Reverse Subtract (3dNow!). - inline void pfsubr(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PFSUBR, &dst, &src); - } - //! @brief Packed SP-FP Reverse Subtract (3dNow!). - inline void pfsubr(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PFSUBR, &dst, &src); - } - - //! @brief Packed DWords to SP-FP (3dNow!). - inline void pi2fd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PI2FD, &dst, &src); - } - //! @brief Packed DWords to SP-FP (3dNow!). - inline void pi2fd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PI2FD, &dst, &src); - } - - //! @brief Packed Words to SP-FP (3dNow!). - inline void pi2fw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PI2FW, &dst, &src); - } - //! @brief Packed Words to SP-FP (3dNow!). - inline void pi2fw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PI2FW, &dst, &src); - } - - //! @brief Packed swap DWord (3dNow!) - inline void pswapd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSWAPD, &dst, &src); - } - //! @brief Packed swap DWord (3dNow!) - inline void pswapd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSWAPD, &dst, &src); - } - - // ------------------------------------------------------------------------- - // [SSE] - // ------------------------------------------------------------------------- - - //! @brief Packed SP-FP Add (SSE). - inline void addps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ADDPS, &dst, &src); - } - //! @brief Packed SP-FP Add (SSE). - inline void addps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ADDPS, &dst, &src); - } - - //! @brief Scalar SP-FP Add (SSE). - inline void addss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ADDSS, &dst, &src); - } - //! @brief Scalar SP-FP Add (SSE). - inline void addss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ADDSS, &dst, &src); - } - - //! @brief Bit-wise Logical And Not For SP-FP (SSE). - inline void andnps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ANDNPS, &dst, &src); - } - //! @brief Bit-wise Logical And Not For SP-FP (SSE). - inline void andnps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ANDNPS, &dst, &src); - } - - //! @brief Bit-wise Logical And For SP-FP (SSE). - inline void andps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ANDPS, &dst, &src); - } - //! @brief Bit-wise Logical And For SP-FP (SSE). - inline void andps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ANDPS, &dst, &src); - } - - //! @brief Packed SP-FP Compare (SSE). - inline void cmpps(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_CMPPS, &dst, &src, &imm8); - } - //! @brief Packed SP-FP Compare (SSE). - inline void cmpps(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_CMPPS, &dst, &src, &imm8); - } - - //! @brief Compare Scalar SP-FP Values (SSE). - inline void cmpss(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_CMPSS, &dst, &src, &imm8); - } - //! @brief Compare Scalar SP-FP Values (SSE). - inline void cmpss(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_CMPSS, &dst, &src, &imm8); - } - - //! @brief Scalar Ordered SP-FP Compare and Set EFLAGS (SSE). - inline void comiss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_COMISS, &dst, &src); - } - //! @brief Scalar Ordered SP-FP Compare and Set EFLAGS (SSE). - inline void comiss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_COMISS, &dst, &src); - } - - //! @brief Packed Signed INT32 to Packed SP-FP Conversion (SSE). - inline void cvtpi2ps(const XMMRegister& dst, const MMRegister& src) - { - emitX86(INST_CVTPI2PS, &dst, &src); - } - //! @brief Packed Signed INT32 to Packed SP-FP Conversion (SSE). - inline void cvtpi2ps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTPI2PS, &dst, &src); - } - - //! @brief Packed SP-FP to Packed INT32 Conversion (SSE). - inline void cvtps2pi(const MMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTPS2PI, &dst, &src); - } - //! @brief Packed SP-FP to Packed INT32 Conversion (SSE). - inline void cvtps2pi(const MMRegister& dst, const Mem& src) - { - emitX86(INST_CVTPS2PI, &dst, &src); - } - - //! @brief Scalar Signed INT32 to SP-FP Conversion (SSE). - inline void cvtsi2ss(const XMMRegister& dst, const Register& src) - { - emitX86(INST_CVTSI2SS, &dst, &src); - } - //! @brief Scalar Signed INT32 to SP-FP Conversion (SSE). - inline void cvtsi2ss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTSI2SS, &dst, &src); - } - - //! @brief Scalar SP-FP to Signed INT32 Conversion (SSE). - inline void cvtss2si(const Register& dst, const XMMRegister& src) - { - emitX86(INST_CVTSS2SI, &dst, &src); - } - //! @brief Scalar SP-FP to Signed INT32 Conversion (SSE). - inline void cvtss2si(const Register& dst, const Mem& src) - { - emitX86(INST_CVTSS2SI, &dst, &src); - } - - //! @brief Packed SP-FP to Packed INT32 Conversion (truncate) (SSE). - inline void cvttps2pi(const MMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTTPS2PI, &dst, &src); - } - //! @brief Packed SP-FP to Packed INT32 Conversion (truncate) (SSE). - inline void cvttps2pi(const MMRegister& dst, const Mem& src) - { - emitX86(INST_CVTTPS2PI, &dst, &src); - } - - //! @brief Scalar SP-FP to Signed INT32 Conversion (truncate) (SSE). - inline void cvttss2si(const Register& dst, const XMMRegister& src) - { - emitX86(INST_CVTTSS2SI, &dst, &src); - } - //! @brief Scalar SP-FP to Signed INT32 Conversion (truncate) (SSE). - inline void cvttss2si(const Register& dst, const Mem& src) - { - emitX86(INST_CVTTSS2SI, &dst, &src); - } - - //! @brief Packed SP-FP Divide (SSE). - inline void divps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_DIVPS, &dst, &src); - } - //! @brief Packed SP-FP Divide (SSE). - inline void divps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_DIVPS, &dst, &src); - } - - //! @brief Scalar SP-FP Divide (SSE). - inline void divss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_DIVSS, &dst, &src); - } - //! @brief Scalar SP-FP Divide (SSE). - inline void divss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_DIVSS, &dst, &src); - } - - //! @brief Load Streaming SIMD Extension Control/Status (SSE). - inline void ldmxcsr(const Mem& src) - { - emitX86(INST_LDMXCSR, &src); - } - - //! @brief Byte Mask Write (SSE). - //! - //! @note The default memory location is specified by DS:EDI. - inline void maskmovq(const MMRegister& data, const MMRegister& mask) - { - emitX86(INST_MASKMOVQ, &data, &mask); - } - - //! @brief Packed SP-FP Maximum (SSE). - inline void maxps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MAXPS, &dst, &src); - } - //! @brief Packed SP-FP Maximum (SSE). - inline void maxps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MAXPS, &dst, &src); - } - - //! @brief Scalar SP-FP Maximum (SSE). - inline void maxss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MAXSS, &dst, &src); - } - //! @brief Scalar SP-FP Maximum (SSE). - inline void maxss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MAXSS, &dst, &src); - } - - //! @brief Packed SP-FP Minimum (SSE). - inline void minps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MINPS, &dst, &src); - } - //! @brief Packed SP-FP Minimum (SSE). - inline void minps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MINPS, &dst, &src); - } - - //! @brief Scalar SP-FP Minimum (SSE). - inline void minss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MINSS, &dst, &src); - } - //! @brief Scalar SP-FP Minimum (SSE). - inline void minss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MINSS, &dst, &src); - } - - //! @brief Move Aligned Packed SP-FP Values (SSE). - inline void movaps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVAPS, &dst, &src); - } - //! @brief Move Aligned Packed SP-FP Values (SSE). - inline void movaps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVAPS, &dst, &src); - } - - //! @brief Move Aligned Packed SP-FP Values (SSE). - inline void movaps(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVAPS, &dst, &src); - } - - //! @brief Move DWord. - inline void movd(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVD, &dst, &src); - } - //! @brief Move DWord. - inline void movd(const Register& dst, const XMMRegister& src) - { - emitX86(INST_MOVD, &dst, &src); - } - //! @brief Move DWord. - inline void movd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVD, &dst, &src); - } - //! @brief Move DWord. - inline void movd(const XMMRegister& dst, const Register& src) - { - emitX86(INST_MOVD, &dst, &src); - } - - //! @brief Move QWord (SSE). - inline void movq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVQ, &dst, &src); - } - //! @brief Move QWord (SSE). - inline void movq(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVQ, &dst, &src); - } -#if defined(ASMJIT_X64) - //! @brief Move QWord (SSE). - inline void movq(const Register& dst, const XMMRegister& src) - { - emitX86(INST_MOVQ, &dst, &src); - } -#endif // ASMJIT_X64 - //! @brief Move QWord (SSE). - inline void movq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVQ, &dst, &src); - } -#if defined(ASMJIT_X64) - //! @brief Move QWord (SSE). - inline void movq(const XMMRegister& dst, const Register& src) - { - emitX86(INST_MOVQ, &dst, &src); - } -#endif // ASMJIT_X64 - - //! @brief Move 64 Bits Non Temporal (SSE). - inline void movntq(const Mem& dst, const MMRegister& src) - { - emitX86(INST_MOVNTQ, &dst, &src); - } - - //! @brief High to Low Packed SP-FP (SSE). - inline void movhlps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVHLPS, &dst, &src); - } - - //! @brief Move High Packed SP-FP (SSE). - inline void movhps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVHPS, &dst, &src); - } - - //! @brief Move High Packed SP-FP (SSE). - inline void movhps(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVHPS, &dst, &src); - } - - //! @brief Move Low to High Packed SP-FP (SSE). - inline void movlhps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVLHPS, &dst, &src); - } - - //! @brief Move Low Packed SP-FP (SSE). - inline void movlps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVLPS, &dst, &src); - } - - //! @brief Move Low Packed SP-FP (SSE). - inline void movlps(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVLPS, &dst, &src); - } - - //! @brief Move Aligned Four Packed SP-FP Non Temporal (SSE). - inline void movntps(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVNTPS, &dst, &src); - } - - //! @brief Move Scalar SP-FP (SSE). - inline void movss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVSS, &dst, &src); - } - - //! @brief Move Scalar SP-FP (SSE). - inline void movss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVSS, &dst, &src); - } - - //! @brief Move Scalar SP-FP (SSE). - inline void movss(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVSS, &dst, &src); - } - - //! @brief Move Unaligned Packed SP-FP Values (SSE). - inline void movups(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVUPS, &dst, &src); - } - //! @brief Move Unaligned Packed SP-FP Values (SSE). - inline void movups(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVUPS, &dst, &src); - } - - //! @brief Move Unaligned Packed SP-FP Values (SSE). - inline void movups(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVUPS, &dst, &src); - } - - //! @brief Packed SP-FP Multiply (SSE). - inline void mulps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MULPS, &dst, &src); - } - //! @brief Packed SP-FP Multiply (SSE). - inline void mulps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MULPS, &dst, &src); - } - - //! @brief Scalar SP-FP Multiply (SSE). - inline void mulss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MULSS, &dst, &src); - } - //! @brief Scalar SP-FP Multiply (SSE). - inline void mulss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MULSS, &dst, &src); - } - - //! @brief Bit-wise Logical OR for SP-FP Data (SSE). - inline void orps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ORPS, &dst, &src); - } - //! @brief Bit-wise Logical OR for SP-FP Data (SSE). - inline void orps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ORPS, &dst, &src); - } - - //! @brief Packed Average (SSE). - inline void pavgb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PAVGB, &dst, &src); - } - //! @brief Packed Average (SSE). - inline void pavgb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PAVGB, &dst, &src); - } - - //! @brief Packed Average (SSE). - inline void pavgw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PAVGW, &dst, &src); - } - //! @brief Packed Average (SSE). - inline void pavgw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PAVGW, &dst, &src); - } - - //! @brief Extract Word (SSE). - inline void pextrw(const Register& dst, const MMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRW, &dst, &src, &imm8); - } - - //! @brief Insert Word (SSE). - inline void pinsrw(const MMRegister& dst, const Register& src, const Immediate& imm8) - { - emitX86(INST_PINSRW, &dst, &src, &imm8); - } - //! @brief Insert Word (SSE). - inline void pinsrw(const MMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PINSRW, &dst, &src, &imm8); - } - - //! @brief Packed Signed Integer Word Maximum (SSE). - inline void pmaxsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMAXSW, &dst, &src); - } - //! @brief Packed Signed Integer Word Maximum (SSE). - inline void pmaxsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMAXSW, &dst, &src); - } - - //! @brief Packed Unsigned Integer Byte Maximum (SSE). - inline void pmaxub(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMAXUB, &dst, &src); - } - //! @brief Packed Unsigned Integer Byte Maximum (SSE). - inline void pmaxub(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMAXUB, &dst, &src); - } - - //! @brief Packed Signed Integer Word Minimum (SSE). - inline void pminsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMINSW, &dst, &src); - } - //! @brief Packed Signed Integer Word Minimum (SSE). - inline void pminsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMINSW, &dst, &src); - } - - //! @brief Packed Unsigned Integer Byte Minimum (SSE). - inline void pminub(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMINUB, &dst, &src); - } - //! @brief Packed Unsigned Integer Byte Minimum (SSE). - inline void pminub(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMINUB, &dst, &src); - } - - //! @brief Move Byte Mask To Integer (SSE). - inline void pmovmskb(const Register& dst, const MMRegister& src) - { - emitX86(INST_PMOVMSKB, &dst, &src); - } - - //! @brief Packed Multiply High Unsigned (SSE). - inline void pmulhuw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMULHUW, &dst, &src); - } - //! @brief Packed Multiply High Unsigned (SSE). - inline void pmulhuw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMULHUW, &dst, &src); - } - - //! @brief Packed Sum of Absolute Differences (SSE). - inline void psadbw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSADBW, &dst, &src); - } - //! @brief Packed Sum of Absolute Differences (SSE). - inline void psadbw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSADBW, &dst, &src); - } - - //! @brief Packed Shuffle word (SSE). - inline void pshufw(const MMRegister& dst, const MMRegister& src, const Immediate& imm8) - { - emitX86(INST_PSHUFW, &dst, &src, &imm8); - } - //! @brief Packed Shuffle word (SSE). - inline void pshufw(const MMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PSHUFW, &dst, &src, &imm8); - } - - //! @brief Packed SP-FP Reciprocal (SSE). - inline void rcpps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_RCPPS, &dst, &src); - } - //! @brief Packed SP-FP Reciprocal (SSE). - inline void rcpps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_RCPPS, &dst, &src); - } - - //! @brief Scalar SP-FP Reciprocal (SSE). - inline void rcpss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_RCPSS, &dst, &src); - } - //! @brief Scalar SP-FP Reciprocal (SSE). - inline void rcpss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_RCPSS, &dst, &src); - } - - //! @brief Prefetch (SSE). - inline void prefetch(const Mem& mem, const Immediate& hint) - { - emitX86(INST_PREFETCH, &mem, &hint); - } - - //! @brief Compute Sum of Absolute Differences (SSE). - inline void psadbw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSADBW, &dst, &src); - } - //! @brief Compute Sum of Absolute Differences (SSE). - inline void psadbw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSADBW, &dst, &src); - } - - //! @brief Packed SP-FP Square Root Reciprocal (SSE). - inline void rsqrtps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_RSQRTPS, &dst, &src); - } - //! @brief Packed SP-FP Square Root Reciprocal (SSE). - inline void rsqrtps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_RSQRTPS, &dst, &src); - } - - //! @brief Scalar SP-FP Square Root Reciprocal (SSE). - inline void rsqrtss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_RSQRTSS, &dst, &src); - } - //! @brief Scalar SP-FP Square Root Reciprocal (SSE). - inline void rsqrtss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_RSQRTSS, &dst, &src); - } - - //! @brief Store fence (SSE). - inline void sfence() - { - emitX86(INST_SFENCE); - } - - //! @brief Shuffle SP-FP (SSE). - inline void shufps(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_SHUFPS, &dst, &src, &imm8); - } - //! @brief Shuffle SP-FP (SSE). - inline void shufps(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_SHUFPS, &dst, &src, &imm8); - } - - //! @brief Packed SP-FP Square Root (SSE). - inline void sqrtps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_SQRTPS, &dst, &src); - } - //! @brief Packed SP-FP Square Root (SSE). - inline void sqrtps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_SQRTPS, &dst, &src); - } - - //! @brief Scalar SP-FP Square Root (SSE). - inline void sqrtss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_SQRTSS, &dst, &src); - } - //! @brief Scalar SP-FP Square Root (SSE). - inline void sqrtss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_SQRTSS, &dst, &src); - } - - //! @brief Store Streaming SIMD Extension Control/Status (SSE). - inline void stmxcsr(const Mem& dst) - { - emitX86(INST_STMXCSR, &dst); - } - - //! @brief Packed SP-FP Subtract (SSE). - inline void subps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_SUBPS, &dst, &src); - } - //! @brief Packed SP-FP Subtract (SSE). - inline void subps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_SUBPS, &dst, &src); - } - - //! @brief Scalar SP-FP Subtract (SSE). - inline void subss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_SUBSS, &dst, &src); - } - //! @brief Scalar SP-FP Subtract (SSE). - inline void subss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_SUBSS, &dst, &src); - } - - //! @brief Unordered Scalar SP-FP compare and set EFLAGS (SSE). - inline void ucomiss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_UCOMISS, &dst, &src); - } - //! @brief Unordered Scalar SP-FP compare and set EFLAGS (SSE). - inline void ucomiss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_UCOMISS, &dst, &src); - } - - //! @brief Unpack High Packed SP-FP Data (SSE). - inline void unpckhps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_UNPCKHPS, &dst, &src); - } - //! @brief Unpack High Packed SP-FP Data (SSE). - inline void unpckhps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_UNPCKHPS, &dst, &src); - } - - //! @brief Unpack Low Packed SP-FP Data (SSE). - inline void unpcklps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_UNPCKLPS, &dst, &src); - } - //! @brief Unpack Low Packed SP-FP Data (SSE). - inline void unpcklps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_UNPCKLPS, &dst, &src); - } - - //! @brief Bit-wise Logical Xor for SP-FP Data (SSE). - inline void xorps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_XORPS, &dst, &src); - } - //! @brief Bit-wise Logical Xor for SP-FP Data (SSE). - inline void xorps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_XORPS, &dst, &src); - } - - // ------------------------------------------------------------------------- - // [SSE2] - // ------------------------------------------------------------------------- - - //! @brief Packed DP-FP Add (SSE2). - inline void addpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ADDPD, &dst, &src); - } - //! @brief Packed DP-FP Add (SSE2). - inline void addpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ADDPD, &dst, &src); - } - - //! @brief Scalar DP-FP Add (SSE2). - inline void addsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ADDSD, &dst, &src); - } - //! @brief Scalar DP-FP Add (SSE2). - inline void addsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ADDSD, &dst, &src); - } - - //! @brief Bit-wise Logical And Not For DP-FP (SSE2). - inline void andnpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ANDNPD, &dst, &src); - } - //! @brief Bit-wise Logical And Not For DP-FP (SSE2). - inline void andnpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ANDNPD, &dst, &src); - } - - //! @brief Bit-wise Logical And For DP-FP (SSE2). - inline void andpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ANDPD, &dst, &src); - } - //! @brief Bit-wise Logical And For DP-FP (SSE2). - inline void andpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ANDPD, &dst, &src); - } - - //! @brief Flush Cache Line (SSE2). - inline void clflush(const Mem& mem) - { - emitX86(INST_CLFLUSH, &mem); - } - - //! @brief Packed DP-FP Compare (SSE2). - inline void cmppd(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_CMPPD, &dst, &src, &imm8); - } - //! @brief Packed DP-FP Compare (SSE2). - inline void cmppd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_CMPPD, &dst, &src, &imm8); - } - - //! @brief Compare Scalar SP-FP Values (SSE2). - inline void cmpsd(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_CMPSD, &dst, &src, &imm8); - } - //! @brief Compare Scalar SP-FP Values (SSE2). - inline void cmpsd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_CMPSD, &dst, &src, &imm8); - } - - //! @brief Scalar Ordered DP-FP Compare and Set EFLAGS (SSE2). - inline void comisd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_COMISD, &dst, &src); - } - //! @brief Scalar Ordered DP-FP Compare and Set EFLAGS (SSE2). - inline void comisd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_COMISD, &dst, &src); - } - - //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2). - inline void cvtdq2pd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTDQ2PD, &dst, &src); - } - //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2). - inline void cvtdq2pd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTDQ2PD, &dst, &src); - } - - //! @brief Convert Packed Dword Integers to Packed SP-FP Values (SSE2). - inline void cvtdq2ps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTDQ2PS, &dst, &src); - } - //! @brief Convert Packed Dword Integers to Packed SP-FP Values (SSE2). - inline void cvtdq2ps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTDQ2PS, &dst, &src); - } - - //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2). - inline void cvtpd2dq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTPD2DQ, &dst, &src); - } - //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2). - inline void cvtpd2dq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTPD2DQ, &dst, &src); - } - - //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2). - inline void cvtpd2pi(const MMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTPD2PI, &dst, &src); - } - //! @brief Convert Packed DP-FP Values to Packed Dword Integers (SSE2). - inline void cvtpd2pi(const MMRegister& dst, const Mem& src) - { - emitX86(INST_CVTPD2PI, &dst, &src); - } - - //! @brief Convert Packed DP-FP Values to Packed SP-FP Values (SSE2). - inline void cvtpd2ps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTPD2PS, &dst, &src); - } - //! @brief Convert Packed DP-FP Values to Packed SP-FP Values (SSE2). - inline void cvtpd2ps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTPD2PS, &dst, &src); - } - - //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2). - inline void cvtpi2pd(const XMMRegister& dst, const MMRegister& src) - { - emitX86(INST_CVTPI2PD, &dst, &src); - } - //! @brief Convert Packed Dword Integers to Packed DP-FP Values (SSE2). - inline void cvtpi2pd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTPI2PD, &dst, &src); - } - - //! @brief Convert Packed SP-FP Values to Packed Dword Integers (SSE2). - inline void cvtps2dq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTPS2DQ, &dst, &src); - } - //! @brief Convert Packed SP-FP Values to Packed Dword Integers (SSE2). - inline void cvtps2dq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTPS2DQ, &dst, &src); - } - - //! @brief Convert Packed SP-FP Values to Packed DP-FP Values (SSE2). - inline void cvtps2pd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTPS2PD, &dst, &src); - } - //! @brief Convert Packed SP-FP Values to Packed DP-FP Values (SSE2). - inline void cvtps2pd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTPS2PD, &dst, &src); - } - - //! @brief Convert Scalar DP-FP Value to Dword Integer (SSE2). - inline void cvtsd2si(const Register& dst, const XMMRegister& src) - { - emitX86(INST_CVTSD2SI, &dst, &src); - } - //! @brief Convert Scalar DP-FP Value to Dword Integer (SSE2). - inline void cvtsd2si(const Register& dst, const Mem& src) - { - emitX86(INST_CVTSD2SI, &dst, &src); - } - - //! @brief Convert Scalar DP-FP Value to Scalar SP-FP Value (SSE2). - inline void cvtsd2ss(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTSD2SS, &dst, &src); - } - //! @brief Convert Scalar DP-FP Value to Scalar SP-FP Value (SSE2). - inline void cvtsd2ss(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTSD2SS, &dst, &src); - } - - //! @brief Convert Dword Integer to Scalar DP-FP Value (SSE2). - inline void cvtsi2sd(const XMMRegister& dst, const Register& src) - { - emitX86(INST_CVTSI2SD, &dst, &src); - } - //! @brief Convert Dword Integer to Scalar DP-FP Value (SSE2). - inline void cvtsi2sd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTSI2SD, &dst, &src); - } - - //! @brief Convert Scalar SP-FP Value to Scalar DP-FP Value (SSE2). - inline void cvtss2sd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTSS2SD, &dst, &src); - } - //! @brief Convert Scalar SP-FP Value to Scalar DP-FP Value (SSE2). - inline void cvtss2sd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTSS2SD, &dst, &src); - } - - //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2). - inline void cvttpd2pi(const MMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTTPD2PI, &dst, &src); - } - //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2). - inline void cvttpd2pi(const MMRegister& dst, const Mem& src) - { - emitX86(INST_CVTTPD2PI, &dst, &src); - } - - //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2). - inline void cvttpd2dq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTTPD2DQ, &dst, &src); - } - //! @brief Convert with Truncation Packed DP-FP Values to Packed Dword Integers (SSE2). - inline void cvttpd2dq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTTPD2DQ, &dst, &src); - } - - //! @brief Convert with Truncation Packed SP-FP Values to Packed Dword Integers (SSE2). - inline void cvttps2dq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_CVTTPS2DQ, &dst, &src); - } - //! @brief Convert with Truncation Packed SP-FP Values to Packed Dword Integers (SSE2). - inline void cvttps2dq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_CVTTPS2DQ, &dst, &src); - } - - //! @brief Convert with Truncation Scalar DP-FP Value to Signed Dword Integer (SSE2). - inline void cvttsd2si(const Register& dst, const XMMRegister& src) - { - emitX86(INST_CVTTSD2SI, &dst, &src); - } - //! @brief Convert with Truncation Scalar DP-FP Value to Signed Dword Integer (SSE2). - inline void cvttsd2si(const Register& dst, const Mem& src) - { - emitX86(INST_CVTTSD2SI, &dst, &src); - } - - //! @brief Packed DP-FP Divide (SSE2). - inline void divpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_DIVPD, &dst, &src); - } - //! @brief Packed DP-FP Divide (SSE2). - inline void divpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_DIVPD, &dst, &src); - } - - //! @brief Scalar DP-FP Divide (SSE2). - inline void divsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_DIVSD, &dst, &src); - } - //! @brief Scalar DP-FP Divide (SSE2). - inline void divsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_DIVSD, &dst, &src); - } - - //! @brief Load Fence (SSE2). - inline void lfence() - { - emitX86(INST_LFENCE); - } - - //! @brief Store Selected Bytes of Double Quadword (SSE2). - //! - //! @note Target is DS:EDI. - inline void maskmovdqu(const XMMRegister& src, const XMMRegister& mask) - { - emitX86(INST_MASKMOVDQU, &src, &mask); - } - - //! @brief Return Maximum Packed Double-Precision FP Values (SSE2). - inline void maxpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MAXPD, &dst, &src); - } - //! @brief Return Maximum Packed Double-Precision FP Values (SSE2). - inline void maxpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MAXPD, &dst, &src); - } - - //! @brief Return Maximum Scalar Double-Precision FP Value (SSE2). - inline void maxsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MAXSD, &dst, &src); - } - //! @brief Return Maximum Scalar Double-Precision FP Value (SSE2). - inline void maxsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MAXSD, &dst, &src); - } - - //! @brief Memory Fence (SSE2). - inline void mfence() - { - emitX86(INST_MFENCE); - } - - //! @brief Return Minimum Packed DP-FP Values (SSE2). - inline void minpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MINPD, &dst, &src); - } - //! @brief Return Minimum Packed DP-FP Values (SSE2). - inline void minpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MINPD, &dst, &src); - } - - //! @brief Return Minimum Scalar DP-FP Value (SSE2). - inline void minsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MINSD, &dst, &src); - } - //! @brief Return Minimum Scalar DP-FP Value (SSE2). - inline void minsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MINSD, &dst, &src); - } - - //! @brief Move Aligned DQWord (SSE2). - inline void movdqa(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVDQA, &dst, &src); - } - //! @brief Move Aligned DQWord (SSE2). - inline void movdqa(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVDQA, &dst, &src); - } - - //! @brief Move Aligned DQWord (SSE2). - inline void movdqa(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVDQA, &dst, &src); - } - - //! @brief Move Unaligned Double Quadword (SSE2). - inline void movdqu(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVDQU, &dst, &src); - } - //! @brief Move Unaligned Double Quadword (SSE2). - inline void movdqu(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVDQU, &dst, &src); - } - - //! @brief Move Unaligned Double Quadword (SSE2). - inline void movdqu(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVDQU, &dst, &src); - } - - //! @brief Extract Packed SP-FP Sign Mask (SSE2). - inline void movmskps(const Register& dst, const XMMRegister& src) - { - emitX86(INST_MOVMSKPS, &dst, &src); - } - - //! @brief Extract Packed DP-FP Sign Mask (SSE2). - inline void movmskpd(const Register& dst, const XMMRegister& src) - { - emitX86(INST_MOVMSKPD, &dst, &src); - } - - //! @brief Move Scalar Double-Precision FP Value (SSE2). - inline void movsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVSD, &dst, &src); - } - //! @brief Move Scalar Double-Precision FP Value (SSE2). - inline void movsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVSD, &dst, &src); - } - - //! @brief Move Scalar Double-Precision FP Value (SSE2). - inline void movsd(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVSD, &dst, &src); - } - - //! @brief Move Aligned Packed Double-Precision FP Values (SSE2). - inline void movapd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVAPD, &dst, &src); - } - - //! @brief Move Aligned Packed Double-Precision FP Values (SSE2). - inline void movapd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVAPD, &dst, &src); - } - - //! @brief Move Aligned Packed Double-Precision FP Values (SSE2). - inline void movapd(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVAPD, &dst, &src); - } - - //! @brief Move Quadword from XMM to MMX Technology Register (SSE2). - inline void movdq2q(const MMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVDQ2Q, &dst, &src); - } - - //! @brief Move Quadword from MMX Technology to XMM Register (SSE2). - inline void movq2dq(const XMMRegister& dst, const MMRegister& src) - { - emitX86(INST_MOVQ2DQ, &dst, &src); - } - - //! @brief Move High Packed Double-Precision FP Value (SSE2). - inline void movhpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVHPD, &dst, &src); - } - - //! @brief Move High Packed Double-Precision FP Value (SSE2). - inline void movhpd(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVHPD, &dst, &src); - } - - //! @brief Move Low Packed Double-Precision FP Value (SSE2). - inline void movlpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVLPD, &dst, &src); - } - - //! @brief Move Low Packed Double-Precision FP Value (SSE2). - inline void movlpd(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVLPD, &dst, &src); - } - - //! @brief Store Double Quadword Using Non-Temporal Hint (SSE2). - inline void movntdq(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVNTDQ, &dst, &src); - } - - //! @brief Store Store DWORD Using Non-Temporal Hint (SSE2). - inline void movnti(const Mem& dst, const Register& src) - { - emitX86(INST_MOVNTI, &dst, &src); - } - - //! @brief Store Packed Double-Precision FP Values Using Non-Temporal Hint (SSE2). - inline void movntpd(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVNTPD, &dst, &src); - } - - //! @brief Move Unaligned Packed Double-Precision FP Values (SSE2). - inline void movupd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVUPD, &dst, &src); - } - - //! @brief Move Unaligned Packed Double-Precision FP Values (SSE2). - inline void movupd(const Mem& dst, const XMMRegister& src) - { - emitX86(INST_MOVUPD, &dst, &src); - } - - //! @brief Packed DP-FP Multiply (SSE2). - inline void mulpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MULPD, &dst, &src); - } - //! @brief Packed DP-FP Multiply (SSE2). - inline void mulpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MULPD, &dst, &src); - } - - //! @brief Scalar DP-FP Multiply (SSE2). - inline void mulsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MULSD, &dst, &src); - } - //! @brief Scalar DP-FP Multiply (SSE2). - inline void mulsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MULSD, &dst, &src); - } - - //! @brief Bit-wise Logical OR for DP-FP Data (SSE2). - inline void orpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ORPD, &dst, &src); - } - //! @brief Bit-wise Logical OR for DP-FP Data (SSE2). - inline void orpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ORPD, &dst, &src); - } - - //! @brief Pack with Signed Saturation (SSE2). - inline void packsswb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PACKSSWB, &dst, &src); - } - //! @brief Pack with Signed Saturation (SSE2). - inline void packsswb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PACKSSWB, &dst, &src); - } - - //! @brief Pack with Signed Saturation (SSE2). - inline void packssdw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PACKSSDW, &dst, &src); - } - //! @brief Pack with Signed Saturation (SSE2). - inline void packssdw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PACKSSDW, &dst, &src); - } - - //! @brief Pack with Unsigned Saturation (SSE2). - inline void packuswb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PACKUSWB, &dst, &src); - } - //! @brief Pack with Unsigned Saturation (SSE2). - inline void packuswb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PACKUSWB, &dst, &src); - } - - //! @brief Packed BYTE Add (SSE2). - inline void paddb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PADDB, &dst, &src); - } - //! @brief Packed BYTE Add (SSE2). - inline void paddb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PADDB, &dst, &src); - } - - //! @brief Packed WORD Add (SSE2). - inline void paddw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PADDW, &dst, &src); - } - //! @brief Packed WORD Add (SSE2). - inline void paddw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PADDW, &dst, &src); - } - - //! @brief Packed DWORD Add (SSE2). - inline void paddd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PADDD, &dst, &src); - } - //! @brief Packed DWORD Add (SSE2). - inline void paddd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PADDD, &dst, &src); - } - - //! @brief Packed QWORD Add (SSE2). - inline void paddq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PADDQ, &dst, &src); - } - //! @brief Packed QWORD Add (SSE2). - inline void paddq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PADDQ, &dst, &src); - } - - //! @brief Packed QWORD Add (SSE2). - inline void paddq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PADDQ, &dst, &src); - } - //! @brief Packed QWORD Add (SSE2). - inline void paddq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PADDQ, &dst, &src); - } - - //! @brief Packed Add with Saturation (SSE2). - inline void paddsb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PADDSB, &dst, &src); - } - //! @brief Packed Add with Saturation (SSE2). - inline void paddsb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PADDSB, &dst, &src); - } - - //! @brief Packed Add with Saturation (SSE2). - inline void paddsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PADDSW, &dst, &src); - } - //! @brief Packed Add with Saturation (SSE2). - inline void paddsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PADDSW, &dst, &src); - } - - //! @brief Packed Add Unsigned with Saturation (SSE2). - inline void paddusb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PADDUSB, &dst, &src); - } - //! @brief Packed Add Unsigned with Saturation (SSE2). - inline void paddusb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PADDUSB, &dst, &src); - } - - //! @brief Packed Add Unsigned with Saturation (SSE2). - inline void paddusw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PADDUSW, &dst, &src); - } - //! @brief Packed Add Unsigned with Saturation (SSE2). - inline void paddusw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PADDUSW, &dst, &src); - } - - //! @brief Logical AND (SSE2). - inline void pand(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PAND, &dst, &src); - } - //! @brief Logical AND (SSE2). - inline void pand(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PAND, &dst, &src); - } - - //! @brief Logical AND Not (SSE2). - inline void pandn(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PANDN, &dst, &src); - } - //! @brief Logical AND Not (SSE2). - inline void pandn(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PANDN, &dst, &src); - } - - //! @brief Spin Loop Hint (SSE2). - inline void pause() - { - emitX86(INST_PAUSE); - } - - //! @brief Packed Average (SSE2). - inline void pavgb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PAVGB, &dst, &src); - } - //! @brief Packed Average (SSE2). - inline void pavgb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PAVGB, &dst, &src); - } - - //! @brief Packed Average (SSE2). - inline void pavgw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PAVGW, &dst, &src); - } - //! @brief Packed Average (SSE2). - inline void pavgw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PAVGW, &dst, &src); - } - - //! @brief Packed Compare for Equal (BYTES) (SSE2). - inline void pcmpeqb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PCMPEQB, &dst, &src); - } - //! @brief Packed Compare for Equal (BYTES) (SSE2). - inline void pcmpeqb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPEQB, &dst, &src); - } - - //! @brief Packed Compare for Equal (WORDS) (SSE2). - inline void pcmpeqw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PCMPEQW, &dst, &src); - } - //! @brief Packed Compare for Equal (WORDS) (SSE2). - inline void pcmpeqw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPEQW, &dst, &src); - } - - //! @brief Packed Compare for Equal (DWORDS) (SSE2). - inline void pcmpeqd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PCMPEQD, &dst, &src); - } - //! @brief Packed Compare for Equal (DWORDS) (SSE2). - inline void pcmpeqd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPEQD, &dst, &src); - } - - //! @brief Packed Compare for Greater Than (BYTES) (SSE2). - inline void pcmpgtb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PCMPGTB, &dst, &src); - } - //! @brief Packed Compare for Greater Than (BYTES) (SSE2). - inline void pcmpgtb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPGTB, &dst, &src); - } - - //! @brief Packed Compare for Greater Than (WORDS) (SSE2). - inline void pcmpgtw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PCMPGTW, &dst, &src); - } - //! @brief Packed Compare for Greater Than (WORDS) (SSE2). - inline void pcmpgtw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPGTW, &dst, &src); - } - - //! @brief Packed Compare for Greater Than (DWORDS) (SSE2). - inline void pcmpgtd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PCMPGTD, &dst, &src); - } - //! @brief Packed Compare for Greater Than (DWORDS) (SSE2). - inline void pcmpgtd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPGTD, &dst, &src); - } - - //! @brief Packed Signed Integer Word Maximum (SSE2). - inline void pmaxsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMAXSW, &dst, &src); - } - //! @brief Packed Signed Integer Word Maximum (SSE2). - inline void pmaxsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMAXSW, &dst, &src); - } - - //! @brief Packed Unsigned Integer Byte Maximum (SSE2). - inline void pmaxub(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMAXUB, &dst, &src); - } - //! @brief Packed Unsigned Integer Byte Maximum (SSE2). - inline void pmaxub(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMAXUB, &dst, &src); - } - - //! @brief Packed Signed Integer Word Minimum (SSE2). - inline void pminsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMINSW, &dst, &src); - } - //! @brief Packed Signed Integer Word Minimum (SSE2). - inline void pminsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMINSW, &dst, &src); - } - - //! @brief Packed Unsigned Integer Byte Minimum (SSE2). - inline void pminub(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMINUB, &dst, &src); - } - //! @brief Packed Unsigned Integer Byte Minimum (SSE2). - inline void pminub(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMINUB, &dst, &src); - } - - //! @brief Move Byte Mask (SSE2). - inline void pmovmskb(const Register& dst, const XMMRegister& src) - { - emitX86(INST_PMOVMSKB, &dst, &src); - } - - //! @brief Packed Multiply High (SSE2). - inline void pmulhw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMULHW, &dst, &src); - } - //! @brief Packed Multiply High (SSE2). - inline void pmulhw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMULHW, &dst, &src); - } - - //! @brief Packed Multiply High Unsigned (SSE2). - inline void pmulhuw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMULHUW, &dst, &src); - } - //! @brief Packed Multiply High Unsigned (SSE2). - inline void pmulhuw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMULHUW, &dst, &src); - } - - //! @brief Packed Multiply Low (SSE2). - inline void pmullw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMULLW, &dst, &src); - } - //! @brief Packed Multiply Low (SSE2). - inline void pmullw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMULLW, &dst, &src); - } - - //! @brief Packed Multiply to QWORD (SSE2). - inline void pmuludq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMULUDQ, &dst, &src); - } - //! @brief Packed Multiply to QWORD (SSE2). - inline void pmuludq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMULUDQ, &dst, &src); - } - - //! @brief Packed Multiply to QWORD (SSE2). - inline void pmuludq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMULUDQ, &dst, &src); - } - //! @brief Packed Multiply to QWORD (SSE2). - inline void pmuludq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMULUDQ, &dst, &src); - } - - //! @brief Bitwise Logical OR (SSE2). - inline void por(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_POR, &dst, &src); - } - //! @brief Bitwise Logical OR (SSE2). - inline void por(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_POR, &dst, &src); - } - - //! @brief Packed Shift Left Logical (SSE2). - inline void pslld(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSLLD, &dst, &src); - } - //! @brief Packed Shift Left Logical (SSE2). - inline void pslld(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSLLD, &dst, &src); - } - //! @brief Packed Shift Left Logical (SSE2). - inline void pslld(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSLLD, &dst, &src); - } - - //! @brief Packed Shift Left Logical (SSE2). - inline void psllq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSLLQ, &dst, &src); - } - //! @brief Packed Shift Left Logical (SSE2). - inline void psllq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSLLQ, &dst, &src); - } - //! @brief Packed Shift Left Logical (SSE2). - inline void psllq(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSLLQ, &dst, &src); - } - - //! @brief Packed Shift Left Logical (SSE2). - inline void psllw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSLLW, &dst, &src); - } - //! @brief Packed Shift Left Logical (SSE2). - inline void psllw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSLLW, &dst, &src); - } - //! @brief Packed Shift Left Logical (SSE2). - inline void psllw(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSLLW, &dst, &src); - } - - //! @brief Packed Shift Left Logical (SSE2). - inline void pslldq(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSLLDQ, &dst, &src); - } - - //! @brief Packed Shift Right Arithmetic (SSE2). - inline void psrad(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSRAD, &dst, &src); - } - //! @brief Packed Shift Right Arithmetic (SSE2). - inline void psrad(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSRAD, &dst, &src); - } - //! @brief Packed Shift Right Arithmetic (SSE2). - inline void psrad(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRAD, &dst, &src); - } - - //! @brief Packed Shift Right Arithmetic (SSE2). - inline void psraw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSRAW, &dst, &src); - } - //! @brief Packed Shift Right Arithmetic (SSE2). - inline void psraw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSRAW, &dst, &src); - } - //! @brief Packed Shift Right Arithmetic (SSE2). - inline void psraw(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRAW, &dst, &src); - } - - //! @brief Packed Subtract (SSE2). - inline void psubb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSUBB, &dst, &src); - } - //! @brief Packed Subtract (SSE2). - inline void psubb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBB, &dst, &src); - } - - //! @brief Packed Subtract (SSE2). - inline void psubw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSUBW, &dst, &src); - } - //! @brief Packed Subtract (SSE2). - inline void psubw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBW, &dst, &src); - } - - //! @brief Packed Subtract (SSE2). - inline void psubd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSUBD, &dst, &src); - } - //! @brief Packed Subtract (SSE2). - inline void psubd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBD, &dst, &src); - } - - //! @brief Packed Subtract (SSE2). - inline void psubq(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSUBQ, &dst, &src); - } - //! @brief Packed Subtract (SSE2). - inline void psubq(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBQ, &dst, &src); - } - - //! @brief Packed Subtract (SSE2). - inline void psubq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSUBQ, &dst, &src); - } - //! @brief Packed Subtract (SSE2). - inline void psubq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBQ, &dst, &src); - } - - //! @brief Packed Multiply and Add (SSE2). - inline void pmaddwd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMADDWD, &dst, &src); - } - //! @brief Packed Multiply and Add (SSE2). - inline void pmaddwd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMADDWD, &dst, &src); - } - - //! @brief Shuffle Packed DWORDs (SSE2). - inline void pshufd(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PSHUFD, &dst, &src, &imm8); - } - //! @brief Shuffle Packed DWORDs (SSE2). - inline void pshufd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PSHUFD, &dst, &src, &imm8); - } - - //! @brief Shuffle Packed High Words (SSE2). - inline void pshufhw(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PSHUFHW, &dst, &src, &imm8); - } - //! @brief Shuffle Packed High Words (SSE2). - inline void pshufhw(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PSHUFHW, &dst, &src, &imm8); - } - - //! @brief Shuffle Packed Low Words (SSE2). - inline void pshuflw(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PSHUFLW, &dst, &src, &imm8); - } - //! @brief Shuffle Packed Low Words (SSE2). - inline void pshuflw(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PSHUFLW, &dst, &src, &imm8); - } - - //! @brief Packed Shift Right Logical (SSE2). - inline void psrld(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSRLD, &dst, &src); - } - //! @brief Packed Shift Right Logical (SSE2). - inline void psrld(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSRLD, &dst, &src); - } - //! @brief Packed Shift Right Logical (SSE2). - inline void psrld(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRLD, &dst, &src); - } - - //! @brief Packed Shift Right Logical (SSE2). - inline void psrlq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSRLQ, &dst, &src); - } - //! @brief Packed Shift Right Logical (SSE2). - inline void psrlq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSRLQ, &dst, &src); - } - //! @brief Packed Shift Right Logical (SSE2). - inline void psrlq(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRLQ, &dst, &src); - } - - //! @brief DQWord Shift Right Logical (MMX). - inline void psrldq(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRLDQ, &dst, &src); - } - - //! @brief Packed Shift Right Logical (SSE2). - inline void psrlw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSRLW, &dst, &src); - } - //! @brief Packed Shift Right Logical (SSE2). - inline void psrlw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSRLW, &dst, &src); - } - //! @brief Packed Shift Right Logical (SSE2). - inline void psrlw(const XMMRegister& dst, const Immediate& src) - { - emitX86(INST_PSRLW, &dst, &src); - } - - //! @brief Packed Subtract with Saturation (SSE2). - inline void psubsb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSUBSB, &dst, &src); - } - //! @brief Packed Subtract with Saturation (SSE2). - inline void psubsb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBSB, &dst, &src); - } - - //! @brief Packed Subtract with Saturation (SSE2). - inline void psubsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSUBSW, &dst, &src); - } - //! @brief Packed Subtract with Saturation (SSE2). - inline void psubsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBSW, &dst, &src); - } - - //! @brief Packed Subtract with Unsigned Saturation (SSE2). - inline void psubusb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSUBUSB, &dst, &src); - } - //! @brief Packed Subtract with Unsigned Saturation (SSE2). - inline void psubusb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBUSB, &dst, &src); - } - - //! @brief Packed Subtract with Unsigned Saturation (SSE2). - inline void psubusw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSUBUSW, &dst, &src); - } - //! @brief Packed Subtract with Unsigned Saturation (SSE2). - inline void psubusw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSUBUSW, &dst, &src); - } - - //! @brief Unpack High Data (SSE2). - inline void punpckhbw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PUNPCKHBW, &dst, &src); - } - //! @brief Unpack High Data (SSE2). - inline void punpckhbw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKHBW, &dst, &src); - } - - //! @brief Unpack High Data (SSE2). - inline void punpckhwd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PUNPCKHWD, &dst, &src); - } - //! @brief Unpack High Data (SSE2). - inline void punpckhwd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKHWD, &dst, &src); - } - - //! @brief Unpack High Data (SSE2). - inline void punpckhdq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PUNPCKHDQ, &dst, &src); - } - //! @brief Unpack High Data (SSE2). - inline void punpckhdq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKHDQ, &dst, &src); - } - - //! @brief Unpack High Data (SSE2). - inline void punpckhqdq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PUNPCKHQDQ, &dst, &src); - } - //! @brief Unpack High Data (SSE2). - inline void punpckhqdq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKHQDQ, &dst, &src); - } - - //! @brief Unpack Low Data (SSE2). - inline void punpcklbw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PUNPCKLBW, &dst, &src); - } - //! @brief Unpack Low Data (SSE2). - inline void punpcklbw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKLBW, &dst, &src); - } - - //! @brief Unpack Low Data (SSE2). - inline void punpcklwd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PUNPCKLWD, &dst, &src); - } - //! @brief Unpack Low Data (SSE2). - inline void punpcklwd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKLWD, &dst, &src); - } - - //! @brief Unpack Low Data (SSE2). - inline void punpckldq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PUNPCKLDQ, &dst, &src); - } - //! @brief Unpack Low Data (SSE2). - inline void punpckldq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKLDQ, &dst, &src); - } - - //! @brief Unpack Low Data (SSE2). - inline void punpcklqdq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PUNPCKLQDQ, &dst, &src); - } - //! @brief Unpack Low Data (SSE2). - inline void punpcklqdq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PUNPCKLQDQ, &dst, &src); - } - - //! @brief Bitwise Exclusive OR (SSE2). - inline void pxor(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PXOR, &dst, &src); - } - //! @brief Bitwise Exclusive OR (SSE2). - inline void pxor(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PXOR, &dst, &src); - } - - //! @brief Shuffle DP-FP (SSE2). - inline void shufpd(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_SHUFPD, &dst, &src, &imm8); - } - //! @brief Shuffle DP-FP (SSE2). - inline void shufpd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_SHUFPD, &dst, &src, &imm8); - } - - //! @brief Compute Square Roots of Packed DP-FP Values (SSE2). - inline void sqrtpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_SQRTPD, &dst, &src); - } - //! @brief Compute Square Roots of Packed DP-FP Values (SSE2). - inline void sqrtpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_SQRTPD, &dst, &src); - } - - //! @brief Compute Square Root of Scalar DP-FP Value (SSE2). - inline void sqrtsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_SQRTSD, &dst, &src); - } - //! @brief Compute Square Root of Scalar DP-FP Value (SSE2). - inline void sqrtsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_SQRTSD, &dst, &src); - } - - //! @brief Packed DP-FP Subtract (SSE2). - inline void subpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_SUBPD, &dst, &src); - } - //! @brief Packed DP-FP Subtract (SSE2). - inline void subpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_SUBPD, &dst, &src); - } - - //! @brief Scalar DP-FP Subtract (SSE2). - inline void subsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_SUBSD, &dst, &src); - } - //! @brief Scalar DP-FP Subtract (SSE2). - inline void subsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_SUBSD, &dst, &src); - } - - //! @brief Scalar Unordered DP-FP Compare and Set EFLAGS (SSE2). - inline void ucomisd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_UCOMISD, &dst, &src); - } - //! @brief Scalar Unordered DP-FP Compare and Set EFLAGS (SSE2). - inline void ucomisd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_UCOMISD, &dst, &src); - } - - //! @brief Unpack and Interleave High Packed Double-Precision FP Values (SSE2). - inline void unpckhpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_UNPCKHPD, &dst, &src); - } - //! @brief Unpack and Interleave High Packed Double-Precision FP Values (SSE2). - inline void unpckhpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_UNPCKHPD, &dst, &src); - } - - //! @brief Unpack and Interleave Low Packed Double-Precision FP Values (SSE2). - inline void unpcklpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_UNPCKLPD, &dst, &src); - } - //! @brief Unpack and Interleave Low Packed Double-Precision FP Values (SSE2). - inline void unpcklpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_UNPCKLPD, &dst, &src); - } - - //! @brief Bit-wise Logical OR for DP-FP Data (SSE2). - inline void xorpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_XORPD, &dst, &src); - } - //! @brief Bit-wise Logical OR for DP-FP Data (SSE2). - inline void xorpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_XORPD, &dst, &src); - } - - // ------------------------------------------------------------------------- - // [SSE3] - // ------------------------------------------------------------------------- - - //! @brief Packed DP-FP Add/Subtract (SSE3). - inline void addsubpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ADDSUBPD, &dst, &src); - } - //! @brief Packed DP-FP Add/Subtract (SSE3). - inline void addsubpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ADDSUBPD, &dst, &src); - } - - //! @brief Packed SP-FP Add/Subtract (SSE3). - inline void addsubps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_ADDSUBPS, &dst, &src); - } - //! @brief Packed SP-FP Add/Subtract (SSE3). - inline void addsubps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_ADDSUBPS, &dst, &src); - } - - //! @brief Store Integer with Truncation (SSE3). - inline void fisttp(const Mem& dst) - { - emitX86(INST_FISTTP, &dst); - } - - //! @brief Packed DP-FP Horizontal Add (SSE3). - inline void haddpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_HADDPD, &dst, &src); - } - //! @brief Packed DP-FP Horizontal Add (SSE3). - inline void haddpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_HADDPD, &dst, &src); - } - - //! @brief Packed SP-FP Horizontal Add (SSE3). - inline void haddps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_HADDPS, &dst, &src); - } - //! @brief Packed SP-FP Horizontal Add (SSE3). - inline void haddps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_HADDPS, &dst, &src); - } - - //! @brief Packed DP-FP Horizontal Subtract (SSE3). - inline void hsubpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_HSUBPD, &dst, &src); - } - //! @brief Packed DP-FP Horizontal Subtract (SSE3). - inline void hsubpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_HSUBPD, &dst, &src); - } - - //! @brief Packed SP-FP Horizontal Subtract (SSE3). - inline void hsubps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_HSUBPS, &dst, &src); - } - //! @brief Packed SP-FP Horizontal Subtract (SSE3). - inline void hsubps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_HSUBPS, &dst, &src); - } - - //! @brief Load Unaligned Integer 128 Bits (SSE3). - inline void lddqu(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_LDDQU, &dst, &src); - } - - //! @brief Set Up Monitor Address (SSE3). - inline void monitor() - { - emitX86(INST_MONITOR); - } - - //! @brief Move One DP-FP and Duplicate (SSE3). - inline void movddup(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVDDUP, &dst, &src); - } - //! @brief Move One DP-FP and Duplicate (SSE3). - inline void movddup(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVDDUP, &dst, &src); - } - - //! @brief Move Packed SP-FP High and Duplicate (SSE3). - inline void movshdup(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVSHDUP, &dst, &src); - } - //! @brief Move Packed SP-FP High and Duplicate (SSE3). - inline void movshdup(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVSHDUP, &dst, &src); - } - - //! @brief Move Packed SP-FP Low and Duplicate (SSE3). - inline void movsldup(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_MOVSLDUP, &dst, &src); - } - //! @brief Move Packed SP-FP Low and Duplicate (SSE3). - inline void movsldup(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVSLDUP, &dst, &src); - } - - //! @brief Monitor Wait (SSE3). - inline void mwait() - { - emitX86(INST_MWAIT); - } - - // ------------------------------------------------------------------------- - // [SSSE3] - // ------------------------------------------------------------------------- - - //! @brief Packed SIGN (SSSE3). - inline void psignb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSIGNB, &dst, &src); - } - //! @brief Packed SIGN (SSSE3). - inline void psignb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSIGNB, &dst, &src); - } - - //! @brief Packed SIGN (SSSE3). - inline void psignb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSIGNB, &dst, &src); - } - //! @brief Packed SIGN (SSSE3). - inline void psignb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSIGNB, &dst, &src); - } - - //! @brief Packed SIGN (SSSE3). - inline void psignw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSIGNW, &dst, &src); - } - //! @brief Packed SIGN (SSSE3). - inline void psignw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSIGNW, &dst, &src); - } - - //! @brief Packed SIGN (SSSE3). - inline void psignw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSIGNW, &dst, &src); - } - //! @brief Packed SIGN (SSSE3). - inline void psignw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSIGNW, &dst, &src); - } - - //! @brief Packed SIGN (SSSE3). - inline void psignd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSIGND, &dst, &src); - } - //! @brief Packed SIGN (SSSE3). - inline void psignd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSIGND, &dst, &src); - } - - //! @brief Packed SIGN (SSSE3). - inline void psignd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSIGND, &dst, &src); - } - //! @brief Packed SIGN (SSSE3). - inline void psignd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSIGND, &dst, &src); - } - - //! @brief Packed Horizontal Add (SSSE3). - inline void phaddw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PHADDW, &dst, &src); - } - //! @brief Packed Horizontal Add (SSSE3). - inline void phaddw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PHADDW, &dst, &src); - } - - //! @brief Packed Horizontal Add (SSSE3). - inline void phaddw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PHADDW, &dst, &src); - } - //! @brief Packed Horizontal Add (SSSE3). - inline void phaddw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PHADDW, &dst, &src); - } - - //! @brief Packed Horizontal Add (SSSE3). - inline void phaddd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PHADDD, &dst, &src); - } - //! @brief Packed Horizontal Add (SSSE3). - inline void phaddd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PHADDD, &dst, &src); - } - - //! @brief Packed Horizontal Add (SSSE3). - inline void phaddd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PHADDD, &dst, &src); - } - //! @brief Packed Horizontal Add (SSSE3). - inline void phaddd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PHADDD, &dst, &src); - } - - //! @brief Packed Horizontal Add and Saturate (SSSE3). - inline void phaddsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PHADDSW, &dst, &src); - } - //! @brief Packed Horizontal Add and Saturate (SSSE3). - inline void phaddsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PHADDSW, &dst, &src); - } - - //! @brief Packed Horizontal Add and Saturate (SSSE3). - inline void phaddsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PHADDSW, &dst, &src); - } - //! @brief Packed Horizontal Add and Saturate (SSSE3). - inline void phaddsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PHADDSW, &dst, &src); - } - - //! @brief Packed Horizontal Subtract (SSSE3). - inline void phsubw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PHSUBW, &dst, &src); - } - //! @brief Packed Horizontal Subtract (SSSE3). - inline void phsubw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PHSUBW, &dst, &src); - } - - //! @brief Packed Horizontal Subtract (SSSE3). - inline void phsubw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PHSUBW, &dst, &src); - } - //! @brief Packed Horizontal Subtract (SSSE3). - inline void phsubw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PHSUBW, &dst, &src); - } - - //! @brief Packed Horizontal Subtract (SSSE3). - inline void phsubd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PHSUBD, &dst, &src); - } - //! @brief Packed Horizontal Subtract (SSSE3). - inline void phsubd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PHSUBD, &dst, &src); - } - - //! @brief Packed Horizontal Subtract (SSSE3). - inline void phsubd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PHSUBD, &dst, &src); - } - //! @brief Packed Horizontal Subtract (SSSE3). - inline void phsubd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PHSUBD, &dst, &src); - } - - //! @brief Packed Horizontal Subtract and Saturate (SSSE3). - inline void phsubsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PHSUBSW, &dst, &src); - } - //! @brief Packed Horizontal Subtract and Saturate (SSSE3). - inline void phsubsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PHSUBSW, &dst, &src); - } - - //! @brief Packed Horizontal Subtract and Saturate (SSSE3). - inline void phsubsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PHSUBSW, &dst, &src); - } - //! @brief Packed Horizontal Subtract and Saturate (SSSE3). - inline void phsubsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PHSUBSW, &dst, &src); - } - - //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3). - inline void pmaddubsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMADDUBSW, &dst, &src); - } - //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3). - inline void pmaddubsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMADDUBSW, &dst, &src); - } - - //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3). - inline void pmaddubsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMADDUBSW, &dst, &src); - } - //! @brief Multiply and Add Packed Signed and Unsigned Bytes (SSSE3). - inline void pmaddubsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMADDUBSW, &dst, &src); - } - - //! @brief Packed Absolute Value (SSSE3). - inline void pabsb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PABSB, &dst, &src); - } - //! @brief Packed Absolute Value (SSSE3). - inline void pabsb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PABSB, &dst, &src); - } - - //! @brief Packed Absolute Value (SSSE3). - inline void pabsb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PABSB, &dst, &src); - } - //! @brief Packed Absolute Value (SSSE3). - inline void pabsb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PABSB, &dst, &src); - } - - //! @brief Packed Absolute Value (SSSE3). - inline void pabsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PABSW, &dst, &src); - } - //! @brief Packed Absolute Value (SSSE3). - inline void pabsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PABSW, &dst, &src); - } - - //! @brief Packed Absolute Value (SSSE3). - inline void pabsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PABSW, &dst, &src); - } - //! @brief Packed Absolute Value (SSSE3). - inline void pabsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PABSW, &dst, &src); - } - - //! @brief Packed Absolute Value (SSSE3). - inline void pabsd(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PABSD, &dst, &src); - } - //! @brief Packed Absolute Value (SSSE3). - inline void pabsd(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PABSD, &dst, &src); - } - - //! @brief Packed Absolute Value (SSSE3). - inline void pabsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PABSD, &dst, &src); - } - //! @brief Packed Absolute Value (SSSE3). - inline void pabsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PABSD, &dst, &src); - } - - //! @brief Packed Multiply High with Round and Scale (SSSE3). - inline void pmulhrsw(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PMULHRSW, &dst, &src); - } - //! @brief Packed Multiply High with Round and Scale (SSSE3). - inline void pmulhrsw(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PMULHRSW, &dst, &src); - } - - //! @brief Packed Multiply High with Round and Scale (SSSE3). - inline void pmulhrsw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMULHRSW, &dst, &src); - } - //! @brief Packed Multiply High with Round and Scale (SSSE3). - inline void pmulhrsw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMULHRSW, &dst, &src); - } - - //! @brief Packed Shuffle Bytes (SSSE3). - inline void pshufb(const MMRegister& dst, const MMRegister& src) - { - emitX86(INST_PSHUFB, &dst, &src); - } - //! @brief Packed Shuffle Bytes (SSSE3). - inline void pshufb(const MMRegister& dst, const Mem& src) - { - emitX86(INST_PSHUFB, &dst, &src); - } - - //! @brief Packed Shuffle Bytes (SSSE3). - inline void pshufb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PSHUFB, &dst, &src); - } - //! @brief Packed Shuffle Bytes (SSSE3). - inline void pshufb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PSHUFB, &dst, &src); - } - - //! @brief Packed Shuffle Bytes (SSSE3). - inline void palignr(const MMRegister& dst, const MMRegister& src, const Immediate& imm8) - { - emitX86(INST_PALIGNR, &dst, &src, &imm8); - } - //! @brief Packed Shuffle Bytes (SSSE3). - inline void palignr(const MMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PALIGNR, &dst, &src, &imm8); - } - - //! @brief Packed Shuffle Bytes (SSSE3). - inline void palignr(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PALIGNR, &dst, &src, &imm8); - } - //! @brief Packed Shuffle Bytes (SSSE3). - inline void palignr(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PALIGNR, &dst, &src, &imm8); - } - - // ------------------------------------------------------------------------- - // [SSE4.1] - // ------------------------------------------------------------------------- - - //! @brief Blend Packed DP-FP Values (SSE4.1). - inline void blendpd(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_BLENDPD, &dst, &src, &imm8); - } - //! @brief Blend Packed DP-FP Values (SSE4.1). - inline void blendpd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_BLENDPD, &dst, &src, &imm8); - } - - //! @brief Blend Packed SP-FP Values (SSE4.1). - inline void blendps(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_BLENDPS, &dst, &src, &imm8); - } - //! @brief Blend Packed SP-FP Values (SSE4.1). - inline void blendps(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_BLENDPS, &dst, &src, &imm8); - } - - //! @brief Variable Blend Packed DP-FP Values (SSE4.1). - inline void blendvpd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_BLENDVPD, &dst, &src); - } - //! @brief Variable Blend Packed DP-FP Values (SSE4.1). - inline void blendvpd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_BLENDVPD, &dst, &src); - } - - //! @brief Variable Blend Packed SP-FP Values (SSE4.1). - inline void blendvps(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_BLENDVPS, &dst, &src); - } - //! @brief Variable Blend Packed SP-FP Values (SSE4.1). - inline void blendvps(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_BLENDVPS, &dst, &src); - } - - //! @brief Dot Product of Packed DP-FP Values (SSE4.1). - inline void dppd(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_DPPD, &dst, &src, &imm8); - } - //! @brief Dot Product of Packed DP-FP Values (SSE4.1). - inline void dppd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_DPPD, &dst, &src, &imm8); - } - - //! @brief Dot Product of Packed SP-FP Values (SSE4.1). - inline void dpps(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_DPPS, &dst, &src, &imm8); - } - //! @brief Dot Product of Packed SP-FP Values (SSE4.1). - inline void dpps(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_DPPS, &dst, &src, &imm8); - } - - //! @brief Extract Packed SP-FP Value @brief (SSE4.1). - inline void extractps(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_EXTRACTPS, &dst, &src, &imm8); - } - //! @brief Extract Packed SP-FP Value @brief (SSE4.1). - inline void extractps(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_EXTRACTPS, &dst, &src, &imm8); - } - - //! @brief Load Double Quadword Non-Temporal Aligned Hint (SSE4.1). - inline void movntdqa(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_MOVNTDQA, &dst, &src); - } - - //! @brief Compute Multiple Packed Sums of Absolute Difference (SSE4.1). - inline void mpsadbw(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_MPSADBW, &dst, &src, &imm8); - } - //! @brief Compute Multiple Packed Sums of Absolute Difference (SSE4.1). - inline void mpsadbw(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_MPSADBW, &dst, &src, &imm8); - } - - //! @brief Pack with Unsigned Saturation (SSE4.1). - inline void packusdw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PACKUSDW, &dst, &src); - } - //! @brief Pack with Unsigned Saturation (SSE4.1). - inline void packusdw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PACKUSDW, &dst, &src); - } - - //! @brief Variable Blend Packed Bytes (SSE4.1). - inline void pblendvb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PBLENDVB, &dst, &src); - } - //! @brief Variable Blend Packed Bytes (SSE4.1). - inline void pblendvb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PBLENDVB, &dst, &src); - } - - //! @brief Blend Packed Words (SSE4.1). - inline void pblendw(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PBLENDW, &dst, &src, &imm8); - } - //! @brief Blend Packed Words (SSE4.1). - inline void pblendw(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PBLENDW, &dst, &src, &imm8); - } - - //! @brief Compare Packed Qword Data for Equal (SSE4.1). - inline void pcmpeqq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PCMPEQQ, &dst, &src); - } - //! @brief Compare Packed Qword Data for Equal (SSE4.1). - inline void pcmpeqq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPEQQ, &dst, &src); - } - - //! @brief Extract Byte (SSE4.1). - inline void pextrb(const Register& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRB, &dst, &src, &imm8); - } - //! @brief Extract Byte (SSE4.1). - inline void pextrb(const Mem& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRB, &dst, &src, &imm8); - } - - //! @brief Extract Dword (SSE4.1). - inline void pextrd(const Register& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRD, &dst, &src, &imm8); - } - //! @brief Extract Dword (SSE4.1). - inline void pextrd(const Mem& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRD, &dst, &src, &imm8); - } - - //! @brief Extract Dword (SSE4.1). - inline void pextrq(const Register& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRQ, &dst, &src, &imm8); - } - //! @brief Extract Dword (SSE4.1). - inline void pextrq(const Mem& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRQ, &dst, &src, &imm8); - } - - //! @brief Extract Word (SSE4.1). - inline void pextrw(const Register& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRW, &dst, &src, &imm8); - } - //! @brief Extract Word (SSE4.1). - inline void pextrw(const Mem& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PEXTRW, &dst, &src, &imm8); - } - - //! @brief Packed Horizontal Word Minimum (SSE4.1). - inline void phminposuw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PHMINPOSUW, &dst, &src); - } - //! @brief Packed Horizontal Word Minimum (SSE4.1). - inline void phminposuw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PHMINPOSUW, &dst, &src); - } - - //! @brief Insert Byte (SSE4.1). - inline void pinsrb(const XMMRegister& dst, const Register& src, const Immediate& imm8) - { - emitX86(INST_PINSRB, &dst, &src, &imm8); - } - //! @brief Insert Byte (SSE4.1). - inline void pinsrb(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PINSRB, &dst, &src, &imm8); - } - - //! @brief Insert Dword (SSE4.1). - inline void pinsrd(const XMMRegister& dst, const Register& src, const Immediate& imm8) - { - emitX86(INST_PINSRD, &dst, &src, &imm8); - } - //! @brief Insert Dword (SSE4.1). - inline void pinsrd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PINSRD, &dst, &src, &imm8); - } - - //! @brief Insert Dword (SSE4.1). - inline void pinsrq(const XMMRegister& dst, const Register& src, const Immediate& imm8) - { - emitX86(INST_PINSRQ, &dst, &src, &imm8); - } - //! @brief Insert Dword (SSE4.1). - inline void pinsrq(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PINSRQ, &dst, &src, &imm8); - } - - //! @brief Insert Word (SSE2). - inline void pinsrw(const XMMRegister& dst, const Register& src, const Immediate& imm8) - { - emitX86(INST_PINSRW, &dst, &src, &imm8); - } - //! @brief Insert Word (SSE2). - inline void pinsrw(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PINSRW, &dst, &src, &imm8); - } - - //! @brief Maximum of Packed Word Integers (SSE4.1). - inline void pmaxuw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMAXUW, &dst, &src); - } - //! @brief Maximum of Packed Word Integers (SSE4.1). - inline void pmaxuw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMAXUW, &dst, &src); - } - - //! @brief Maximum of Packed Signed Byte Integers (SSE4.1). - inline void pmaxsb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMAXSB, &dst, &src); - } - //! @brief Maximum of Packed Signed Byte Integers (SSE4.1). - inline void pmaxsb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMAXSB, &dst, &src); - } - - //! @brief Maximum of Packed Signed Dword Integers (SSE4.1). - inline void pmaxsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMAXSD, &dst, &src); - } - //! @brief Maximum of Packed Signed Dword Integers (SSE4.1). - inline void pmaxsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMAXSD, &dst, &src); - } - - //! @brief Maximum of Packed Unsigned Dword Integers (SSE4.1). - inline void pmaxud(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMAXUD, &dst, &src); - } - //! @brief Maximum of Packed Unsigned Dword Integers (SSE4.1). - inline void pmaxud(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMAXUD, &dst, &src); - } - - //! @brief Minimum of Packed Signed Byte Integers (SSE4.1). - inline void pminsb(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMINSB, &dst, &src); - } - //! @brief Minimum of Packed Signed Byte Integers (SSE4.1). - inline void pminsb(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMINSB, &dst, &src); - } - - //! @brief Minimum of Packed Word Integers (SSE4.1). - inline void pminuw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMINUW, &dst, &src); - } - //! @brief Minimum of Packed Word Integers (SSE4.1). - inline void pminuw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMINUW, &dst, &src); - } - - //! @brief Minimum of Packed Dword Integers (SSE4.1). - inline void pminud(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMINUD, &dst, &src); - } - //! @brief Minimum of Packed Dword Integers (SSE4.1). - inline void pminud(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMINUD, &dst, &src); - } - - //! @brief Minimum of Packed Dword Integers (SSE4.1). - inline void pminsd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMINSD, &dst, &src); - } - //! @brief Minimum of Packed Dword Integers (SSE4.1). - inline void pminsd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMINSD, &dst, &src); - } - - //! @brief Packed Move with Sign Extend (SSE4.1). - inline void pmovsxbw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVSXBW, &dst, &src); - } - //! @brief Packed Move with Sign Extend (SSE4.1). - inline void pmovsxbw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVSXBW, &dst, &src); - } - - //! @brief Packed Move with Sign Extend (SSE4.1). - inline void pmovsxbd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVSXBD, &dst, &src); - } - //! @brief Packed Move with Sign Extend (SSE4.1). - inline void pmovsxbd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVSXBD, &dst, &src); - } - - //! @brief Packed Move with Sign Extend (SSE4.1). - inline void pmovsxbq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVSXBQ, &dst, &src); - } - //! @brief Packed Move with Sign Extend (SSE4.1). - inline void pmovsxbq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVSXBQ, &dst, &src); - } - - //! @brief Packed Move with Sign Extend (SSE4.1). - inline void pmovsxwd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVSXWD, &dst, &src); - } - //! @brief Packed Move with Sign Extend (SSE4.1). - inline void pmovsxwd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVSXWD, &dst, &src); - } - - //! @brief (SSE4.1). - inline void pmovsxwq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVSXWQ, &dst, &src); - } - //! @brief (SSE4.1). - inline void pmovsxwq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVSXWQ, &dst, &src); - } - - //! @brief (SSE4.1). - inline void pmovsxdq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVSXDQ, &dst, &src); - } - //! @brief (SSE4.1). - inline void pmovsxdq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVSXDQ, &dst, &src); - } - - //! @brief Packed Move with Zero Extend (SSE4.1). - inline void pmovzxbw(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVZXBW, &dst, &src); - } - //! @brief Packed Move with Zero Extend (SSE4.1). - inline void pmovzxbw(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVZXBW, &dst, &src); - } - - //! @brief Packed Move with Zero Extend (SSE4.1). - inline void pmovzxbd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVZXBD, &dst, &src); - } - //! @brief Packed Move with Zero Extend (SSE4.1). - inline void pmovzxbd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVZXBD, &dst, &src); - } - - //! @brief Packed Move with Zero Extend (SSE4.1). - inline void pmovzxbq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVZXBQ, &dst, &src); - } - //! @brief Packed Move with Zero Extend (SSE4.1). - inline void pmovzxbq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVZXBQ, &dst, &src); - } - - //! @brief Packed Move with Zero Extend (SSE4.1). - inline void pmovzxwd(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVZXWD, &dst, &src); - } - //! @brief Packed Move with Zero Extend (SSE4.1). - inline void pmovzxwd(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVZXWD, &dst, &src); - } - - //! @brief (SSE4.1). - inline void pmovzxwq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVZXWQ, &dst, &src); - } - //! @brief (SSE4.1). - inline void pmovzxwq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVZXWQ, &dst, &src); - } - - //! @brief (SSE4.1). - inline void pmovzxdq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMOVZXDQ, &dst, &src); - } - //! @brief (SSE4.1). - inline void pmovzxdq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMOVZXDQ, &dst, &src); - } - - //! @brief Multiply Packed Signed Dword Integers (SSE4.1). - inline void pmuldq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMULDQ, &dst, &src); - } - //! @brief Multiply Packed Signed Dword Integers (SSE4.1). - inline void pmuldq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMULDQ, &dst, &src); - } - - //! @brief Multiply Packed Signed Integers and Store Low Result (SSE4.1). - inline void pmulld(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PMULLD, &dst, &src); - } - //! @brief Multiply Packed Signed Integers and Store Low Result (SSE4.1). - inline void pmulld(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PMULLD, &dst, &src); - } - - //! @brief Logical Compare (SSE4.1). - inline void ptest(const XMMRegister& op1, const XMMRegister& op2) - { - emitX86(INST_PTEST, &op1, &op2); - } - //! @brief Logical Compare (SSE4.1). - inline void ptest(const XMMRegister& op1, const Mem& op2) - { - emitX86(INST_PTEST, &op1, &op2); - } - - //! Round Packed SP-FP Values @brief (SSE4.1). - inline void roundps(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_ROUNDPS, &dst, &src, &imm8); - } - //! Round Packed SP-FP Values @brief (SSE4.1). - inline void roundps(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_ROUNDPS, &dst, &src, &imm8); - } - - //! @brief Round Scalar SP-FP Values (SSE4.1). - inline void roundss(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_ROUNDSS, &dst, &src, &imm8); - } - //! @brief Round Scalar SP-FP Values (SSE4.1). - inline void roundss(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_ROUNDSS, &dst, &src, &imm8); - } - - //! @brief Round Packed DP-FP Values (SSE4.1). - inline void roundpd(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_ROUNDPD, &dst, &src, &imm8); - } - //! @brief Round Packed DP-FP Values (SSE4.1). - inline void roundpd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_ROUNDPD, &dst, &src, &imm8); - } - - //! @brief Round Scalar DP-FP Values (SSE4.1). - inline void roundsd(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_ROUNDSD, &dst, &src, &imm8); - } - //! @brief Round Scalar DP-FP Values (SSE4.1). - inline void roundsd(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_ROUNDSD, &dst, &src, &imm8); - } - - // ------------------------------------------------------------------------- - // [SSE4.2] - // ------------------------------------------------------------------------- - - //! @brief Accumulate CRC32 Value (polynomial 0x11EDC6F41) (SSE4.2). - inline void crc32(const Register& dst, const Register& src) - { - ASMJIT_ASSERT(dst.isRegType(REG_GPD) || dst.isRegType(REG_GPQ)); - emitX86(INST_CRC32, &dst, &src); - } - //! @brief Accumulate CRC32 Value (polynomial 0x11EDC6F41) (SSE4.2). - inline void crc32(const Register& dst, const Mem& src) - { - ASMJIT_ASSERT(dst.isRegType(REG_GPD) || dst.isRegType(REG_GPQ)); - emitX86(INST_CRC32, &dst, &src); - } - - //! @brief Packed Compare Explicit Length Strings, Return Index (SSE4.2). - inline void pcmpestri(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PCMPESTRI, &dst, &src, &imm8); - } - //! @brief Packed Compare Explicit Length Strings, Return Index (SSE4.2). - inline void pcmpestri(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PCMPESTRI, &dst, &src, &imm8); - } - - //! @brief Packed Compare Explicit Length Strings, Return Mask (SSE4.2). - inline void pcmpestrm(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PCMPESTRM, &dst, &src, &imm8); - } - //! @brief Packed Compare Explicit Length Strings, Return Mask (SSE4.2). - inline void pcmpestrm(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PCMPESTRM, &dst, &src, &imm8); - } - - //! @brief Packed Compare Implicit Length Strings, Return Index (SSE4.2). - inline void pcmpistri(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PCMPISTRI, &dst, &src, &imm8); - } - //! @brief Packed Compare Implicit Length Strings, Return Index (SSE4.2). - inline void pcmpistri(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PCMPISTRI, &dst, &src, &imm8); - } - - //! @brief Packed Compare Implicit Length Strings, Return Mask (SSE4.2). - inline void pcmpistrm(const XMMRegister& dst, const XMMRegister& src, const Immediate& imm8) - { - emitX86(INST_PCMPISTRM, &dst, &src, &imm8); - } - //! @brief Packed Compare Implicit Length Strings, Return Mask (SSE4.2). - inline void pcmpistrm(const XMMRegister& dst, const Mem& src, const Immediate& imm8) - { - emitX86(INST_PCMPISTRM, &dst, &src, &imm8); - } - - //! @brief Compare Packed Data for Greater Than (SSE4.2). - inline void pcmpgtq(const XMMRegister& dst, const XMMRegister& src) - { - emitX86(INST_PCMPGTQ, &dst, &src); - } - //! @brief Compare Packed Data for Greater Than (SSE4.2). - inline void pcmpgtq(const XMMRegister& dst, const Mem& src) - { - emitX86(INST_PCMPGTQ, &dst, &src); - } - - //! @brief Return the Count of Number of Bits Set to 1 (SSE4.2). - inline void popcnt(const Register& dst, const Register& src) - { - ASMJIT_ASSERT(!dst.isRegType(REG_GPB)); - ASMJIT_ASSERT(src.type() == dst.type()); - emitX86(INST_POPCNT, &dst, &src); - } - //! @brief Return the Count of Number of Bits Set to 1 (SSE4.2). - inline void popcnt(const Register& dst, const Mem& src) - { - ASMJIT_ASSERT(!dst.isRegType(REG_GPB)); - emitX86(INST_POPCNT, &dst, &src); - } - - // ------------------------------------------------------------------------- - // [AMD only] - // ------------------------------------------------------------------------- - - //! @brief Prefetch (3dNow - Amd). - //! - //! Loads the entire 64-byte aligned memory sequence containing the - //! specified memory address into the L1 data cache. The position of - //! the specified memory address within the 64-byte cache line is - //! irrelevant. If a cache hit occurs, or if a memory fault is detected, - //! no bus cycle is initiated and the instruction is treated as a NOP. - inline void amd_prefetch(const Mem& mem) - { - emitX86(INST_AMD_PREFETCH, &mem); - } - - //! @brief Prefetch and set cache to modified (3dNow - Amd). - //! - //! The PREFETCHW instruction loads the prefetched line and sets the - //! cache-line state to Modified, in anticipation of subsequent data - //! writes to the line. The PREFETCH instruction, by contrast, typically - //! sets the cache-line state to Exclusive (depending on the hardware - //! implementation). - inline void amd_prefetchw(const Mem& mem) - { - emitX86(INST_AMD_PREFETCHW, &mem); - } - - // ------------------------------------------------------------------------- - // [Intel only] - // ------------------------------------------------------------------------- - - //! @brief Move Data After Swapping Bytes (SSE3 - Intel Atom). - inline void movbe(const Register& dst, const Mem& src) - { - ASMJIT_ASSERT(!dst.isRegType(REG_GPB)); - emitX86(INST_MOVBE, &dst, &src); - } - - //! @brief Move Data After Swapping Bytes (SSE3 - Intel Atom). - inline void movbe(const Mem& dst, const Register& src) - { - ASMJIT_ASSERT(!src.isRegType(REG_GPB)); - emitX86(INST_MOVBE, &dst, &src); - } - - // ------------------------------------------------------------------------- - // [Rep] - // ------------------------------------------------------------------------- - - inline void rep_lodsb() { emitX86(INST_REP_LODSB); } - inline void rep_lodsd() { emitX86(INST_REP_LODSD); } -#if defined(ASMJIT_X64) - inline void rep_lodsq() { emitX86(INST_REP_LODSQ); } -#endif // ASMJIT_X64 - inline void rep_lodsw() { emitX86(INST_REP_LODSW); } - - inline void rep_movsb() { emitX86(INST_REP_MOVSB); } - inline void rep_movsd() { emitX86(INST_REP_MOVSD); } -#if defined(ASMJIT_X64) - inline void rep_movsq() { emitX86(INST_REP_MOVSQ); } -#endif // ASMJIT_X64 - inline void rep_movsw() { emitX86(INST_REP_MOVSW); } - - inline void rep_stosb() { emitX86(INST_REP_STOSB); } - inline void rep_stosd() { emitX86(INST_REP_STOSD); } -#if defined(ASMJIT_X64) - inline void rep_stosq() { emitX86(INST_REP_STOSQ); } -#endif // ASMJIT_X64 - inline void rep_stosw() { emitX86(INST_REP_STOSW); } - - inline void repe_cmpsb() { emitX86(INST_REPE_CMPSB); } - inline void repe_cmpsd() { emitX86(INST_REPE_CMPSD); } -#if defined(ASMJIT_X64) - inline void repe_cmpsq() { emitX86(INST_REPE_CMPSQ); } -#endif // ASMJIT_X64 - inline void repe_cmpsw() { emitX86(INST_REPE_CMPSW); } - - inline void repe_scasb() { emitX86(INST_REPE_SCASB); } - inline void repe_scasd() { emitX86(INST_REPE_SCASD); } -#if defined(ASMJIT_X64) - inline void repe_scasq() { emitX86(INST_REPE_SCASQ); } -#endif // ASMJIT_X64 - inline void repe_scasw() { emitX86(INST_REPE_SCASW); } - - inline void repne_cmpsb() { emitX86(INST_REPNE_CMPSB); } - inline void repne_cmpsd() { emitX86(INST_REPNE_CMPSD); } -#if defined(ASMJIT_X64) - inline void repne_cmpsq() { emitX86(INST_REPNE_CMPSQ); } -#endif // ASMJIT_X64 - inline void repne_cmpsw() { emitX86(INST_REPNE_CMPSW); } - - inline void repne_scasb() { emitX86(INST_REPNE_SCASB); } - inline void repne_scasd() { emitX86(INST_REPNE_SCASD); } -#if defined(ASMJIT_X64) - inline void repne_scasq() { emitX86(INST_REPNE_SCASQ); } -#endif // ASMJIT_X64 - inline void repne_scasw() { emitX86(INST_REPNE_SCASW); } -}; - -// ============================================================================ -// [AsmJit::Serializer] -// ============================================================================ - -//! @brief Assembler instruction serializer. -//! -//! @brief Serializer functionality is implemented in @c SerializerCore class -//! and serializer intrinsics are implemented in @c SerializerIntrinsics class. -//! -//! Always use this class and never use @c SerializerCore or @c SerializerIntrinsics -//! classes directly. -struct ASMJIT_API Serializer : public SerializerIntrinsics -{ - Serializer() ASMJIT_NOTHROW; - virtual ~Serializer() ASMJIT_NOTHROW; -}; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_SERIALIZERX86X64_H diff --git a/src/thirdparty/dyndetours/AsmJit/Util.h b/src/thirdparty/dyndetours/AsmJit/Util.h deleted file mode 100644 index 551871c26..000000000 --- a/src/thirdparty/dyndetours/AsmJit/Util.h +++ /dev/null @@ -1,784 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_UTIL_H -#define _ASMJIT_UTIL_H - -// [Dependencies] -#include "Build.h" - -#include -#include - -namespace AsmJit { - -//! @addtogroup AsmJit_Util -//! @{ - -// ============================================================================ -// [AsmJit::Macros] -// ============================================================================ - -// Skip documenting this. -#if !defined(ASMJIT_NODOC) -struct ASMJIT_HIDDEN _DontInitialize {}; -struct ASMJIT_HIDDEN _Initialize {}; -#endif // !ASMJIT_NODOC - -// ============================================================================ -// [AsmJit::function_cast<>] -// ============================================================================ - -//! @brief Cast used to cast pointer to function. It's like reinterpret_cast<>, -//! but uses internally C style cast to work with MinGW. -//! -//! If you are using single compiler and @c reinterpret_cast<> works for you, -//! there is no reason to use @c AsmJit::function_cast<>. If you are writing -//! crossplatform software with various compiler support, consider using -//! @c AsmJit::function_cast<> instead of @c @c reinterpret_cast<>. -template -static inline T function_cast(Z* p) ASMJIT_NOTHROW { return (T)p; } - -// ============================================================================ -// [AsmJit::isIntX] -// ============================================================================ - -//! @brief Returns @c true if a given integer @a x is signed 8 bit integer -static inline bool isInt8(SysInt x) ASMJIT_NOTHROW { return x >= -128 && x <= 127; } -//! @brief Returns @c true if a given integer @a x is unsigned 8 bit integer -static inline bool isUInt8(SysInt x) ASMJIT_NOTHROW { return x >= 0 && x <= 255; } - -//! @brief Returns @c true if a given integer @a x is signed 16 bit integer -static inline bool isInt16(SysInt x) ASMJIT_NOTHROW { return x >= -32768 && x <= 32767; } -//! @brief Returns @c true if a given integer @a x is unsigned 16 bit integer -static inline bool isUInt16(SysInt x) ASMJIT_NOTHROW { return x >= 0 && x <= 65535; } - -//! @brief Returns @c true if a given integer @a x is signed 16 bit integer -static inline bool isInt32(SysInt x) ASMJIT_NOTHROW -{ -#if defined(ASMJIT_X86) - ASMJIT_USE(x); - return true; -#else - return x >= ASMJIT_INT64_C(-2147483648) && x <= ASMJIT_INT64_C(2147483647); -#endif -} -//! @brief Returns @c true if a given integer @a x is unsigned 16 bit integer -static inline bool isUInt32(SysInt x) ASMJIT_NOTHROW -{ -#if defined(ASMJIT_X86) - return x >= 0; -#else - return x >= 0 && x <= ASMJIT_INT64_C(4294967295); -#endif -} - -// ============================================================================ -// [AsmJit::floatAsInt32, int32AsFloat] -// ============================================================================ - -//! @brief used to cast float to 32 bit integer and vica versa. -//! -//! @internal -union I32FPUnion -{ - //! @brief 32 bit signed integer value. - Int32 i; - //! @brief 32 bit SP-FP value. - float f; -}; - -//! @brief used to cast double to 64 bit integer and vica versa. -//! -//! @internal -union I64FPUnion -{ - //! @brief 64 bit signed integer value. - Int64 i; - //! @brief 64 bit DP-FP value. - double f; -}; - -//! @brief Binary cast 32 bit integer to SP-FP value (@c float). -static inline float int32AsFloat(Int32 i) ASMJIT_NOTHROW -{ - I32FPUnion u; - u.i = i; - return u.f; -} - -//! @brief Binary cast SP-FP value (@c float) to 32 bit integer. -static inline Int32 floatAsInt32(float f) ASMJIT_NOTHROW -{ - I32FPUnion u; - u.f = f; - return u.i; -} - -//! @brief Binary cast 64 bit integer to DP-FP value (@c double). -static inline double int64AsDouble(Int64 i) ASMJIT_NOTHROW -{ - I64FPUnion u; - u.i = i; - return u.f; -} - -//! @brief Binary cast DP-FP value (@c double) to 64 bit integer. -static inline Int64 doubleAsInt64(double f) ASMJIT_NOTHROW -{ - I64FPUnion u; - u.f = f; - return u.i; -} - -// ============================================================================ -// [AsmJit::(X)MMData] -// ============================================================================ - -//! @brief Structure used for MMX specific data (64 bits). -//! -//! This structure can be used to load / store data from / to MMX register. -union ASMJIT_HIDDEN MMData -{ - //! @brief Array of eight signed 8 bit integers. - Int8 sb[8]; - //! @brief Array of eight unsigned 8 bit integers. - UInt8 ub[8]; - //! @brief Array of four signed 16 bit integers. - Int16 sw[4]; - //! @brief Array of four unsigned 16 bit integers. - UInt16 uw[4]; - //! @brief Array of two signed 32 bit integers. - Int32 sd[2]; - //! @brief Array of two unsigned 32 bit integers. - UInt32 ud[2]; - //! @brief Array of one signed 64 bit integer. - Int64 sq[1]; - //! @brief Array of one unsigned 64 bit integer. - UInt64 uq[1]; - - //! @brief Array of two SP-FP values. - float sf[2]; - - //! @brief Set all eight signed 8 bit integers. - inline void set_sb(Int8 x0, Int8 x1, Int8 x2, Int8 x3, Int8 x4, Int8 x5, Int8 x6, Int8 x7) ASMJIT_NOTHROW - { sb[0] = x0; sb[1] = x1; sb[2] = x2; sb[3] = x3; sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7; } - - //! @brief Set all eight unsigned 8 bit integers. - inline void set_ub(UInt8 x0, UInt8 x1, UInt8 x2, UInt8 x3, UInt8 x4, UInt8 x5, UInt8 x6, UInt8 x7) ASMJIT_NOTHROW - { ub[0] = x0; ub[1] = x1; ub[2] = x2; ub[3] = x3; ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7; } - - //! @brief Set all four signed 16 bit integers. - inline void set_sw(Int16 x0, Int16 x1, Int16 x2, Int16 x3) ASMJIT_NOTHROW - { sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; } - - //! @brief Set all four unsigned 16 bit integers. - inline void set_uw(UInt16 x0, UInt16 x1, UInt16 x2, UInt16 x3) ASMJIT_NOTHROW - { uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; } - - //! @brief Set all two signed 32 bit integers. - inline void set_sd(Int32 x0, Int32 x1) ASMJIT_NOTHROW - { sd[0] = x0; sd[1] = x1; } - - //! @brief Set all two unsigned 32 bit integers. - inline void set_ud(UInt32 x0, UInt32 x1) ASMJIT_NOTHROW - { ud[0] = x0; ud[1] = x1; } - - //! @brief Set signed 64 bit integer. - inline void set_sd(Int64 x0) ASMJIT_NOTHROW - { sq[0] = x0; } - - //! @brief Set unsigned 64 bit integer. - inline void set_ud(UInt64 x0) ASMJIT_NOTHROW - { uq[0] = x0; } - - //! @brief Set all two SP-FP values. - inline void set_sf(float x0, float x1) ASMJIT_NOTHROW - { sf[0] = x0; sf[1] = x1; } -}; - -//! @brief Structure used for SSE specific data (128 bits). -//! -//! This structure can be used to load / store data from / to SSE register. -//! -//! @note Always align SSE data to 16 bytes. -union ASMJIT_HIDDEN XMMData -{ - //! @brief Array of sixteen signed 8 bit integers. - Int8 sb[16]; - //! @brief Array of sixteen unsigned 8 bit integers. - UInt8 ub[16]; - //! @brief Array of eight signed 16 bit integers. - Int16 sw[8]; - //! @brief Array of eight unsigned 16 bit integers. - UInt16 uw[8]; - //! @brief Array of four signed 32 bit integers. - Int32 sd[4]; - //! @brief Array of four unsigned 32 bit integers. - UInt32 ud[4]; - //! @brief Array of two signed 64 bit integers. - Int64 sq[2]; - //! @brief Array of two unsigned 64 bit integers. - UInt64 uq[2]; - - //! @brief Array of four SP-FP values. - float sf[4]; - //! @brief Array of two DP-FP values. - double df[2]; - - inline void set_sb( - Int8 x0, Int8 x1, Int8 x2 , Int8 x3 , Int8 x4 , Int8 x5 , Int8 x6 , Int8 x7 , - Int8 x8, Int8 x9, Int8 x10, Int8 x11, Int8 x12, Int8 x13, Int8 x14, Int8 x15) ASMJIT_NOTHROW - { - sb[0] = x0; sb[1] = x1; sb[ 2] = x2 ; sb[3 ] = x3 ; sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ; - sb[8] = x8; sb[9] = x9; sb[10] = x10; sb[11] = x11; sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15; - } - - inline void set_ub( - UInt8 x0, UInt8 x1, UInt8 x2 , UInt8 x3 , UInt8 x4 , UInt8 x5 , UInt8 x6 , UInt8 x7 , - UInt8 x8, UInt8 x9, UInt8 x10, UInt8 x11, UInt8 x12, UInt8 x13, UInt8 x14, UInt8 x15) ASMJIT_NOTHROW - { - ub[0] = x0; ub[1] = x1; ub[ 2] = x2 ; ub[3 ] = x3 ; ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ; - ub[8] = x8; ub[9] = x9; ub[10] = x10; ub[11] = x11; ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15; - } - - inline void set_sw(Int16 x0, Int16 x1, Int16 x2, Int16 x3, Int16 x4, Int16 x5, Int16 x6, Int16 x7) ASMJIT_NOTHROW - { sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7; } - - inline void set_uw(UInt16 x0, UInt16 x1, UInt16 x2, UInt16 x3, UInt16 x4, UInt16 x5, UInt16 x6, UInt16 x7) ASMJIT_NOTHROW - { uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7; } - - inline void set_sd(Int32 x0, Int32 x1, Int32 x2, Int32 x3) ASMJIT_NOTHROW - { sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3; } - - inline void set_ud(UInt32 x0, UInt32 x1, UInt32 x2, UInt32 x3) ASMJIT_NOTHROW - { ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3; } - - inline void set_sd(Int64 x0, Int64 x1) ASMJIT_NOTHROW - { sq[0] = x0; sq[1] = x1; } - - inline void set_ud(UInt64 x0, UInt64 x1) ASMJIT_NOTHROW - { uq[0] = x0; uq[1] = x1; } - - inline void set_sf(float x0, float x1, float x2, float x3) ASMJIT_NOTHROW - { sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3; } - - inline void set_df(double x0, double x1) ASMJIT_NOTHROW - { df[0] = x0; df[1] = x1; } -}; - -// ============================================================================ -// [AsmJit::Buffer] -// ============================================================================ - -//! @brief Buffer used to store instruction stream in AsmJit. -//! -//! This class can be dangerous, if you don't know how it works. Assembler -//! instruction stream is usually constructed by multiple calls of emit -//! functions that emits bytes, words, dwords or qwords. But to decrease -//! AsmJit library size and improve performance, we are not checking for -//! buffer overflow for each emit operation, but only once in highler level -//! emit instruction. -//! -//! So, if you want to use this class, you need to do buffer checking yourself -//! by using @c ensureSpace() method. It's designed to grow buffer if needed. -//! Threshold for growing is named @c growThreshold() and it means count of -//! bytes for emitting single operation. Default size is set to 16 bytes, -//! because x86 and x64 instruction can't be larger (so it's space to hold 1 -//! instruction). -//! -//! Example using Buffer: -//! -//! @code -//! // Buffer instance, growThreshold == 16 -//! // (no memory allocated in constructor). -//! AsmJit::Buffer buf(16); -//! -//! // Begin of emit stream, ensure space can fail on out of memory error. -//! if (buf.ensureSpace()) -//! { -//! // here, you can emit up to 16 (growThreshold) bytes -//! buf.emitByte(0x00); -//! buf.emitByte(0x01); -//! buf.emitByte(0x02); -//! buf.emitByte(0x03); -//! ... -//! } -//! @endcode -struct ASMJIT_API Buffer -{ - inline Buffer(SysInt growThreshold = 16) ASMJIT_NOTHROW : - _data(NULL), - _cur(NULL), - _max(NULL), - _capacity(0), - _growThreshold(growThreshold) - { - } - - inline ~Buffer() ASMJIT_NOTHROW - { - if (_data) ASMJIT_FREE(_data); - } - - //! @brief Return start of buffer. - inline UInt8* data() const ASMJIT_NOTHROW { return _data; } - - //! @brief Return current pointer in code buffer. - inline UInt8* cur() const ASMJIT_NOTHROW { return _cur; } - - //! @brief Return maximum pointer in code buffer for growing. - inline UInt8* maximum() const ASMJIT_NOTHROW { return _max; } - - //! @brief Return current offset in buffer (same as codeSize()). - inline SysInt offset() const ASMJIT_NOTHROW { return (SysInt)(_cur - _data); } - - //! @brief Return capacity of buffer. - inline SysInt capacity() const ASMJIT_NOTHROW { return _capacity; } - - //! @brief Return grow threshold. - inline SysInt growThreshold() const ASMJIT_NOTHROW { return _growThreshold; } - - //! @brief Ensure space for next instruction - inline bool ensureSpace() ASMJIT_NOTHROW { return (_cur >= _max) ? grow() : true; } - - //! @brief Sets offset to @a o and returns previous offset. - //! - //! This method can be used to truncate buffer or it's used to - //! overwrite specific position in buffer by Assembler. - inline SysInt toOffset(SysInt o) ASMJIT_NOTHROW - { - ASMJIT_ASSERT(o < _capacity); - - SysInt prev = (SysInt)(_cur - _data); - _cur = _data + o; - return prev; - } - - //! @brief Reallocate buffer. - //! - //! It's only used for growing, buffer is never reallocated to smaller - //! number than current capacity() is. - bool realloc(SysInt to) ASMJIT_NOTHROW; - - //! @brief Used to grow the buffer. - //! - //! It will typically realloc to twice size of capacity(), but if capacity() - //! is large, it will use smaller steps. - bool grow() ASMJIT_NOTHROW; - - //! @brief Clear everything, but not deallocate buffer. - void clear() ASMJIT_NOTHROW; - - //! @brief Free buffer and NULL all pointers. - void free() ASMJIT_NOTHROW; - - //! @brief Return buffer and NULL all pointers. - UInt8* take() ASMJIT_NOTHROW; - - //! @brief Emit Byte. - inline void emitByte(UInt8 x) ASMJIT_NOTHROW - { - *_cur++ = x; - } - - //! @brief Emit Word (2 bytes). - inline void emitWord(UInt16 x) ASMJIT_NOTHROW - { - *(UInt16 *)_cur = x; - _cur += 2; - } - - //! @brief Emit DWord (4 bytes). - inline void emitDWord(UInt32 x) ASMJIT_NOTHROW - { - *(UInt32 *)_cur = x; - _cur += 4; - } - - //! @brief Emit QWord (8 bytes). - inline void emitQWord(UInt64 x) ASMJIT_NOTHROW - { - *(UInt64 *)_cur = x; - _cur += 8; - } - - //! @brief Emit system signed integer (4 or 8 bytes). - inline void emitSysInt(SysInt x) ASMJIT_NOTHROW - { - *(SysInt *)_cur = x; - _cur += sizeof(SysInt); - } - - //! @brief Emit system unsigned integer (4 or 8 bytes). - inline void emitSysUInt(SysUInt x) ASMJIT_NOTHROW - { - *(SysUInt *)_cur = x; - _cur += sizeof(SysUInt); - } - - //! @brief Emit custom data. - void emitData(const void* ptr, SysUInt len) ASMJIT_NOTHROW; - - //! @brief Set byte at position @a pos. - inline UInt8 getByteAt(SysInt pos) const ASMJIT_NOTHROW - { - return *reinterpret_cast(_data + pos); - } - - //! @brief Set word at position @a pos. - inline UInt16 getWordAt(SysInt pos) const ASMJIT_NOTHROW - { - return *reinterpret_cast(_data + pos); - } - - //! @brief Set word at position @a pos. - inline UInt32 getDWordAt(SysInt pos) const ASMJIT_NOTHROW - { - return *reinterpret_cast(_data + pos); - } - - //! @brief Set word at position @a pos. - inline UInt64 getQWordAt(SysInt pos) const ASMJIT_NOTHROW - { - return *reinterpret_cast(_data + pos); - } - - //! @brief Set byte at position @a pos. - inline void setByteAt(SysInt pos, UInt8 x) ASMJIT_NOTHROW - { - *reinterpret_cast(_data + pos) = x; - } - - //! @brief Set word at position @a pos. - inline void setWordAt(SysInt pos, UInt16 x) ASMJIT_NOTHROW - { - *reinterpret_cast(_data + pos) = x; - } - - //! @brief Set word at position @a pos. - inline void setDWordAt(SysInt pos, UInt32 x) ASMJIT_NOTHROW - { - *reinterpret_cast(_data + pos) = x; - } - - //! @brief Set word at position @a pos. - inline void setQWordAt(SysInt pos, UInt64 x) ASMJIT_NOTHROW - { - *reinterpret_cast(_data + pos) = x; - } - - // All members are public, because they can be accessed and modified by - // Assembler/Compiler directly. - - //! @brief Beginning position of buffer. - UInt8* _data; - //! @brief Current position in buffer. - UInt8* _cur; - //! @brief Maximum position in buffer for realloc. - UInt8* _max; - - //! @brief Buffer capacity (in bytes). - SysInt _capacity; - - //! @brief Grow threshold - SysInt _growThreshold; -}; - -// ============================================================================ -// [AsmJit::PodVector<>] -// ============================================================================ - -//! @brief Template used to store and manage array of POD data. -//! -//! This template has these adventages over other vector<> templates: -//! - Non-copyable (designed to be non-copyable, we want it) -//! - No copy-on-write (some implementations of stl can use it) -//! - Optimized for working only with POD types -//! - Uses ASMJIT_... memory management macros -template -struct PodVector -{ - //! @brief Create new instance of PodVector template. Data will not - //! be allocated (will be NULL). - inline PodVector() ASMJIT_NOTHROW : _data(NULL), _length(0), _capacity(0) - { - } - - //! @brief Destroy PodVector and free all data. - inline ~PodVector() ASMJIT_NOTHROW - { - if (_data) ASMJIT_FREE(_data); - } - - //! @brief Return vector data. - inline T* data() ASMJIT_NOTHROW { return _data; } - //! @overload - inline const T* data() const ASMJIT_NOTHROW { return _data; } - //! @brief Return vector length. - inline SysUInt length() const ASMJIT_NOTHROW { return _length; } - //! @brief Return vector capacity (allocation capacity). - inline SysUInt capacity() const ASMJIT_NOTHROW { return _capacity; } - - //! @brief Clear vector data, but not free internal buffer. - void clear() ASMJIT_NOTHROW - { - _length = 0; - } - - //! @brief Clear vector data and free internal buffer. - void free() ASMJIT_NOTHROW - { - if (_data) - { - ASMJIT_FREE(_data); - _data = 0; - _length = 0; - _capacity = 0; - } - } - - //! @brief Prepend @a item to vector. - bool prepend(const T& item) ASMJIT_NOTHROW - { - if (_length == _capacity && !_grow()) return false; - - memmove(_data + 1, _data, sizeof(T) * _length); - memcpy(_data, &item, sizeof(T)); - - _length++; - return true; - } - - bool insert(SysUInt index, const T& item) ASMJIT_NOTHROW - { - ASMJIT_ASSERT(index <= _length); - if (_length == _capacity && !_grow()) return false; - - T* dst = _data + index; - memmove(dst + 1, dst, _length - index); - memcpy(dst, &item, sizeof(T)); - - _length++; - return true; - } - - //! @brief Append @a item to vector. - bool append(const T& item) ASMJIT_NOTHROW - { - if (_length == _capacity && !_grow()) return false; - - memcpy(_data + _length, &item, sizeof(T)); - - _length++; - return true; - } - - //! @brief Return index of @a val or (SysUInt)-1 if not found. - SysUInt indexOf(const T& val) const ASMJIT_NOTHROW - { - SysUInt i = 0, len = _length; - for (i = 0; i < len; i++) { if (_data[i] == val) return i; } - return (SysUInt)-1; - } - - //! @brief Remove element at index @a i. - void removeAt(SysUInt i) - { - ASMJIT_ASSERT(i < _length); - - T* dst = _data + i; - _length--; - memmove(dst, dst + 1, _length - i); - } - - void swap(PodVector& other) - { - T* _tmp_data = _data; - SysUInt _tmp_length = _length; - SysUInt _tmp_capacity = _capacity; - - _data = other._data; - _length = other._length; - _capacity = other._capacity; - - other._data = _tmp_data; - other._length = _tmp_length; - other._capacity = _tmp_capacity; - } - - //! @brief Return item at @a i position. - inline T& operator[](SysUInt i) ASMJIT_NOTHROW { ASMJIT_ASSERT(i < _length); return _data[i]; } - //! @brief Return item at @a i position. - inline const T& operator[](SysUInt i) const ASMJIT_NOTHROW { ASMJIT_ASSERT(i < _length); return _data[i]; } - -private: - //! @brief Called to grow internal array. - bool _grow() ASMJIT_NOTHROW - { - return _realloc(_capacity < 16 ? 16 : _capacity << 1); - } - - //! @brief Realloc internal array to fit @a to items. - bool _realloc(SysUInt to) ASMJIT_NOTHROW - { - ASMJIT_ASSERT(to >= _length); - - T* p = reinterpret_cast(_data - ? ASMJIT_REALLOC(_data, to * sizeof(T)) - : ASMJIT_MALLOC(to * sizeof(T))); - if (!p) return false; - - _data = p; - _capacity = to; - return true; - } - - //! @brief Items. - T* _data; - //! @brief Length of buffer (count of items in array). - SysUInt _length; - //! @brief Capacity of buffer (maximum items that can fit to current array). - SysUInt _capacity; - - // Disable copy. - ASMJIT_DISABLE_COPY(PodVector); -}; - -// ============================================================================ -// [AsmJit::Zone] -// ============================================================================ - -//! @brief Memory allocator designed to fast alloc memory that will be freed -//! in one step. -//! -//! @note This is hackery for performance. Concept is that objects created -//! by @c Zone are freed all at once. This means that lifetime of -//! these objects are same as zone object itselt. -//! -//! All emittables, variables, labels and states allocated by @c Compiler are -//! allocated through @c Zone object. -struct ASMJIT_API Zone -{ - // [Construction / Destruction] - - //! @brief Create new instance of @c Zone. - //! @param chunkSize Default size for one zone chunk. - Zone(SysUInt chunkSize) ASMJIT_NOTHROW; - - //! @brief Destroy zone instance. - ~Zone() ASMJIT_NOTHROW; - - // [Methods] - - //! @brief Allocate @c size bytes of memory and return pointer to it. - //! - //! Pointer allocated by this way will be valid until @c Zone object is - //! destroyed. To create class by this way use placement @c new and - //! @c delete operators: - //! - //! @code - //! // Example of allocating simple class - //! - //! // Your class - //! class Object - //! { - //! // members... - //! }; - //! - //! // Your function - //! void f() - //! { - //! // We are using AsmJit namespace - //! using namespace AsmJit - //! - //! // Create zone object with chunk size of 65536 bytes. - //! Zone zone(65536); - //! - //! // Create your objects using zone object allocating, for example: - //! Object* obj = new(zone.alloc(sizeof(YourClass))) Object(); - //! - //! // ... lifetime of your objects ... - //! - //! // Destroy your objects: - //! obj->~Object(); - //! - //! // Zone destructor will free all memory allocated through it, - //! // alternative is to call @c zone.freeAll(). - //! } - //! @endcode - void* alloc(SysUInt size) ASMJIT_NOTHROW; - - //! @brief Free all allocated memory except first block that remains for reuse. - //! - //! Note that this method will invalidate all instances using this memory - //! allocated by this zone instance. - void clear() ASMJIT_NOTHROW; - - //! @brief Free all allocated memory at once. - //! - //! Note that this method will invalidate all instances using this memory - //! allocated by this zone instance. - void freeAll() ASMJIT_NOTHROW; - - //! @brief Return total size of allocated objects - by @c alloc(). - inline SysUInt total() const ASMJIT_NOTHROW { return _total; } - //! @brief Return (default) chunk size. - inline SysUInt chunkSize() const ASMJIT_NOTHROW { return _chunkSize; } - - // [Chunk] - - //! @brief One allocated chunk of memory. - struct ASMJIT_HIDDEN Chunk - { - //! @brief Link to previous chunk. - Chunk* prev; - //! @brief Position in this chunk. - SysUInt pos; - //! @brief Size of this chunk (in bytes). - SysUInt size; - - //! @brief Data. - UInt8 data[sizeof(void*)]; - - //! @brief Return count of remaining (unused) bytes in chunk. - inline SysUInt remain() const ASMJIT_NOTHROW { return size - pos; } - }; - -private: - //! @brief Last allocated chunk of memory. - Chunk* _chunks; - //! @brief Total size of allocated objects - by @c alloc() method. - SysUInt _total; - //! @brief One chunk size. - SysUInt _chunkSize; -}; - -//! @} - -} // AsmJit namespace - -#endif // _ASMJIT_UTIL_H diff --git a/src/thirdparty/dyndetours/AsmJit/VirtualMemory.h b/src/thirdparty/dyndetours/AsmJit/VirtualMemory.h deleted file mode 100644 index beb318b6e..000000000 --- a/src/thirdparty/dyndetours/AsmJit/VirtualMemory.h +++ /dev/null @@ -1,87 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// [Guard] -#ifndef _ASMJIT_VIRTUALMEMORY_H -#define _ASMJIT_VIRTUALMEMORY_H - -// [Dependencies] -#include "Build.h" - -// [Warnings-Push] -#include "WarningsPush.h" - -namespace AsmJit { - -//! @addtogroup AsmJit_MemoryManagement -//! @{ - -// ============================================================================ -// [AsmJit::VirtualMemory] -// ============================================================================ - -//! @brief Class that helps with allocating memory for executing code -//! generated by JIT compiler. -//! -//! There are defined functions that provides facility to allocate and free -//! memory where can be executed code. If processor and operating system -//! supports execution protection then you can't run code from normally -//! malloc()'ed memory. -//! -//! Functions are internally implemented by operating system dependent way. -//! VirtualAlloc() function is used for Windows operating system and mmap() -//! for posix ones. If you want to study or create your own functions, look -//! at VirtualAlloc() or mmap() documentation (depends on you target OS). -//! -//! Under posix operating systems is also useable mprotect() function, that -//! can enable execution protection to malloc()'ed memory block. -struct ASMJIT_API VirtualMemory -{ - //! @brief Allocate virtual memory. - //! - //! Pages are readable/writeable, but they are not guaranteed to be - //! executable unless 'canExecute' is true. Returns the address of - //! allocated memory, or NULL if failed. - static void* alloc(SysUInt length, SysUInt* allocated, bool canExecute) ASMJIT_NOTHROW; - - //! @brief Free memory allocated by @c alloc() - static void free(void* addr, SysUInt length) ASMJIT_NOTHROW; - - //! @brief Get the Alignment guaranteed by alloc(). - static SysUInt alignment() ASMJIT_NOTHROW; - - //! @brief Returns size of one page. - static SysUInt pageSize() ASMJIT_NOTHROW; -}; - -//! @} - -} // AsmJit namespace - -// [Warnings-Pop] -#include "WarningsPop.h" - -// [Guard] -#endif // _ASMJIT_VIRTUALMEMORY_H diff --git a/src/thirdparty/dyndetours/AsmJit/WarningsPop.h b/src/thirdparty/dyndetours/AsmJit/WarningsPop.h deleted file mode 100644 index fdd275e37..000000000 --- a/src/thirdparty/dyndetours/AsmJit/WarningsPop.h +++ /dev/null @@ -1,29 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// Pop disabled warnings by AsmJitWarningsPush.h -#if defined(_MSC_VER) -#pragma warning(pop) -#endif // _MSC_VER diff --git a/src/thirdparty/dyndetours/AsmJit/WarningsPush.h b/src/thirdparty/dyndetours/AsmJit/WarningsPush.h deleted file mode 100644 index fc2e410fc..000000000 --- a/src/thirdparty/dyndetours/AsmJit/WarningsPush.h +++ /dev/null @@ -1,37 +0,0 @@ -// AsmJit - Complete JIT Assembler for C++ Language. - -// Copyright (c) 2008-2009, Petr Kobalicek -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// Disable some warnings we know about - -// MSVC -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4127) // conditional expression is constant -#pragma warning(disable: 4251) // struct needs to have dll-interface to be used - // by clients of struct ... -#pragma warning(disable: 4275) // non dll-interface struct ... used as base for - // dll-interface struct -#pragma warning(disable: 4355) // this used in base member initializer list -#endif // _MSC_VER diff --git a/src/thirdparty/dyndetours/arg_class.h b/src/thirdparty/dyndetours/arg_class.h deleted file mode 100644 index 13ae3f37a..000000000 --- a/src/thirdparty/dyndetours/arg_class.h +++ /dev/null @@ -1,56 +0,0 @@ -// ======================================================================= -// File: arg_class.h -// Purpose: Defines a class which represents a function argument. -// ======================================================================= -#ifndef _ARG_CLASS_H -#define _ARG_CLASS_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "arg_types.h" - -// ======================================================================= -// The CFuncArg class. This class allows one to build argument information -// and then parent that information to a function object. -// ======================================================================= -class CFuncArg -{ - private: - eArgType m_ArgType; - eArgPassType m_PassType; - unsigned int m_nSize; - unsigned int m_nOffset; - - public: - // ------------------------------------ - // @brief Constructor. - // ------------------------------------ - CFuncArg( void ); - - // ------------------------------------ - // Setter / Getter for arg type. - // ------------------------------------ - void SetType( eArgType type ); - eArgType GetType( void ) { return m_ArgType; } - - // ------------------------------------ - // Setter / Getter for arg passtype. - // ------------------------------------ - void SetPassType( eArgPassType passType ) { m_PassType = passType; } - eArgPassType GetPassType( void ) { return m_PassType; } - - // ------------------------------------ - // Setter / Getter for arg size. - // ------------------------------------ - unsigned int GetSize( void ) { return m_nSize; } - void SetSize( unsigned int size ) { m_nSize = size; } - - // ------------------------------------ - // Setter / Getter for stack offset. - // ------------------------------------ - unsigned int GetOffset( void ) { return m_nOffset; } - void SetOffset( unsigned int offset ) { m_nOffset = offset; } -}; - -#endif // _ARG_CLASS_H diff --git a/src/thirdparty/dyndetours/arg_types.h b/src/thirdparty/dyndetours/arg_types.h deleted file mode 100644 index 116b426f9..000000000 --- a/src/thirdparty/dyndetours/arg_types.h +++ /dev/null @@ -1,60 +0,0 @@ -// ======================================================================= -// File: arg_types.h -// Purpose: This file defines a number of constants which represent -// attributes of a function argument (be it type, or size). -// ======================================================================= -#ifndef _ARG_TYPES_H -#define _ARG_TYPES_H - -#define DC_SIGCHAR_VOID 'v' -#define DC_SIGCHAR_BOOL 'B' -#define DC_SIGCHAR_CHAR 'c' -#define DC_SIGCHAR_UCHAR 'C' -#define DC_SIGCHAR_SHORT 's' -#define DC_SIGCHAR_USHORT 'S' -#define DC_SIGCHAR_INT 'i' -#define DC_SIGCHAR_UINT 'I' -#define DC_SIGCHAR_LONG 'j' -#define DC_SIGCHAR_ULONG 'J' -#define DC_SIGCHAR_LONGLONG 'l' -#define DC_SIGCHAR_ULONGLONG 'L' -#define DC_SIGCHAR_FLOAT 'f' -#define DC_SIGCHAR_DOUBLE 'd' -#define DC_SIGCHAR_POINTER 'p' -#define DC_SIGCHAR_STRING 'Z' - -// ======================================================================= -// Types of arguments we can have. -// ======================================================================= -enum eArgType -{ - TYPE_UNKNOWN, // Type is not a default type. - TYPE_VOID, - TYPE_BOOL, - TYPE_CHAR, - TYPE_UCHAR, - TYPE_SHORT, - TYPE_USHORT, - TYPE_INT, - TYPE_UINT, - TYPE_LONG, - TYPE_ULONG, - TYPE_LONGLONG, - TYPE_ULONGLONG, - TYPE_FLOAT, - TYPE_DOUBLE, - TYPE_POINTER, - TYPE_STRING -}; - -// ======================================================================= -// If we're passed by reference or not. -// ======================================================================= -enum eArgPassType -{ - PASS_UNKNOWN, // Unknown passing convention. - PASS_BYREF, // Argument passed by reference to function. - PASS_BYVAL, // Argument passed by value to the function. -}; - -#endif // _ARG_TYPES_H diff --git a/src/thirdparty/dyndetours/asmbridge_class.h b/src/thirdparty/dyndetours/asmbridge_class.h deleted file mode 100644 index 960aded73..000000000 --- a/src/thirdparty/dyndetours/asmbridge_class.h +++ /dev/null @@ -1,96 +0,0 @@ -// ======================================================================= -// File: asmbridge_class.h -// Purpose: This file declares the CASMBridge class. This class will be -// used to bridge the hooked function to the DynDetours library. -// ======================================================================= -#ifndef _ASMBRIDGE_CLASS_H -#define _ASMBRIDGE_CLASS_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "AsmJit/AsmJit.h" -#include "conv_main.h" - -// ======================================================================= -// Forward declarations. -// ======================================================================= -class CDetour; - -// ======================================================================= -// The ASMBridge class. -// ======================================================================= -class CASMBridge -{ - private: - // ------------------------------------ - // Needed to generate ASM op codes. - // ------------------------------------ - AsmJit::Assembler m_Assembler; - - // ------------------------------------ - // Instructions to execute before calling - // the callback. - // ------------------------------------ - AsmJit::Label m_PreCall; - - // ------------------------------------ - // Instructions to execute after calling - // the callback. - // ------------------------------------ - AsmJit::Label m_PostCall; - - // ------------------------------------ - // Instructions to override the return - // value of the function. - // ------------------------------------ - AsmJit::Label m_Override; - - // ------------------------------------ - // The calling convention instance - // used to generate ASM for pre and - // post calls. - // ------------------------------------ - ICallConvention* m_pCallConvention; - - // ------------------------------------ - // True if we're initialized. - // ------------------------------------ - bool m_bInitialized; - - public: - - // ------------------------------------ - // @brief Constructor - // @param pDetour - The detour instance - // responsible for pTarget. - // ------------------------------------ - CASMBridge( CDetour* pDetour ); - - // ------------------------------------ - // @brief Destructor. - // ------------------------------------ - ~CASMBridge( void ); - - // ------------------------------------ - // Returns the calling convention for - // this detour. - // ------------------------------------ - ICallConvention* GetConv( void ) - { return m_pCallConvention; } - - // ------------------------------------ - // Returns the base address of the - // ASM instruction blob. - // ------------------------------------ - void* GetBase( void ) { return m_Assembler.make(); } - - // ------------------------------------ - // Returns true if we are initialized. - // ------------------------------------ - bool GetInitialized( void ) { return m_bInitialized; } -}; - - -#endif // _ASMBRIDGE_CLASS_H - diff --git a/src/thirdparty/dyndetours/callback_manager.h b/src/thirdparty/dyndetours/callback_manager.h deleted file mode 100644 index 16c790359..000000000 --- a/src/thirdparty/dyndetours/callback_manager.h +++ /dev/null @@ -1,51 +0,0 @@ -// ======================================================================= -// File: ICallbackManager.h -// Purpose: The callback manager interface. Each language should implement -// a callback manager to manage callback processing. -// ======================================================================= -#ifndef _ICALLBACKMANAGER_H -#define _ICALLBACKMANAGER_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "hook_types.h" - -// ======================================================================= -// Forward declarations. -// ======================================================================= -class CDetour; - -// ======================================================================= -// The ICallbackManager interface. -// ======================================================================= -class ICallbackManager -{ - public: - // ------------------------------------ - // Virtual destructor. - // ------------------------------------ - virtual ~ICallbackManager() {}; - - // ------------------------------------ - // Callback adding / removal. pFuncObj - // is a blackbox for whatever your - // language uses to represent functions. - // ------------------------------------ - virtual void Add( void* pFuncObj, eHookType type ) = 0; - virtual void Remove( void* pFuncObj, eHookType type ) = 0; - - // ------------------------------------ - // Callback processing. - // ------------------------------------ - virtual HookRetBuf_t* DoPreCalls( CDetour* pDet ) = 0; - virtual HookRetBuf_t* DoPostCalls( CDetour* pDet ) = 0; - - // ------------------------------------ - // Returns the language this callback - // is implemented by. - // ------------------------------------ - virtual const char* GetLang( void ) = 0; -}; - -#endif // _ICALLBACKMANAGER_H diff --git a/src/thirdparty/dyndetours/conv_cdecl.h b/src/thirdparty/dyndetours/conv_cdecl.h deleted file mode 100644 index ad91084e3..000000000 --- a/src/thirdparty/dyndetours/conv_cdecl.h +++ /dev/null @@ -1,36 +0,0 @@ -// ======================================================================= -// File: conv_cdecl.h -// Purpose: Declares the CCdecl_Convention class which generates ASM code -// for cdecl calling convention functions. -// ======================================================================= -#ifndef _CONV_CDECL_H -#define _CONV_CDECL_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "conv_interface.h" -#include "register_class.h" -#include "AsmJit/AsmJit.h" - -// ======================================================================= -// The CCdecl_Convention class. -// ======================================================================= -class CCdecl_Convention : public ICallConvention -{ - private: - CRegisterObj m_Registers; - - public: - // ------------------------------------ - // ICallConvention overrides. - // ------------------------------------ - virtual void Stage_1( AsmJit::Assembler* pAssembler ); - virtual void Stage_2( AsmJit::Assembler* pAssembler ); - virtual void Stage_3( AsmJit::Assembler* pAssembler ); - virtual CRegisterObj* GetRegisters( void ) { return &m_Registers; } - -}; - -#endif // _CONV_CDECL_H - diff --git a/src/thirdparty/dyndetours/conv_interface.h b/src/thirdparty/dyndetours/conv_interface.h deleted file mode 100644 index eaf5b6888..000000000 --- a/src/thirdparty/dyndetours/conv_interface.h +++ /dev/null @@ -1,50 +0,0 @@ -// ======================================================================= -// File: conv_interface.h -// Purpose: This file declares the ICallConvention interface. This -// interface is used providing uniformity accross calling conventions. -// The ASMBridge class uses this interface in order to generate the -// correct ASM without having it all stuffed into a single function. -// ======================================================================= -#ifndef _CONV_INTERFACE_H -#define _CONV_INTERFACE_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "AsmJit/AsmJit.h" -#include "register_class.h" - -// ======================================================================= -// The ICallConvention interface. -// ======================================================================= -class ICallConvention -{ - public: - - /* @brief Generates code to save convention specific registers. - * Called by CASMBridge when generating the ASM code for the - * detour. - * @param pAssembler - The assembler to generate the code with. - */ - virtual void Stage_1( AsmJit::Assembler* pAssembler ) = 0; - - /* @brief Generates code to clean up the stack. Called by the - * CASMBridge class when generating ASM code to clean up the - * stack. - * @param pAssembler - The assembler to generate the code with. - */ - virtual void Stage_2( AsmJit::Assembler* pAssembler ) = 0; - - /* @brief Generates code which will execute before we do the - * override. - * @param pAssembler - The assembler to generate code with. - */ - virtual void Stage_3( AsmJit::Assembler* pAssembler ) = 0; - - /* @brief Returns the register object containing the values - * of x86 registers pertinent to this call. - */ - virtual CRegisterObj* GetRegisters( void ) = 0; -}; - -#endif // _CONV_INTERFACE_H diff --git a/src/thirdparty/dyndetours/conv_main.h b/src/thirdparty/dyndetours/conv_main.h deleted file mode 100644 index 8765154eb..000000000 --- a/src/thirdparty/dyndetours/conv_main.h +++ /dev/null @@ -1,25 +0,0 @@ -// ======================================================================= -// File: conv_main.h -// Purpose: Links in all calling convention types. This file will -// disappear as soon as I write dynamic calling convention instantiation -// code. -// -// Ideas: Creating a linked list of convention names (stored as strings), -// paired to a function to generate new instances of calling convention -// classes. -// ======================================================================= -#ifndef _CONV_MAIN_H -#define _CONV_MAIN_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "conv_interface.h" -#include "func_types.h" - -// ======================================================================= -// Returns a new instance of a calling convention. -// ======================================================================= -ICallConvention* EnumToConvention(eCallConv conv); - -#endif // _CONV_MAIN_H diff --git a/src/thirdparty/dyndetours/conv_stdcall.h b/src/thirdparty/dyndetours/conv_stdcall.h deleted file mode 100644 index 3c0321435..000000000 --- a/src/thirdparty/dyndetours/conv_stdcall.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _CONV_STDCALL_H -#define _CONV_STDCALL_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "conv_interface.h" -#include "register_class.h" -#include "AsmJit/AsmJit.h" - -// ======================================================================= -// The CCdecl_Convention class. -// ======================================================================= -class CStdCall_Convention : public ICallConvention -{ -private: - CRegisterObj m_Registers; - -public: - // ------------------------------------ - // ICallConvention overrides. - // ------------------------------------ - virtual void Stage_1( AsmJit::Assembler* pAssembler ); - virtual void Stage_2( AsmJit::Assembler* pAssembler ); - virtual void Stage_3( AsmJit::Assembler* pAssembler ); - virtual CRegisterObj* GetRegisters( void ) { return &m_Registers; } -}; - -#endif // _CONV_STDCALL_H diff --git a/src/thirdparty/dyndetours/conv_thiscall.h b/src/thirdparty/dyndetours/conv_thiscall.h deleted file mode 100644 index 652f6012e..000000000 --- a/src/thirdparty/dyndetours/conv_thiscall.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _CONV_THISCALL_H -#define _CONV_THISCALL_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "conv_interface.h" -#include "register_class.h" -#include "AsmJit/AsmJit.h" - -// ======================================================================= -// The CCdecl_Convention class. -// ======================================================================= -class CThiscall_Convention : public ICallConvention -{ - private: - CRegisterObj m_Registers; - - public: - // ------------------------------------ - // ICallConvention overrides. - // ------------------------------------ - virtual void Stage_1( AsmJit::Assembler* pAssembler ); - virtual void Stage_2( AsmJit::Assembler* pAssembler ); - virtual void Stage_3( AsmJit::Assembler* pAssembler ); - virtual CRegisterObj* GetRegisters( void ) { return &m_Registers; } -}; - -#endif // _CONV_THISCALL_H diff --git a/src/thirdparty/dyndetours/cpp_manager.h b/src/thirdparty/dyndetours/cpp_manager.h deleted file mode 100644 index 3dba09a32..000000000 --- a/src/thirdparty/dyndetours/cpp_manager.h +++ /dev/null @@ -1,66 +0,0 @@ -// ======================================================================= -// File: cpp_manager.h -// Purpose: Declares the CCPPManager callback manager. This class is -// responsible for adding / creating callbacks for the C++ language. -// ======================================================================= -#ifndef _CPP_MANAGER_H -#define _CPP_MANAGER_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "callback_manager.h" -#include "hook_types.h" -#include "func_types.h" -#include - -// ======================================================================= -// Forward declarations -// ======================================================================= -class CDetour; - -// ======================================================================= -// This is the function prototype for a C++ callback. -// ======================================================================= -typedef HookRetBuf_t* (*CPPCallBack)( CDetour* ); - -// ======================================================================= -// Creates a C++ callback for a detour. -// ======================================================================= -extern bool CPP_CreateCallback( void* target, eCallConv conv, const char* szParams, - CPPCallBack callback, eHookType type ); - -// ======================================================================= -// The CCPPManager class. -// ======================================================================= -class CCPPManager : public ICallbackManager -{ - private: - // ------------------------------------ - // Callback lists. - // ------------------------------------ - std::vector m_vecPreCalls; - std::vector m_vecPostCalls; - - public: - // ------------------------------------ - // Language accessor. - // ------------------------------------ - virtual const char* GetLang( void ) { - return "C++"; - } - - // ------------------------------------ - // Callback adding / removal. - // ------------------------------------ - virtual void Add( void* pFuncObj, eHookType type ); - virtual void Remove( void* pFuncObj, eHookType type ); - - // ------------------------------------ - // Callback processing. - // ------------------------------------ - virtual HookRetBuf_t* DoPreCalls( CDetour* pDet ); - virtual HookRetBuf_t* DoPostCalls( CDetour* pDet ); -}; - -#endif // _CPP_MANAGER diff --git a/src/thirdparty/dyndetours/dd_utils.h b/src/thirdparty/dyndetours/dd_utils.h deleted file mode 100644 index 559816bd1..000000000 --- a/src/thirdparty/dyndetours/dd_utils.h +++ /dev/null @@ -1,20 +0,0 @@ -// ======================================================================= -// File: dd_utils.h -// Purpose: Useful functions used accross dyndetours. -// ======================================================================= -#ifndef _DD_UTILS_H -#define _DD_UTILS_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "arg_types.h" - -// ======================================================================= -// Returns the eArgType enum corresponding to the given char. Returns -// TYPE_UNKNOWN if there is no mapping. -// ======================================================================= -eArgType CharToTypeEnum( char c ); -char TypeEnumToChar(eArgType); - -#endif // _DD_UTILS_H diff --git a/src/thirdparty/dyndetours/detour_class.h b/src/thirdparty/dyndetours/detour_class.h deleted file mode 100644 index be39b5046..000000000 --- a/src/thirdparty/dyndetours/detour_class.h +++ /dev/null @@ -1,117 +0,0 @@ -// ======================================================================= -// File: detour_class.h -// Purpose: This is where the magic begins. An instance of the CDetour -// class is instantiated for every NEW target function that the library -// recieves. This means only one CDetour instance per target. This class -// also stores a list of all callback functions to call before and after -// the original function is executed. -// ======================================================================= -#ifndef _DETOUR_CLASS_H -#define _DETOUR_CLASS_H - -// ======================================================================= -// Includes -// ======================================================================= -#include -#include "hook_types.h" -#include "func_class.h" -#include "asmbridge_class.h" -#include "trampoline_class.h" -#include "callback_manager.h" - -// ======================================================================= -// The CDetour class. -// ======================================================================= -class CDetour -{ - private: - // ------------------------------------ - // This points to an array of saved - // bytes from the original function. - // ------------------------------------ - CTrampoline* m_pTrampoline; - - // ------------------------------------ - // This contains the ASM bridge which - // connects the original function to - // our detour. - // ------------------------------------ - CASMBridge* m_pBridge; - - // ------------------------------------ - // The function object representing - // the target function. - // ------------------------------------ - CFuncObj* m_pFuncObj; - - // ------------------------------------ - // The status of this detour. - // ------------------------------------ - bool m_bInitialized; - - // ------------------------------------ - // TEMPORARY! Stores pointers to all of - // our pre-execution callbacks. - // ------------------------------------ - std::vector m_vecPreCallbacks; - - // ------------------------------------ - // TEMPORARY! Stores pointers to all of - // our post-execution callbacks. - // ------------------------------------ - std::vector m_vecPostCallbacks; - - // ------------------------------------ - // @brief Parses and creates a function - // object from the parameter list. - // ------------------------------------ - CFuncObj* CreateFromString( const char* szParamList, - eCallConv eConv, void* pTarget ); - - public: - - // ------------------------------------ - // Constructor - // ------------------------------------ - CDetour( void* pTarget, const char* szParamList, - eCallConv eConv ); - - // ------------------------------------ - // Destructor - // ------------------------------------ - ~CDetour( void ); - - // ------------------------------------ - // Adds a callback manager. - // ------------------------------------ - void AddManager( ICallbackManager* pManager, eHookType type ); - - // ------------------------------------ - // Callback manager accessor. - // ------------------------------------ - ICallbackManager* GetManager( const char* lang, eHookType type ); - - // ------------------------------------ - // Processes callbacks. - // ------------------------------------ - HookRetBuf_t* DoCallbacks( eHookType type ); - - // ------------------------------------ - // Returns the ASM bridge for this - // detour. - // ------------------------------------ - CASMBridge* GetAsmBridge( void ) { return m_pBridge; } - - // ------------------------------------ - // Trampoline accessor. - // ------------------------------------ - void* GetTrampoline( void ) { return m_pTrampoline->GetBase(); } - - // ------------------------------------ - // Function object accessor. - // ------------------------------------ - CFuncObj* GetFuncObj( void ) { return m_pFuncObj; } -}; - -#endif // _DETOUR_CLASS_H - diff --git a/src/thirdparty/dyndetours/detourman_class.h b/src/thirdparty/dyndetours/detourman_class.h deleted file mode 100644 index cbc0032c9..000000000 --- a/src/thirdparty/dyndetours/detourman_class.h +++ /dev/null @@ -1,60 +0,0 @@ -// ======================================================================= -// File: detour_class.h -// Purpose: Handles detour creation. -// ======================================================================= -#ifndef _DETOURMAN_CLASS_H -#define _DETOURMAN_CLASS_H - -//======================================================================== -// Includes -//======================================================================== -#include -#include "hook_types.h" -#include "func_types.h" - -//======================================================================== -// Forward declarations. -//======================================================================== -class CDetour; - -//======================================================================== -// Detour Manager class -//======================================================================== -class CDetourManager -{ - private: - /* This vector will store a list of detours and their addresses. */ - std::vector m_DetourList; - - public: - - /* @brief Destructor. Removes all detours and frees up memory - * taken up by them. - */ - ~CDetourManager( void ); - - /* @brief Adds a detour to our internal list of detours. - * @param pTarget - Pointer to a callback function. - * @param szParams - Parameter format string. - * @param conv - Calling convention of hooked function. - * @return A detour instance for the target address. - */ - CDetour* Add_Detour( void* pTarget, const char* szParams, eCallConv conv ); - - /* @brief Removes a detour at the target address. - * @param pTarget - The target address the detour is bound to. - * @return True if the detour was found and removed successfully. - */ - bool Remove_Detour( void* pTarget ); - - /* @brief Finds a detour in our list. - * @param pTarget - The address that the detour has hooked. - * @return A CDetour pointer that is tied to the target function. - */ - CDetour* Find_Detour( void* pTarget ); -}; - -extern CDetourManager g_DetourManager; - -#endif // _DETOURMAN_CLASS_H - diff --git a/src/thirdparty/dyndetours/func_class.h b/src/thirdparty/dyndetours/func_class.h deleted file mode 100644 index 19befa17d..000000000 --- a/src/thirdparty/dyndetours/func_class.h +++ /dev/null @@ -1,126 +0,0 @@ -// ======================================================================= -// File: func_class.h -// Purpose: This file declares the CFuncObj class which encapsulates and -// represents the attributes of a C/C++ function in memory. -// ======================================================================= -#ifndef _FUNC_CLASS_H -#define _FUNC_CLASS_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "arg_types.h" -#include "func_stack.h" -#include "func_types.h" -#include - -// ======================================================================= -// Namespaces to use -// ======================================================================= -using namespace std; - -// ======================================================================= -// The CFuncObj class. -// ======================================================================= -class CFuncObj -{ - private: - // ------------------------------------ - // Each function has the following - // attributes: - // - Calling Convention. - // - Parameters. - // - Return value + type. - // - Address. - // ------------------------------------ - - CFuncArg m_RetArg; - CFuncStack m_Stack; - // vector m_ArgList; - eCallConv m_eConv; - void* m_pAddr; - - public: - - // ------------------------------------ - // @brief Constructor. - // @param pAddr - The address of the - // function. - // @param conv - Calling convention. - // ------------------------------------ - CFuncObj( void* pAddr, eCallConv conv ); - - // ------------------------------------ - // @brief Constructor. Sets up the - // function object via string. - // @param szParamList - Parameter - // format string. - // @param eConv - Calling convention of - // the function. - // ------------------------------------ - CFuncObj( void* pAddr, const char* szParamList, - eCallConv eConv ); - - // ------------------------------------ - // @brief Destructor - // ------------------------------------ - ~CFuncObj( void ); - - // ------------------------------------ - // @brief Adds an argument to this - // function's argument stack. - // @param type - Type of argument. - // @param passType - How the argument - // is passed to the function. - // @param size - Optional unless type - // is TYPE_CUSTOM. The size of the - // argument in bytes. - // ------------------------------------ - void AddArg(eArgType type, eArgPassType passType, int size=0); - - // ------------------------------------ - // Returns the number of arguments - // ------------------------------------ - unsigned int GetNumArgs( void ); - - // ------------------------------------ - // Retrieves an argument at the - // specified index. Returns NULL if - // there is no argument at this index. - // ------------------------------------ - CFuncArg* GetArg( int iArgNum ); - - // ------------------------------------ - // Stacj accessor. - // ------------------------------------ - CFuncStack* GetStack( void ); - - // ------------------------------------ - // @brief Returns return value - // information. - // ------------------------------------ - CFuncArg* GetRetType( void ) { return &m_RetArg; } - - // ------------------------------------ - // @brief Sets the return type. - // NOTE: If you used a parameter - // format string to create this funcobj, - // you do not need to use this method. - // ------------------------------------ - void SetRetType( eArgType retType, int size=0 ); - - // ------------------------------------ - // @brief Accessor for calling - // convention. - // ------------------------------------ - eCallConv GetConvention( void ) { return m_eConv; } - - // ------------------------------------ - // @brief Accessor for function - // address. - // ------------------------------------ - void* GetAddress( void ) { return m_pAddr; } -}; - -#endif // _FUNC_CLASS_H - diff --git a/src/thirdparty/dyndetours/func_stack.h b/src/thirdparty/dyndetours/func_stack.h deleted file mode 100644 index 177dc971c..000000000 --- a/src/thirdparty/dyndetours/func_stack.h +++ /dev/null @@ -1,86 +0,0 @@ -// ======================================================================= -// File: func_stack.h -// Purpose: This file represents the stack frame of a function. It stores -// CFuncArg instances and calculates the offsets they are from a given -// ESP value. -// ======================================================================= -#ifndef _FUNC_STACK_H -#define _FUNC_STACK_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "arg_class.h" - -// ======================================================================= -// A node representing an argument. To be used in our linked list of -// function arguments. -// ======================================================================= -struct ArgNode_t -{ - CFuncArg* m_pArg; // Argument instance. - int m_nOffset; // Offset of the argument from ESP. - ArgNode_t* m_pNext; // Next argument in the list. -}; - -// ======================================================================= -// The stack class. -// ======================================================================= -class CFuncStack -{ - private: - // ------------------------------------ - // Linked list of arguments. - // ------------------------------------ - ArgNode_t* m_pArgListHead; - - // ------------------------------------ - // Number of arguments registered to - // this stack instance. - // ------------------------------------ - int m_nNumArgs; - - // ------------------------------------ - // Total stack size. - // ------------------------------------ - int m_nTotalSize; - - public: - - // ------------------------------------ - // Constructor / Destructor. - // ------------------------------------ - CFuncStack( void ); - ~CFuncStack( void ); - - // ------------------------------------ - // @brief Adds an argument to the - // linked list. - // @return The CFuncArg instance that - // was just created. - // ------------------------------------ - bool AddArgument( CFuncArg* pArg ); - - // ------------------------------------ - // @brief Returns an ArgNode_t by its - // position in the stack. - // @param pos - Position of the - // desired argument on the stack. - // @return The ArgNode_t instance at the - // given index. - // ------------------------------------ - ArgNode_t* GetArgument( int pos ); - - // ------------------------------------ - // Stack size accessor. - // ------------------------------------ - int GetStackSize( void ) { return m_nTotalSize; } - - // ------------------------------------ - // NumArgs accessor. - // ------------------------------------ - int GetNumArgs( void ) { return m_nNumArgs; } - -}; - -#endif // _FUNC_STACK_H diff --git a/src/thirdparty/dyndetours/func_types.h b/src/thirdparty/dyndetours/func_types.h deleted file mode 100644 index 5843a64b2..000000000 --- a/src/thirdparty/dyndetours/func_types.h +++ /dev/null @@ -1,23 +0,0 @@ -// ======================================================================= -// File: func_types.h -// Purpose: This file defines some useful constants with regard to -// function attributes. -// ======================================================================= -#ifndef _FUNC_TYPES_H -#define _FUNC_TYPES_H - -// ======================================================================= -// Calling conventions. -// ======================================================================= -enum eCallConv -{ - CONV_CDECL = 0, -#ifdef _WIN32 - CONV_STDCALL = 2, - CONV_THISCALL = 5, -#else - CONV_THISCALL = 6, -#endif -}; - -#endif // _FUNC_TYPES_H diff --git a/src/thirdparty/dyndetours/hook_handler.h b/src/thirdparty/dyndetours/hook_handler.h deleted file mode 100644 index c31f09f9d..000000000 --- a/src/thirdparty/dyndetours/hook_handler.h +++ /dev/null @@ -1,25 +0,0 @@ -// ======================================================================= -// File: hook_handler.h -// Purpose: Main callback for handling hooks. Every single detour registered -// using DynDetours will call this callback! -// ======================================================================= -#ifndef _HOOK_HANDLER_H -#define _HOOK_HANDLER_H - -// ======================================================================= -// Includes -// ======================================================================= -#include "hook_types.h" - -// ======================================================================= -// Forward declarations. -// ======================================================================= -class CDetour; - -// ======================================================================= -// Pre-callback hooks. -// ======================================================================= -eHookRes Dyn_PreHandler( CDetour* pDetour ); -eHookRes Dyn_PostHandler( CDetour* pDetour ); - -#endif // _HOOK_HANDLER_H diff --git a/src/thirdparty/dyndetours/hook_types.h b/src/thirdparty/dyndetours/hook_types.h deleted file mode 100644 index f89367c05..000000000 --- a/src/thirdparty/dyndetours/hook_types.h +++ /dev/null @@ -1,37 +0,0 @@ -// ======================================================================= -// File: hook_types.h -// Purpose: Defines some useful constants for the hook system. -// ======================================================================= -#ifndef _HOOK_TYPES_H -#define _HOOK_TYPES_H - -// ======================================================================= -// Constants for callback execution. -// ======================================================================= -enum eHookType -{ - TYPE_PRE, // Execute callback before original. - TYPE_POST, // Execute callback after original. -}; - -// ======================================================================= -// Constants for the hooking system. -// ======================================================================= -enum eHookRes -{ - HOOKRES_ERROR=-1, // Problem occured. - HOOKRES_NONE=0, // Call orig like normal. - HOOKRES_NEWPARAMS,// Parameters modified - HOOKRES_OVERRIDE, // Don't call orig function. -}; - -// ======================================================================= -// Hook result buffer -// ======================================================================= -struct HookRetBuf_t -{ - eHookRes eRes; // Result action - void* pRetBuf; // Dynamically allocated space for the return value. -}; - -#endif // _HOOK_CONSTANTS_H diff --git a/src/thirdparty/dyndetours/lib/AsmJit.lib b/src/thirdparty/dyndetours/lib/AsmJit.lib deleted file mode 100644 index 79905acdc..000000000 Binary files a/src/thirdparty/dyndetours/lib/AsmJit.lib and /dev/null differ diff --git a/src/thirdparty/dyndetours/lib/DynDetours.lib b/src/thirdparty/dyndetours/lib/DynDetours.lib deleted file mode 100644 index 204c8215e..000000000 Binary files a/src/thirdparty/dyndetours/lib/DynDetours.lib and /dev/null differ diff --git a/src/thirdparty/dyndetours/lib/libAsmJit.a b/src/thirdparty/dyndetours/lib/libAsmJit.a deleted file mode 100644 index e9246a71f..000000000 Binary files a/src/thirdparty/dyndetours/lib/libAsmJit.a and /dev/null differ diff --git a/src/thirdparty/dyndetours/lib/libDynDetours.a b/src/thirdparty/dyndetours/lib/libDynDetours.a deleted file mode 100644 index 4ec7a2d5c..000000000 Binary files a/src/thirdparty/dyndetours/lib/libDynDetours.a and /dev/null differ diff --git a/src/thirdparty/dyndetours/manager_class.h b/src/thirdparty/dyndetours/manager_class.h deleted file mode 100644 index 89b8b6e13..000000000 --- a/src/thirdparty/dyndetours/manager_class.h +++ /dev/null @@ -1,42 +0,0 @@ -// ======================================================================= -// File: manager_class.h -// Purpose: This file contains the CDetourManager class which is -// responsible for creating and removing detours. -// ======================================================================= -#ifndef _MANAGER_CLASS_H -#define _MANAGER_CLASS_H - -// ======================================================================= -// Forward declarations -// ======================================================================= -class CDetour; - -// ======================================================================= -// Includes -// ======================================================================= -#include -#include "func_types.h" - -// ======================================================================= -// Some typedefs to help us along. -// ======================================================================= -typedef std::pair TDetourPair; -typedef std::map TDetourMap; - -// ======================================================================= -// CDetourManager class. -// ======================================================================= -class CDetourManager -{ - private: - TDetourMap m_DetourList; - - public: - - CDetour* CreateDetour(void* pTarget, void* pCallBack, - eCallConv conv, char* szParams); - - CDetour* GetDetour(void* pAddress); -}; - -#endif // _MANAGER_CLASS_H diff --git a/src/thirdparty/dyndetours/register_class.h b/src/thirdparty/dyndetours/register_class.h deleted file mode 100644 index 5af30d102..000000000 --- a/src/thirdparty/dyndetours/register_class.h +++ /dev/null @@ -1,55 +0,0 @@ -// ======================================================================= -// File: register_class.h -// Purpose: This class encapsulates common X86 registers used when -// functions are called. Each calling convention interface should have -// an instance of this class. -// ======================================================================= -#ifndef _REGISTER_CLASS_H -#define _REGISTER_CLASS_H - -// ======================================================================= -// The register object. -// ======================================================================= -class CRegisterObj -{ - // ------------------------------------ - // One thing I need to consider is - // what happens if a function returns - // something that is more than 8 bytes. - // Perhaps I could allocate a retbuf in - // the detour class. I could grab the - // size of the retval from the CFuncArg - // class which represents the retval. - // ------------------------------------ - - public: - // ------------------------------------ - // Constructors. - // ------------------------------------ - CRegisterObj( void ) - { - // ------------------------------------ - // Initialize everything to 0. - // ------------------------------------ - r_esp = 0; - r_ebp = 0; - r_ecx = 0; - r_edx = 0; - r_retreg = NULL; - } - - // ------------------------------------ - // These are public because we want - // the calling convention classes to - // grab the addresses of these for - // inline ASM placement. - // ------------------------------------ - unsigned long r_esp; // Stack pointer. - unsigned long r_ebp; // Base pointer. - unsigned long r_ecx; // Counter. Used for thiscalls on windows. - unsigned long r_edx; - void* r_retreg; // eax and st0 at once -}; - - -#endif // _REGISTER_CLASS_H diff --git a/src/thirdparty/dyndetours/trampoline_class.h b/src/thirdparty/dyndetours/trampoline_class.h deleted file mode 100644 index 4091a1a0a..000000000 --- a/src/thirdparty/dyndetours/trampoline_class.h +++ /dev/null @@ -1,67 +0,0 @@ -// ======================================================================= -// File: trampoline_class.h -// Purpose: This file contains the CTrampoline class. This class is -// responsible for saving the first few bytes of the target function that -// is to be hooked. The trampoline is also used to call the original -// function after hooks are executed. -// ======================================================================= -#ifndef _TRAMPOLINE_CLASS_H -#define _TRAMPOLINE_CLASS_H - -// ======================================================================= -// The trampoline class. -// ======================================================================= -class CTrampoline -{ - private: - // ------------------------------------ - // Points to the array of bytes we - // have saved from the original function. - // ------------------------------------ - unsigned char* m_pSavedBytes; - - // ------------------------------------ - // The number of bytes we saved. Used - // to allocate space for the saved bytes. - // ------------------------------------ - int m_iSavedBytes; - - // ------------------------------------ - // The target function. - // ------------------------------------ - unsigned char* m_pTarget; - - public: - - // ------------------------------------ - // @brief Constructor. - // @param pTarget - The target function - // to create the trampoline from. - // ------------------------------------ - CTrampoline( void* pTarget ); - - // ------------------------------------ - // @brief Destructor. - // ------------------------------------ - ~CTrampoline( void ); - - // ------------------------------------ - // @brief Returns a pointer to the - // array of saved bytes. - // ------------------------------------ - void* GetBase( void ) { return m_pSavedBytes; } - - // ------------------------------------ - // @brief Returns the number of bytes - // we saved from the original function. - // ------------------------------------ - int GetNumSavedBytes( void ) { return m_iSavedBytes; } - - // ------------------------------------ - // @brief Restores the original bytes - // of the target function. - // ------------------------------------ - bool Restore( void ); -}; - -#endif // _TRAMPOLINE_CLASS_H